2026-09-15 10:47:19 +05:30

69 lines
3.2 KiB
Python

from odoo import models, fields, api
from odoo.exceptions import ValidationError
class EducationGradingSystem(models.Model):
_name = 'education.grading.system'
_description = 'Grading System'
name = fields.Char(string='Name', required=True)
code = fields.Char(string='Code', required=True)
scale_type = fields.Selection([
('percentage', 'Percentage'),
('gpa_4', 'GPA 4.0'),
('gpa_10', 'GPA 10.0')
], string='Scale Type', required=True, default='percentage')
active = fields.Boolean(default=True)
grade_ids = fields.One2many('education.grade', 'grading_system_id', string='Grades')
def get_grade(self, percentage):
self.ensure_one()
grade = self.grade_ids.filtered(lambda g: g.min_percentage <= percentage <= g.max_percentage)
if grade:
# If multiple match due to floating point edge cases, take the highest grade point
return grade.sorted('grade_point', reverse=True)[0]
return self.env['education.grade']
class EducationGrade(models.Model):
_name = 'education.grade'
_description = 'Education Grade'
_order = 'sequence, id'
grading_system_id = fields.Many2one('education.grading.system', string='Grading System', required=True, ondelete='cascade')
name = fields.Char(string='Name', required=True)
code = fields.Char(string='Code')
min_percentage = fields.Float(string='Minimum Percentage', required=True)
max_percentage = fields.Float(string='Maximum Percentage', required=True)
grade_point = fields.Float(string='Grade Point', required=True)
result_status = fields.Selection([
('pass', 'Pass'),
('fail', 'Fail')
], string='Result Status', required=True, default='pass')
sequence = fields.Integer(string='Sequence', default=10)
active = fields.Boolean(default=True)
@api.constrains('min_percentage', 'max_percentage')
def _check_percentages(self):
for record in self:
if record.min_percentage < 0 or record.max_percentage > 100:
raise ValidationError("Percentages must be between 0 and 100.")
if record.min_percentage > record.max_percentage:
raise ValidationError("Minimum percentage cannot be greater than maximum percentage.")
# Check overlaps
domain = [
('grading_system_id', '=', record.grading_system_id.id),
('id', '!=', record.id),
'|', '|',
'&', ('min_percentage', '<=', record.min_percentage), ('max_percentage', '>=', record.min_percentage),
'&', ('min_percentage', '<=', record.max_percentage), ('max_percentage', '>=', record.max_percentage),
'&', ('min_percentage', '>=', record.min_percentage), ('max_percentage', '<=', record.max_percentage),
]
if self.search_count(domain) > 0:
raise ValidationError("Grade percentage ranges cannot overlap within the same grading system.")
@api.constrains('grade_point')
def _check_grade_point(self):
for record in self:
if record.grade_point < 0:
raise ValidationError("Grade point cannot be negative.")