50 lines
2.9 KiB
Python
50 lines
2.9 KiB
Python
# pyrefly: ignore [missing-import]
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class EducationStudent(models.Model):
|
|
_inherit = 'education.student'
|
|
|
|
ledger_line_ids = fields.One2many('education.student.ledger', 'student_id', string='Ledger Lines')
|
|
payment_ids = fields.One2many('education.student.payment', 'student_id', string='Payments')
|
|
|
|
currency_id = fields.Many2one('res.currency', string='Currency', related='company_id.currency_id', readonly=True, store=True)
|
|
|
|
outstanding_amount = fields.Monetary(string='Outstanding Dues', compute='_compute_finance_metrics', currency_field='currency_id', store=True, index=True)
|
|
total_fees = fields.Monetary(string='Total Fees', compute='_compute_finance_metrics', currency_field='currency_id', store=True, index=True)
|
|
total_paid = fields.Monetary(string='Total Paid', compute='_compute_finance_metrics', currency_field='currency_id', store=True, index=True)
|
|
|
|
last_payment_date = fields.Date(string='Last Payment Date', compute='_compute_finance_metrics', store=True, index=True)
|
|
last_receipt_number = fields.Char(string='Last Receipt Number', compute='_compute_finance_metrics', store=True, index=True)
|
|
payment_status = fields.Selection([
|
|
('no_dues', 'No Dues'),
|
|
('partial', 'Partial'),
|
|
('overdue', 'Overdue'),
|
|
('fully_paid', 'Fully Paid')
|
|
], string='Payment Status', compute='_compute_finance_metrics', default='no_dues', store=True, index=True)
|
|
|
|
@api.depends('ledger_line_ids.debit', 'ledger_line_ids.credit', 'ledger_line_ids.status', 'payment_ids.amount', 'payment_ids.status', 'payment_ids.payment_date', 'payment_ids.receipt_number')
|
|
def _compute_finance_metrics(self):
|
|
for rec in self:
|
|
active_ledgers = rec.ledger_line_ids.filtered(lambda l: l.status in ('outstanding', 'paid'))
|
|
total_debits = sum(line.debit for line in active_ledgers)
|
|
total_credits = sum(line.credit for line in active_ledgers)
|
|
rec.total_fees = total_debits
|
|
|
|
confirmed_payments = rec.payment_ids.filtered(lambda p: p.status == 'confirmed').sorted(key=lambda p: (p.payment_date or fields.Date.today(), p.id), reverse=True)
|
|
rec.total_paid = sum(p.amount for p in confirmed_payments)
|
|
rec.outstanding_amount = total_debits - total_credits
|
|
|
|
last_payment = confirmed_payments[0] if confirmed_payments else False
|
|
rec.last_payment_date = last_payment.payment_date if last_payment else False
|
|
rec.last_receipt_number = last_payment.receipt_number if last_payment else False
|
|
|
|
if total_debits == 0:
|
|
rec.payment_status = 'no_dues'
|
|
elif rec.outstanding_amount <= 0:
|
|
rec.payment_status = 'fully_paid'
|
|
elif rec.total_paid > 0:
|
|
rec.payment_status = 'partial'
|
|
else:
|
|
rec.payment_status = 'overdue'
|