66 lines
3.0 KiB
Python
66 lines
3.0 KiB
Python
# 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'
|