metatroncubeswdev a36c89222b O5: mc_education_timetable - one dataset, three views, conflict-checked
Serves Demo Scene 7: mc.timetable.slot (batch, weekday, period,
subject, teacher, room, year, term) is the single dataset. "Three
read views" are three entry points into that same model rather than
three separate data structures - a stat button on mc.batch, on
mc.teacher, and on mc.student (resolved through the student's active
enrollment to their batch) each open the same list/search action with
a different domain. Auto-generation is out of scope per spec; this
module only configures slots by hand (demo data is a real Mon-Fri
week for Grade 8-A, since a timetable is a recurring weekly pattern
and one week fully represents it, unlike attendance/fees which
genuinely need a run of history).

Conflict prevention ("a teacher or a room cannot hold two slots in
the same weekday+period") follows the same two-layer pattern used for
mc.academic.year.is_current and mc.enrollment in O1: a partial unique
index per conflict type (teacher, room, and - not explicitly asked
for but an obvious extension of the same rule - batch, since a batch
can't be in two places at once either) is the actual guarantee, and a
pre-check in create()/write() raises a readable ValidationError
before the insert/update, not after, for the same reason established
building mc.enrollment: the DB index fires first and the friendly
message is unreachable otherwise.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 12:53:47 -04:00

23 lines
769 B
Python

from odoo import _, models
from odoo.exceptions import UserError
class McStudent(models.Model):
_inherit = "mc.student"
def action_view_timetable(self):
self.ensure_one()
enrollment = self.env["mc.enrollment"].search([
("student_id", "=", self.id), ("state", "=", "active"),
], limit=1)
if not enrollment:
raise UserError(_("%s has no active enrollment.") % self.name)
return {
"type": "ir.actions.act_window",
"name": "Timetable - %s" % self.name,
"res_model": "mc.timetable.slot",
"view_mode": "list,form",
"domain": [("batch_id", "=", enrollment.batch_id.id)],
"context": {"search_default_group_weekday": 1},
}