Skip to main content
OpenEduCat logo
Pull Sync

Moodle Grade Sync

Grades recorded in Moodle, through the gradebook, assignment submissions, or quiz attempts, flow into OpenEduCat's gradebook automatically. Every 15 minutes, the sync service checks for changes. Records that haven't changed are skipped. When something changes, the OEC record is updated and gradebook totals are recomputed.

Moodle is the authoritative source for learning data. When a conflict exists, Moodle wins. The sync prevents infinite write loops by setting a connector_no_export flag on the Odoo environment during all pull operations.

Supported Grade Sources

Four grade sources from Moodle, each pulled via a specific WS function and written to a specific OEC model.

Grade sourceMoodle WS functionOEC target model
Gradebook gradesgradereport_user_get_grade_itemsop.result.line / gradebook.line
Assignment submissionsmod_assign_get_gradesop.exam.attendees
Quiz best-gradesmod_quiz_get_user_best_gradeop.exam.attendees
Course completioncore_completion_get_course_completion_statusmoodle.mapping.extra_data

Grade Pipeline

What happens inside SyncGrades.pull_all_combined() on every cron run.

1

Cron fires (every 15 min)

_cron_grade_pull on the moodle.instance model iterates all active instances.

2

Fetch grade items from Moodle

SyncGrades._prefetch_mappings() loads all student mappings in one query into _student_map. Then gradereport_user_get_grade_items is called per Moodle course.

3

Hash comparison

SHA-256 of (grade_raw:grade_max) is compared against moodle.mapping.sync_hash. Unchanged grades skip all OEC writes.

4

OEC record creation

Community path: op.exam.session → op.exam → op.exam.attendees + op.result.line. Enterprise path (if openeducat_grading installed): grading.assignment → gradebook.gradebook → gradebook.line.

5

Gradebook recompute

_recompute_gradebooks() calls calculate_percentage() and student_Grade_override() once across all affected gradebooks, not per-grade-item.

6

Completion sync

SyncCompletion runs after grade pull, updating enrollment mapping extra_data with complete/incomplete per student-course pair.

Sync Frequency and Triggers

Cron (default)

Every 15 minutes

_cron_grade_pull runs on all active instances. Lightweight due to hash-skip on unchanged records.

Manual trigger

Immediate

"Pull Grades Now" button on the Moodle Instance form in Odoo, or call action_pull_grades_now() via RPC.

Manual wizard

On demand

The Sync Wizard supports a dry-run preview before committing any grade writes to OEC.

Conflict resolution

Moodle is authoritative for learning data. If a grade exists in OEC and the Moodle pull returns a different value, the Moodle value overwrites OEC on the next pull. To prevent the write from triggering a push back to Moodle (which would create an infinite loop), all pull services set connector_no_export=True on the Odoo environment in their constructor:

self.env = env(context=dict(env.context, connector_no_export=True))

Every write() hook on OEC models checks this flag before enqueueing a push job.

Community vs Enterprise Grade Path

The sync service detects which OEC edition is installed and writes grades to the appropriate model.

Community Edition

Requires openeducat_exam module. Creates an op.exam.session op.exam op.exam.attendees + op.result.line hierarchy. Exam state is advanced via sudo().act_held() because the state field is readonly on the model.

Enterprise Edition

Requires openeducat_grading module (takes priority if both installed). Creates a grading.assignment gradebook.gradebook gradebook.line hierarchy. Calls calculate_percentage() and student_Grade_override() once per batch, not per grade item.

Grade Sync Configuration

These fields on the Moodle Instance record in Odoo control grade sync behavior.

FieldDefaultDescription
Pull Gradebook GradesOnEnable/disable the gradereport_user_get_grade_items pull
Pull Assignment GradesOnEnable/disable the mod_assign_get_grades pull
Pull Quiz GradesOnEnable/disable the mod_quiz_get_user_best_grade pull
Grade Scale TypepercentageHow grades are stored in OEC: percentage, letter, or points
Pass Threshold (%)50.0Below this percentage → fail state in community exam creation
Grade Scale(empty)Letter grade bands from moodle.grade.scale.line (e.g., A=90-100)
Pull Completion StatusOnRun SyncCompletion after each grade pull cycle

Grade Sync, Frequently Asked Questions

Technical questions about the Moodle → OEC grade pipeline.

The default cron runs every 15 minutes. You can also trigger an immediate pull via the "Pull Grades Now" button on the Moodle Instance form in Odoo, or call action_pull_grades_now() via RPC. The grade sync uses SHA-256 hashing on the (grade_raw, grade_max) pair; unchanged grades are skipped, so the 15-minute cron is very lightweight.

Ready to Transform Your Grade Sync?

See how OpenEduCat frees up time so every student gets the attention they deserve.

Try it free for 15 days. No credit card required.