104 lines
3.6 KiB
Python
104 lines
3.6 KiB
Python
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.")
|