from odoo import api, fields, models from odoo.exceptions import ValidationError class McExam(models.Model): _name = "mc.exam" _inherit = ["mail.thread"] _description = "Exam" _order = "date desc" _rec_name = "display_name" name = fields.Char(string="Name", required=True) term_id = fields.Many2one("mc.academic.term", string="Term", required=True, ondelete="restrict") batch_id = fields.Many2one("mc.batch", string="Batch", required=True, ondelete="restrict") subject_id = fields.Many2one("mc.subject", string="Subject", required=True, ondelete="restrict") max_marks = fields.Float(string="Max Marks", required=True, default=100) pass_marks = fields.Float(string="Pass Marks", required=True, default=35) date = fields.Date(string="Date", required=True) mark_ids = fields.One2many("mc.mark", "exam_id", string="Marks") _batch_subject_term_uniq = models.Constraint( "unique(batch_id, subject_id, term_id, name)", "An exam with this name already exists for this batch, subject and term.", ) @api.depends("name", "batch_id.name", "subject_id.name") def _compute_display_name(self): for exam in self: exam.display_name = "%s - %s (%s)" % ( exam.name, exam.batch_id.name or "?", exam.subject_id.name or "?", ) @api.constrains("max_marks", "pass_marks") def _check_marks_positive(self): for exam in self: if exam.max_marks <= 0: raise ValidationError("Max marks must be greater than zero.") if exam.pass_marks < 0 or exam.pass_marks > exam.max_marks: raise ValidationError("Pass marks must be between 0 and max marks.") def action_enter_marks(self): self.ensure_one() enrollments = self.env["mc.enrollment"].search([ ("batch_id", "=", self.batch_id.id), ("state", "=", "active"), ]) existing_student_ids = set(self.mark_ids.mapped("student_id").ids) to_create = [ {"exam_id": self.id, "student_id": enrollment.student_id.id, "marks_obtained": 0} for enrollment in enrollments if enrollment.student_id.id not in existing_student_ids ] if to_create: self.env["mc.mark"].create(to_create) return { "type": "ir.actions.act_window", "name": "Enter Marks - %s" % self.display_name, "res_model": "mc.mark", "view_mode": "list", "domain": [("exam_id", "=", self.id)], "context": {"default_exam_id": self.id}, }