from odoo import models, fields, api from odoo.exceptions import ValidationError, AccessError class EducationLMSSection(models.Model): _name = 'education.lms.section' _description = 'LMS Section' _order = 'sequence, id' name = fields.Char(string='Name', required=True) course_id = fields.Many2one('education.lms.course', string='Course', required=True, ondelete='cascade') sequence = fields.Integer(string='Sequence', default=10) description = fields.Text(string='Description') published = fields.Boolean(string='Published', default=False) active = fields.Boolean(default=True) lesson_ids = fields.One2many('education.lms.lesson', 'section_id', string='Lessons') @api.constrains('published', 'course_id') def _check_published_state(self): for record in self: if record.published and record.course_id.state != 'published': raise ValidationError("Cannot publish a section if the parent course is not published.") @api.constrains('course_id') def _check_section_ownership(self): if self.env.su or self.env.user.has_group('education_lms.group_education_lms_admin'): return for record in self: if record.course_id.faculty_id.id != self.env.user.id: raise AccessError("You can only create or modify sections for your own courses.") class EducationLMSLesson(models.Model): _name = 'education.lms.lesson' _description = 'LMS Lesson' _order = 'sequence, id' name = fields.Char(string='Name', required=True) section_id = fields.Many2one('education.lms.section', string='Section', required=True, ondelete='cascade') course_id = fields.Many2one('education.lms.course', related='section_id.course_id', store=True, string='Course') sequence = fields.Integer(string='Sequence', default=10) description = fields.Html(string='Content') published = fields.Boolean(string='Published', default=False) active = fields.Boolean(default=True) material_ids = fields.One2many('education.lms.material', 'lesson_id', string='Materials') @api.constrains('published', 'section_id') def _check_published_state(self): for record in self: if record.published and not record.section_id.published: raise ValidationError("Cannot publish a lesson if the parent section is not published.") @api.constrains('section_id') def _check_lesson_ownership(self): if self.env.su or self.env.user.has_group('education_lms.group_education_lms_admin'): return for record in self: if record.section_id.course_id.faculty_id.id != self.env.user.id: raise AccessError("You can only create or modify lessons for your own courses.") class EducationLMSMaterial(models.Model): _name = 'education.lms.material' _description = 'LMS Material' _order = 'sequence, id' name = fields.Char(string='Name', required=True) lesson_id = fields.Many2one('education.lms.lesson', string='Lesson', required=True, ondelete='cascade') material_type = fields.Selection([ ('file', 'File/Document'), ('url', 'URL/Link'), ('video', 'Video Link') ], string='Type', required=True, default='file') attachment_id = fields.Many2one('ir.attachment', string='Attachment') url = fields.Char(string='URL') sequence = fields.Integer(string='Sequence', default=10) description = fields.Text(string='Description') published = fields.Boolean(string='Published', default=False) active = fields.Boolean(default=True) @api.constrains('material_type', 'attachment_id', 'url') def _check_material_content(self): for record in self: if record.material_type == 'file' and not record.attachment_id: raise ValidationError("File material must have an attachment.") elif record.material_type in ['url', 'video'] and not record.url: raise ValidationError("URL or Video material must have a URL provided.") @api.constrains('published', 'lesson_id') def _check_published_state(self): for record in self: if record.published and not record.lesson_id.published: raise ValidationError("Cannot publish a material if the parent lesson is not published.") @api.constrains('lesson_id') def _check_material_ownership(self): if self.env.su or self.env.user.has_group('education_lms.group_education_lms_admin'): return for record in self: if record.lesson_id.section_id.course_id.faculty_id.id != self.env.user.id: raise AccessError("You can only create or modify materials for your own courses.")