from odoo import api, fields, models class CommunitySchoolEnrollment(models.Model): _name = 'community.school.enrollment' _description = 'School Enrollment' _order = 'id desc' student_id = fields.Many2one('community.school.student', required=True, ondelete='cascade') class_id = fields.Many2one('community.school.class', required=True, ondelete='cascade') term_id = fields.Many2one(related='class_id.term_id', store=True) enrollment_date = fields.Date(default=fields.Date.context_today) state = fields.Selection( [ ('waitlist', 'Waitlisted'), ('enrolled', 'Enrolled'), ('completed', 'Completed'), ('withdrawn', 'Withdrawn'), ], default='enrolled', required=True, ) payment_state = fields.Selection( [('not_invoiced', 'Not Invoiced'), ('invoiced', 'Invoiced'), ('paid', 'Paid')], default='not_invoiced', required=True, ) invoice_id = fields.Many2one('account.move', readonly=True, copy=False) attendance_ids = fields.One2many('community.school.attendance', 'enrollment_id') attendance_rate = fields.Float(compute='_compute_attendance_rate') is_at_risk = fields.Boolean(compute='_compute_is_at_risk') @api.depends('attendance_ids.state') def _compute_attendance_rate(self): for enrollment in self: records = enrollment.attendance_ids total = len(records) if not total: enrollment.attendance_rate = 0.0 continue present = len(records.filtered(lambda a: a.state in ('present', 'late'))) enrollment.attendance_rate = (present / total) * 100.0 @api.depends('attendance_rate', 'attendance_ids') def _compute_is_at_risk(self): threshold = int(self.env['ir.config_parameter'].sudo().get_param( 'community_school.at_risk_attendance_threshold', 70 )) for enrollment in self: enrollment.is_at_risk = bool(enrollment.attendance_ids) and enrollment.attendance_rate < threshold def action_enroll_from_waitlist(self): for enrollment in self: if enrollment.state == 'waitlist' and enrollment.class_id.enrolled_count < enrollment.class_id.max_students: enrollment.state = 'enrolled' return True