From 3088b14d83e1792c0bf0a05721008afadd36954b Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Tue, 24 Feb 2026 17:40:58 +0530 Subject: [PATCH] fix: recalculate course progress when lesson is inserted or deleted --- frontend/src/pages/Lesson.vue | 5 ++-- lms/lms/api.py | 2 +- .../doctype/course_chapter/course_chapter.py | 15 +----------- .../doctype/course_lesson/course_lesson.py | 23 ++++++++++++++++++- .../lms_course_progress.py | 15 ++---------- lms/lms/utils.py | 15 ++++++++++++ 6 files changed, 44 insertions(+), 31 deletions(-) diff --git a/frontend/src/pages/Lesson.vue b/frontend/src/pages/Lesson.vue index 2a8a9523..a334af82 100644 --- a/frontend/src/pages/Lesson.vue +++ b/frontend/src/pages/Lesson.vue @@ -400,7 +400,7 @@ const sidebarStore = useSidebar() const plyrSources = ref([]) const showInlineMenu = ref(false) const currentTab = ref('Notes') -let timerInterval +let timerInterval = null const tabs = ref([ { @@ -742,7 +742,8 @@ const updateVideoTime = (video) => { const startTimer = () => { if (!lesson.data?.membership) return - let timerInterval = setInterval(() => { + timerInterval = setInterval(() => { + console.log('Timer:', timer.value) timer.value++ if (timer.value == 30) { clearInterval(timerInterval) diff --git a/lms/lms/api.py b/lms/lms/api.py index f6d5250c..69ac3088 100644 --- a/lms/lms/api.py +++ b/lms/lms/api.py @@ -475,7 +475,7 @@ def delete_lesson(lesson: str, chapter: str): update_index(lessons, chapter) frappe.db.delete("LMS Course Progress", {"lesson": lesson}) - frappe.db.delete("Course Lesson", lesson) + frappe.delete_doc("Course Lesson", lesson) @frappe.whitelist() diff --git a/lms/lms/doctype/course_chapter/course_chapter.py b/lms/lms/doctype/course_chapter/course_chapter.py index 04c89587..251a14b2 100644 --- a/lms/lms/doctype/course_chapter/course_chapter.py +++ b/lms/lms/doctype/course_chapter/course_chapter.py @@ -4,25 +4,12 @@ import frappe from frappe.model.document import Document -from lms.lms.utils import get_course_progress, get_lesson_count +from lms.lms.utils import get_lesson_count class CourseChapter(Document): def on_update(self): - self.recalculate_course_progress() self.update_lesson_count() - frappe.enqueue(method=self.recalculate_course_progress, queue="short", timeout=300, is_async=True) - - def recalculate_course_progress(self): - """Recalculate course progress if a new lesson is added or removed""" - previous_lessons = self.get_doc_before_save() and self.get_doc_before_save().as_dict().lessons - current_lessons = self.lessons - - if previous_lessons and previous_lessons != current_lessons: - enrolled_members = frappe.get_all("LMS Enrollment", {"course": self.course}, ["member", "name"]) - for enrollment in enrolled_members: - new_progress = get_course_progress(self.course, enrollment.member) - frappe.db.set_value("LMS Enrollment", enrollment.name, "progress", new_progress) def update_lesson_count(self): """Update lesson count in the course""" diff --git a/lms/lms/doctype/course_lesson/course_lesson.py b/lms/lms/doctype/course_lesson/course_lesson.py index 7add79ab..8c0c821c 100644 --- a/lms/lms/doctype/course_lesson/course_lesson.py +++ b/lms/lms/doctype/course_lesson/course_lesson.py @@ -9,15 +9,36 @@ from frappe.model.document import Document from frappe.realtime import get_website_room from frappe.utils.telemetry import capture -from lms.lms.utils import get_course_progress +from lms.lms.utils import get_course_progress, recalculate_course_progress from ...md import find_macros class CourseLesson(Document): + def after_insert(self): + frappe.enqueue(method=self.recalculate_progress, queue="long", is_async=True) + + def after_delete(self): + frappe.enqueue(method=self.recalculate_progress, queue="long", is_async=True) + def on_update(self): self.validate_quiz_id() + def recalculate_progress(self): + if not self.course or not self.chapter: + return + + enrollments = frappe.db.get_all( + "LMS Enrollment", + filters={"course": self.course}, + fields=["name", "member"], + ) + if not len(enrollments): + return + + for enrollment in enrollments: + recalculate_course_progress(self.course, enrollment.member) + def validate_quiz_id(self): if self.quiz_id and not frappe.db.exists("LMS Quiz", self.quiz_id): frappe.throw(_("Invalid Quiz ID")) diff --git a/lms/lms/doctype/lms_course_progress/lms_course_progress.py b/lms/lms/doctype/lms_course_progress/lms_course_progress.py index 3b9fa05a..8c0fe7d2 100644 --- a/lms/lms/doctype/lms_course_progress/lms_course_progress.py +++ b/lms/lms/doctype/lms_course_progress/lms_course_progress.py @@ -4,20 +4,9 @@ import frappe from frappe.model.document import Document -from lms.lms.doctype.lms_enrollment.lms_enrollment import update_program_progress -from lms.lms.utils import get_course_progress +from lms.lms.utils import recalculate_course_progress class LMSCourseProgress(Document): def after_delete(self): - progress = get_course_progress(self.course, self.member) - membership = frappe.db.get_value( - "LMS Enrollment", - { - "member": self.member, - "course": self.course, - }, - "name", - ) - frappe.db.set_value("LMS Enrollment", membership, "progress", progress) - update_program_progress(self.member) + recalculate_course_progress(self.course, self.member) diff --git a/lms/lms/utils.py b/lms/lms/utils.py index d617b7f2..9e3afc8e 100644 --- a/lms/lms/utils.py +++ b/lms/lms/utils.py @@ -28,6 +28,7 @@ from frappe.utils import ( from pypika import Case from pypika import functions as fn +from lms.lms.doctype.lms_enrollment.lms_enrollment import update_program_progress from lms.lms.md import find_macros RE_SLUG_NOTALLOWED = re.compile("[^a-z0-9]+") @@ -2312,3 +2313,17 @@ def has_lms_role(): lms_roles = set(LMS_ROLES) user_roles = set(roles) return not lms_roles.isdisjoint(user_roles) + + +def recalculate_course_progress(course: str, member: str): + progress = get_course_progress(course, member) + membership = frappe.db.get_value( + "LMS Enrollment", + { + "member": member, + "course": course, + }, + "name", + ) + frappe.db.set_value("LMS Enrollment", membership, "progress", progress) + update_program_progress(member)