Files
Odoo-Tutorial/CatEdu/openeducat_exam/models/exam.py
T
2025-05-05 09:03:48 +07:00

127 lines
5.2 KiB
Python

###############################################################################
#
# OpenEduCat Inc
# Copyright (C) 2009-TODAY OpenEduCat Inc(<https://www.openeducat.org>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
import datetime
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class OpExam(models.Model):
_name = "op.exam"
_inherit = "mail.thread"
_description = "Exam"
session_id = fields.Many2one('op.exam.session', 'Exam Session',
domain=[('state', 'not in',
['cancel', 'done'])])
course_id = fields.Many2one(
'op.course', related='session_id.course_id', store=True,
readonly=True)
batch_id = fields.Many2one(
'op.batch', 'Batch', related='session_id.batch_id', store=True,
readonly=True)
subject_id = fields.Many2one('op.subject', 'Subject', required=True)
exam_code = fields.Char('Exam Code', size=16, required=True)
attendees_line = fields.One2many(
'op.exam.attendees', 'exam_id', 'Attendees', readonly=True)
start_time = fields.Datetime('Start Time', required=True)
end_time = fields.Datetime('End Time', required=True)
state = fields.Selection(
[('draft', 'Draft'), ('schedule', 'Scheduled'), ('held', 'Held'),
('result_updated', 'Result Updated'),
('cancel', 'Cancelled'), ('done', 'Done')], 'State',
readonly=True, default='draft', tracking=True)
note = fields.Text('Note')
responsible_id = fields.Many2many('op.faculty', string='Responsible')
name = fields.Char('Exam', size=256, required=True)
total_marks = fields.Integer('Total Marks', required=True)
min_marks = fields.Integer('Passing Marks', required=True)
active = fields.Boolean(default=True)
attendees_count = fields.Integer(string='Attendees Count',
compute='_compute_attendees_count')
_sql_constraints = [
('unique_exam_code',
'unique(exam_code)', 'Code should be unique per exam!')]
@api.constrains('total_marks', 'min_marks')
def _check_marks(self):
if self.total_marks <= 0.0 or self.min_marks <= 0.0:
raise ValidationError(_('Enter proper marks!'))
if self.min_marks > self.total_marks:
raise ValidationError(_(
"Passing Marks can't be greater than Total Marks"))
@api.constrains('start_time', 'end_time')
def _check_date_time(self):
session_start = datetime.datetime.combine(
fields.Date.from_string(self.session_id.start_date),
datetime.time.min)
session_end = datetime.datetime.combine(
fields.Date.from_string(self.session_id.end_date),
datetime.time.max)
start_time = fields.Datetime.from_string(self.start_time)
end_time = fields.Datetime.from_string(self.end_time)
if start_time > end_time:
raise ValidationError(_('End Time cannot be set before Start Time.'))
elif start_time < session_start or start_time > session_end or \
end_time < session_start or end_time > session_end:
raise ValidationError(
_('Exam Time should in between Exam Session Dates.'))
def open_exam_attendees(self):
return {
"type": "ir.actions.act_window",
"res_model": "op.exam.attendees",
"domain": [("exam_id", "=", self.id)],
"name": "Students",
"view_mode": "list,form",
}
def _compute_attendees_count(self):
for record in self:
record.attendees_count = self.env["op.exam.attendees"].search_count(
[("exam_id", "=", record.id)])
@api.constrains('subject_id', 'start_time', 'end_time')
def _check_overlapping_times(self):
for record in self:
existing_exams = self.env['op.exam'].search([
('subject_id', '=', record.subject_id.id),
('id', '!=', record.id),
('start_time', '<', record.end_time),
('end_time', '>', record.start_time),
])
if existing_exams:
raise ValidationError(_('The exam time overlaps with an existing exam for the same subject.')) # noqa
def act_result_updated(self):
self.state = 'result_updated'
def act_done(self):
self.state = 'done'
def act_draft(self):
self.state = 'draft'
def act_cancel(self):
self.state = 'cancel'