from odoo import models, fields, api from odoo.exceptions import ValidationError class SchoolGradesheetLine(models.Model): _name = 'school.gradesheet.line' _description = 'Student Grade Line' _order = 'student_name' gradesheet_id = fields.Many2one('school.gradesheet', string="Gradesheet", ondelete="cascade") application_id = fields.Many2one('school.application', string="Application", required=True) student_id = fields.Many2one('school.application', string="Student", required=True) student_name = fields.Char(related='student_id.name', string="Student Name", store=True) roll_number = fields.Char(related='student_id.roll_no', string="Roll Number", store=True) subject_id = fields.Many2one('school.subject', string="Subject") enrollment_id = fields.Many2one( 'school.enrollment', string="Enrollment" ) obtained_marks = fields.Float( string="Obtained Marks", default=0.0 ) total_marks = fields.Float( string="Total Marks", default=100.0 ) percentage = fields.Float( string="Percentage (%)", compute="_compute_percentage", store=True ) # Grade Info final_grade = fields.Selection([ ('A+', 'A+ (90-100%)'), ('A', 'A (80-89%)'), ('B+', 'B+ (70-79%)'), ('B', 'B (60-69%)'), ('C', 'C (50-59%)'), ('D', 'D (40-49%)'), ('F', 'F (Below 40%)') ], string="Grade", default='F') status = fields.Selection([ ('pass', 'Pass'), ('fail', 'Fail') ], string="Status", default='fail') remarks = fields.Text(string="Remarks") # Compute percentage @api.depends('obtained_marks', 'total_marks') def _compute_percentage(self): for record in self: if record.total_marks > 0: record.percentage = (record.obtained_marks / record.total_marks) * 100 else: record.percentage = 0.0 # Auto-update grade and status on marks change @api.onchange('obtained_marks', 'total_marks') def _onchange_marks(self): for record in self: if record.total_marks > 0: percentage = (record.obtained_marks / record.total_marks) * 100 if percentage >= 90: record.final_grade = 'A+' record.status = 'pass' elif percentage >= 80: record.final_grade = 'A' record.status = 'pass' elif percentage >= 70: record.final_grade = 'B+' record.status = 'pass' elif percentage >= 60: record.final_grade = 'B' record.status = 'pass' elif percentage >= 50: record.final_grade = 'C' record.status = 'pass' elif percentage >= 40: record.final_grade = 'D' record.status = 'pass' else: record.final_grade = 'F' record.status = 'fail' else: record.percentage = 0.0 record.final_grade = 'F' record.status = 'fail' # Validation to prevent invalid marks @api.constrains('obtained_marks', 'total_marks') def _check_marks(self): for record in self: if record.obtained_marks < 0 or record.total_marks < 0: raise ValidationError("Marks cannot be negative.") if record.obtained_marks > record.total_marks: raise ValidationError("Obtained marks cannot exceed total marks.")