# pyrefly: ignore [missing-import] from odoo import api, fields, models # pyrefly: ignore [missing-import] from odoo.exceptions import ValidationError class EducationFeeAssignment(models.Model): _name = 'education.fee.assignment' _description = 'Student Fee Assignment' _order = 'assignment_date desc' student_id = fields.Many2one('education.student', string='Student', required=True, index=True) academic_year_id = fields.Many2one('education.academic.year', string='Academic Year', required=True, index=True) semester_id = fields.Many2one('education.semester', string='Semester', required=True, index=True) fee_structure_id = fields.Many2one('education.fee.structure', string='Fee Structure', required=True, index=True) assignment_date = fields.Date(string='Assignment Date', required=True, default=fields.Date.context_today) state = fields.Selection([ ('draft', 'Draft'), ('confirmed', 'Confirmed'), ], string='Status', default='draft', required=True, index=True) active = fields.Boolean(default=True) company_id = fields.Many2one( 'res.company', string='Company', required=True, default=lambda self: self.env.company, index=True, ) _sql_constraints = [ ('uniq_assignment', 'unique(student_id, academic_year_id, semester_id, fee_structure_id, company_id)', 'This fee structure is already assigned to this student for this semester.'), ] def action_confirm(self): for rec in self: if rec.state == 'confirmed': continue if not rec.fee_structure_id.line_ids: raise ValidationError(f"The selected fee structure '{rec.fee_structure_id.name}' has no fee lines. Please add fee lines to this structure before confirming.") for line in rec.fee_structure_id.line_ids: self.env['education.student.ledger'].create({ 'student_id': rec.student_id.id, 'academic_year_id': rec.academic_year_id.id, 'semester_id': rec.semester_id.id, 'category_id': line.fee_type_id.category_id.id, 'fee_type_id': line.fee_type_id.id, 'date': rec.assignment_date, 'ref': f"FEE/{rec.id}", 'description': f"{line.fee_type_id.name} (Assigned via {rec.fee_structure_id.name})", 'debit': line.amount, 'credit': 0.0, 'status': 'outstanding', 'company_id': rec.company_id.id, }) rec.state = 'confirmed' def action_cancel(self): for rec in self: if rec.state == 'confirmed': ledger_entries = self.env['education.student.ledger'].search([ ('student_id', '=', rec.student_id.id), ('ref', '=', f"FEE/{rec.id}"), ]) ledger_entries.unlink() rec.state = 'draft'