81 lines
3.3 KiB
Python
81 lines
3.3 KiB
Python
# pyrefly: ignore [missing-import]
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class EducationStudentLedger(models.Model):
|
|
_name = 'education.student.ledger'
|
|
_description = 'Student Financial Ledger'
|
|
_order = 'date asc, id asc'
|
|
|
|
student_id = fields.Many2one('education.student', string='Student', required=True, index=True, ondelete='cascade')
|
|
academic_year_id = fields.Many2one('education.academic.year', string='Academic Year', index=True)
|
|
semester_id = fields.Many2one('education.semester', string='Semester', index=True)
|
|
category_id = fields.Many2one('education.fee.category', string='Fee Category', index=True)
|
|
fee_type_id = fields.Many2one('education.fee.type', string='Fee Type', index=True)
|
|
|
|
date = fields.Date(string='Date', required=True, default=fields.Date.context_today, index=True)
|
|
ref = fields.Char(string='Reference', index=True)
|
|
description = fields.Text(string='Description')
|
|
|
|
currency_id = fields.Many2one(
|
|
'res.currency',
|
|
string='Currency',
|
|
required=True,
|
|
default=lambda self: self.env.company.currency_id,
|
|
)
|
|
debit = fields.Monetary(string='Debit (Charges)', default=0.0, currency_field='currency_id', index=True)
|
|
credit = fields.Monetary(string='Credit (Payments/Credits)', default=0.0, currency_field='currency_id', index=True)
|
|
balance = fields.Monetary(string='Balance', currency_field='currency_id', index=True)
|
|
status = fields.Selection([
|
|
('draft', 'Draft'),
|
|
('outstanding', 'Outstanding'),
|
|
('paid', 'Paid'),
|
|
('cancelled', 'Cancelled')
|
|
], string='Status', default='outstanding', 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,
|
|
)
|
|
|
|
def _recalculate_student_balances(self, student_ids):
|
|
for student_id in student_ids:
|
|
lines = self.search([
|
|
('student_id', '=', student_id),
|
|
('status', 'in', ('outstanding', 'paid'))
|
|
], order='date asc, id asc')
|
|
running = 0.0
|
|
for line in lines:
|
|
running += line.debit - line.credit
|
|
self.env.cr.execute(
|
|
"UPDATE education_student_ledger SET balance = %s WHERE id = %s",
|
|
(running, line.id)
|
|
)
|
|
# Force metrics recalculation on the student record
|
|
student = self.env['education.student'].browse(student_id)
|
|
student.modified(['ledger_line_ids'])
|
|
self.invalidate_model(['balance'])
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
records = super().create(vals_list)
|
|
student_ids = records.mapped('student_id').ids
|
|
self._recalculate_student_balances(student_ids)
|
|
return records
|
|
|
|
def write(self, vals):
|
|
student_ids = self.mapped('student_id').ids
|
|
res = super().write(vals)
|
|
student_ids = list(set(student_ids + self.mapped('student_id').ids))
|
|
self._recalculate_student_balances(student_ids)
|
|
return res
|
|
|
|
def unlink(self):
|
|
student_ids = self.mapped('student_id').ids
|
|
res = super().unlink()
|
|
self._recalculate_student_balances(student_ids)
|
|
return res
|