from odoo import api, fields, models from odoo.exceptions import ValidationError class AcademicTerm(models.Model): _name = 'education.academic.term' _description = 'Academic Term' _order = 'sequence, start_date' name = fields.Char(required=True, string='Term Name') code = fields.Char(string='Code', required=True, index=True) academic_year_id = fields.Many2one( 'education.academic.year', string='Academic Year', required=True, ondelete='restrict', index=True, ) start_date = fields.Date(string='Start Date', required=True) end_date = fields.Date(string='End Date', required=True) sequence = fields.Integer(default=1, required=True) active = fields.Boolean(default=True) state = fields.Selection([ ('draft', 'Draft'), ('active', 'Active'), ('closed', 'Closed'), ], default='draft', required=True) company_id = fields.Many2one( 'res.company', related='academic_year_id.company_id', store=True, readonly=True, index=True, ) _sql_constraints = [ ('uniq_term_code_year', 'unique(code, academic_year_id)', 'Term code must be unique within the academic year.'), ('uniq_term_sequence_year', 'unique(sequence, academic_year_id)', 'Term sequence must be unique within the academic year.'), ] @api.constrains('start_date', 'end_date') def _check_term_dates(self): for rec in self: if rec.start_date and rec.end_date and rec.start_date > rec.end_date: raise ValidationError('End date must be greater than start date.') @api.constrains('academic_year_id', 'start_date', 'end_date') def _check_term_overlap(self): for rec in self: if not rec.academic_year_id: continue overlapping = self.search([ ('id', '!=', rec.id), ('academic_year_id', '=', rec.academic_year_id.id), ('start_date', '<=', rec.end_date), ('end_date', '>=', rec.start_date), ]) if overlapping: raise ValidationError('Academic terms within the same year cannot overlap.') def action_activate(self): self.write({'state': 'active'}) def action_close(self): self.write({'state': 'closed'})