2026-09-25 18:00:58 +05:30

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