EMS

EMS — Developer Documentation

Technical reference for developers working on the EMS module.


Curriculum

Model Description
ems.level Study levels (top of the curriculum hierarchy)
ems.study Study programmes under a level: subjects, curriculum documents, the uses_enrollment_flow derived flag
ems.subject Subjects: the most widely referenced curriculum node, and the automatic product.product sync on create/write
ems.outcome Learning outcomes nested in a subject’s form — no menu of its own; the subject_id dangling-compute bug fix
ems.criteria Evaluation criteria nested two levels deep (subject → outcome popup → criteria popup); the identical dangling-compute bug fix on outcome_id
ems.content Content items with a real self-referencing “Composite” hierarchy; fixes a view-context bug where adding a nested child silently created a sibling instead

Settings

Model Description
ems.course Academic year windows; known limitation — no course-management UI exists yet (only the “Current course” selector), see the doc for the unbuilt “Setup next course” TODO
res.company (EMS extension) Every centre-wide config field EMS adds, grouped by area with cross-links to their owning feature docs; the Fernet-encrypted credential pattern (limesurvey_pwd, google_ws_sa_json) and a real NameError bug fixed in its inverse method
res.config.settings (EMS extension) The related-field proxy that makes every res.company field above editable from Settings; set_values()’s EMS auto-checkout cron activation

Facilities

Model Description
ems.space_type Kinds of physical space (classroom, lab…); removed a stale TODO comment about a config page that already existed
ems.space Physical spaces, widely referenced by scheduling/attendance/documentation models

Contacts

Model Description
ems.group The core class-group model — one of the most widely-referenced in EMS; group_type switching, the tutor-role sync bug fix, the side-effecting enrollment_view_ids compute
Group schedule (read-only aggregation) The group form’s “Schedule” tab: aggregating teachers’ resource.calendar.attendance rows by group_ids, deriving the break period from the level’s schedule framework, the “Subject → Teacher(s)” co-teaching summary, and the PDF export
Student schedule (read-only aggregation) The student form’s own “Schedule” tab: the same read-only mechanism as the group’s, reused via the shared readonly_schedule_grid widget, but scoped per (subject_id, group_id) enrollment pair instead of a whole group — and the overlap-aware column-split layout that scoping makes necessary
ems.contact.data.request Contact data update requests: sending them from the backend (individually or by group, study or level), the portal page students and families answer on, family-contact recognition and linking, and the review/approval flow that applies the staged changes

Employees

Topic Description
hr.employee (EMS extension) Map of the whole model — cross-links every already-documented area (roles, schedule, photo, Google Workspace) plus a real compute_sudo bug fix on read_only, new get_report_role_lines() branch coverage, and a flagged ems.group.create() gap
Academic role hierarchy Teacher → Tutor → Department Chief → Head of Studies → Director → Administrator group chain and how roles sync to res.users.groups_id
Department Chief / Seminar Chief / Head of Studies / Director cascade hr.department.manager_id/seminar_chief_id/is_top_level/top_level_role (Head of Studies/Deputy/Secretary) plus res.company.director_id driving hr.employee.parent_id (between departments and up to the Director) and the role_dchieff/role_seminar/role_hos/role_dhos/role_secretary/role_director roles automatically
hr.job (EMS extension) Two fields only (employee_type, group_id) — the security-group auto-grant is consumed and already tested from hr.employee’s side
ems.workgroup Simple free-form employee grouping (project teams, committees) — no business logic
ems.teaching Ternary teacher/group/subject relation, derived from and kept in sync with the schedule via _sync_from_schedule()
ems.non_teaching_type Catalogue of non-subject schedule period types (breaks, guard duties); note the admin group is group_department_chief, not the usual group_academic_admin
hr.attendance auto-checkout (EMS extension) Closing stale open attendances on check-in, and the EMS nightly cron mode using the employee’s real schedule instead of fixed hours
res.users (EMS extension) _sync_ems_implied_groups() — compensates for Odoo’s own implied-group grants being permanent/never auto-revoked
ems.tracking Free-form student follow-up notes; flags a possible access-scope mismatch (teachers described as able to “add” notes but only granted read access)
Teacher working schedules & schedule frameworks The “Schedule” tab widget, schedule frameworks, the empty-slot rule, employee lifecycle hooks, the XML import wizard
Google Workspace staff integration & EMS user auto-creation Corporate Google account creation (Directory API), automatic res.users with OAuth pre-link, lifecycle sync (archive ↔ suspend), required-fields chain
Profile picture disable switch The res.users.image_disabled toggle, keeping hr.employee/res.users photos in sync, and the write_photo() mimetype-safety helper

Attendance

Model Description
ems.attendance_template Who teaches what, where and for whom: schedule sync/reconciliation from the “Schedule” tab and the XML importer, co-teaching, external-conflict detection
ems.attendance_status Archivable model replacing the old hardcoded status enum; status_id field rename across the session line, justification, issue-notification and reporting code; the “Issue” status retirement now that ems.strike covers it
Guard Duty Schedule Board Read-only, centre-wide view of every teacher’s occupied time blocks per weekday, with guard-duty teachers highlighted separately; extends ems.course, ems.non_teaching_type.is_guard

Coexistence

Model Description
ems.strike Disciplinary notices issued from the roll-call view: recipient/authorization rules, HoS/DHoS-branch escalation matching, access control

Meetings

Model Description
ems.meeting.presence Meeting attendance confirmed with the NFC tag at a public token-protected kiosk: convened list by scope, scan outcomes, closing, access control, and how it joins the quality work’s minutes

Enrollment

Model Description
ems.enrollment_proposal_wizard Bulk draft enrollments from a student selection, and the secretary-only allow_other_study flag that enrolls a current student into a different study
Enrollment benefits Fee bonifications/exemptions: draft-order recompute, freeze after confirmation and the secretary re-apply action that regenerates the invoice

Settings

Model Description
ems.course_transition_wizard End-of-year transition: study-scoped preview and apply, graduates archived as alumni, bulk placement from the destination enrollments and conditional course flip

Shared

Topic Description
Free-pick color widget widget="color" + the ems_color_swatch styling, the role_color_tags badge widget, and ems.hex_color_mixin — used by ems.role, ems.attendance_template, and hr.department’s custom_color
Task assignment mail.activity.type’s ems_task_assignment/ems_assignee_ids — an explicit, config-driven recipient list decoupled from security groups
ems.base Chatter/notification helpers (notify, chatter, chatter_exception), permission checks (get_user_is_admin/_tutor), persistent_hash — the foundational mixin inherited by most business models
ems.datetime_utils Timezone-aware ↔ naive-UTC ↔ float-hour conversions shared by every attendance/schedule model
Dates, times and timezones The one-timezone policy (always the company’s): server-side helpers, the web client’s company-timezone service and serverNow(), and the record-level tz alignment
ems.multithreading The run_in_thread() setup/compute/store/callback engine behind the LimeSurvey integration’s long-running actions
ems.schedule_report_mixin The shared weekly-schedule aggregation-to-report pipeline (report-line building, break derivation, colour/time-label helpers) behind both the group’s and the student’s own read-only Schedule tab
google.workspace.mixin The Directory API client, password policy, and text/phone normalization shared by the staff and student Google Workspace integrations
User menu “Documentation” entry Points the avatar dropdown’s native “Documentation” entry at EMS’s own user manuals, in the user’s language, instead of Odoo’s developer docs
Shared test utilities tests/common.py: create_level_study(_group), mock_outgoing_email, make_synchronous_run_in_thread — fixture/mock boilerplate extracted after it was found duplicated across dozens of test files

Tooling

Topic Description
AI agent test notifications when running inside a container Why push/desktop notifications from an AI coding agent don’t reach you inside an LXC/Incus/Docker container reached via an editor extension, and how to bridge them with a host-side file-drop watcher + a Claude Code hook

More information about the project on the GitHub repository.