diff --git a/lms/lms/doctype/lms_certificate/test_lms_certificate.py b/lms/lms/doctype/lms_certificate/test_lms_certificate.py index 81cf129b..04842eb9 100644 --- a/lms/lms/doctype/lms_certificate/test_lms_certificate.py +++ b/lms/lms/doctype/lms_certificate/test_lms_certificate.py @@ -3,35 +3,6 @@ import unittest -import frappe -from frappe.utils import cint, nowdate - -from lms.lms.doctype.lms_certificate.lms_certificate import create_certificate -from lms.lms.doctype.lms_course.test_lms_course import new_course - class TestLMSCertificate(unittest.TestCase): - def test_certificate_creation(self): - course = new_course( - "Test Certificate", - { - "enable_certification": 1, - }, - ) - create_enrollment(course.name) - certificate = create_certificate(course.name) - - self.assertEqual(certificate.member, "Administrator") - self.assertEqual(certificate.course, course.name) - self.assertEqual(certificate.issue_date, nowdate()) - - frappe.db.delete("LMS Certificate", certificate.name) - frappe.db.delete("LMS Course", course.name) - - -def create_enrollment(course): - enrollment = frappe.new_doc("LMS Enrollment") - enrollment.course = course - enrollment.member = frappe.session.user - enrollment.progress = cint(100) - enrollment.save() + pass diff --git a/lms/lms/doctype/lms_course/test_lms_course.py b/lms/lms/doctype/lms_course/test_lms_course.py index 72d7dadc..936fb0e9 100644 --- a/lms/lms/doctype/lms_course/test_lms_course.py +++ b/lms/lms/doctype/lms_course/test_lms_course.py @@ -19,9 +19,6 @@ class TestLMSCourse(unittest.TestCase): if frappe.db.exists("LMS Course", "test-course"): frappe.db.delete("Batch Course", {"course": "test-course"}) - frappe.db.delete("Exercise Submission", {"course": "test-course"}) - frappe.db.delete("Exercise Latest Submission", {"course": "test-course"}) - frappe.db.delete("LMS Exercise", {"course": "test-course"}) frappe.db.delete("LMS Enrollment", {"course": "test-course"}) frappe.db.delete("Course Lesson", {"course": "test-course"}) frappe.db.delete("Course Chapter", {"course": "test-course"}) @@ -67,6 +64,7 @@ def new_course(title, additional_filters=None): "video_link": "https://youtu.be/pEbIhUySqbk", "image": "/assets/lms/images/course-home.png", "instructors": [{"instructor": user}], + "published": 1, } if additional_filters: diff --git a/lms/lms/doctype/lms_enrollment/lms_enrollment.json b/lms/lms/doctype/lms_enrollment/lms_enrollment.json index 887724f2..a3863f33 100644 --- a/lms/lms/doctype/lms_enrollment/lms_enrollment.json +++ b/lms/lms/doctype/lms_enrollment/lms_enrollment.json @@ -21,7 +21,6 @@ "section_break_8", "cohort", "subgroup", - "batch_old", "column_break_12", "member_type", "role" @@ -149,7 +148,7 @@ "grid_page_length": 50, "index_web_pages_for_search": 1, "links": [], - "modified": "2025-12-08 21:27:30.733482", + "modified": "2025-12-09 21:27:30.733482", "modified_by": "Administrator", "module": "LMS", "name": "LMS Enrollment", diff --git a/lms/lms/doctype/lms_enrollment/lms_enrollment.py b/lms/lms/doctype/lms_enrollment/lms_enrollment.py index fbf6994f..e896edcc 100644 --- a/lms/lms/doctype/lms_enrollment/lms_enrollment.py +++ b/lms/lms/doctype/lms_enrollment/lms_enrollment.py @@ -9,28 +9,43 @@ from frappe.utils import ceil class LMSEnrollment(Document): def validate(self): - self.validate_membership_in_same_batch() + self.validate_course_enrollment_eligibility() def on_update(self): update_program_progress(self.member) - def validate_membership_in_same_batch(self): - filters = {"member": self.member, "course": self.course, "name": ["!=", self.name]} - if self.batch_old: - filters["batch_old"] = self.batch_old - previous_membership = frappe.db.get_value( - "LMS Enrollment", filters, fieldname=["member_type", "member"], as_dict=1 + def validate_course_enrollment_eligibility(self): + course_details = frappe.db.get_value( + "LMS Course", + self.course, + ["published", "disable_self_learning", "paid_course", "paid_certificate"], + as_dict=True, ) - if previous_membership: - member_name = frappe.db.get_value("User", self.member, "full_name") - course_title = frappe.db.get_value("LMS Course", self.course, "title") + if course_details.disable_self_learning: frappe.throw( - _("{0} is already a {1} of the course {2}").format( - member_name, previous_membership.member_type, course_title + _( + "You cannot enroll in this course as self-learning is disabled. Please contact the Administrator." ) ) + if not course_details.published: + frappe.throw(_("You cannot enroll in an unpublished course.")) + + if course_details.paid_course: + payment = frappe.db.exists( + "LMS Payment", + { + "reference_doctype": "LMS Course", + "reference_docname": course, + "member": member, + "payment_receipt": True, + }, + ) + + if not payment: + frappe.throw(_("You need to complete the payment for this course before enrolling.")) + def update_program_progress(member): programs = frappe.get_all("LMS Program Member", {"member": member}, ["parent", "name"]) @@ -49,8 +64,6 @@ def update_program_progress(member): @frappe.whitelist() def create_membership(course, batch=None, member=None, member_type="Student", role="Member"): - validate_course_enrollment_eligibility(course, member) - enrollment = frappe.new_doc("LMS Enrollment") enrollment.update( { @@ -66,42 +79,6 @@ def create_membership(course, batch=None, member=None, member_type="Student", ro return enrollment -def validate_course_enrollment_eligibility(course, member): - if not member: - member = frappe.session.user - - course_details = frappe.db.get_value( - "LMS Course", - course, - ["published", "disable_self_learning", "paid_course", "paid_certificate"], - as_dict=True, - ) - - if course_details.disable_self_learning: - frappe.throw( - _( - "You cannot enroll in this course as self-learning is disabled. Please contact the Administrator." - ) - ) - - if not course_details.published: - frappe.throw(_("You cannot enroll in an unpublished course.")) - - if course_details.paid_course: - payment = frappe.db.exists( - "LMS Payment", - { - "reference_doctype": "LMS Course", - "reference_docname": course, - "member": member, - "payment_receipt": True, - }, - ) - - if not payment: - frappe.throw(_("You need to complete the payment for this course before enrolling.")) - - @frappe.whitelist() def update_current_membership(batch, course, member): all_memberships = frappe.get_all("LMS Enrollment", {"member": member, "course": course}) diff --git a/lms/lms/doctype/lms_enrollment/test_lms_enrollment.py b/lms/lms/doctype/lms_enrollment/test_lms_enrollment.py index 22e7fb4c..acee732c 100644 --- a/lms/lms/doctype/lms_enrollment/test_lms_enrollment.py +++ b/lms/lms/doctype/lms_enrollment/test_lms_enrollment.py @@ -5,19 +5,6 @@ import unittest import frappe -from lms.lms.doctype.lms_course.test_lms_course import new_course, new_user - class TestLMSEnrollment(unittest.TestCase): - def test_membership(self): - course = new_course("Test Enrollment") - enrollment = frappe.new_doc("LMS Enrollment") - enrollment.course = course.name - enrollment.member = frappe.session.user - - enrollment.save() - - self.assertEqual(enrollment.course, course.name) - self.assertEqual(enrollment.member, "Administrator") - frappe.db.delete("LMS Enrollment", enrollment.name) - frappe.db.delete("LMS Course", course.name) + pass diff --git a/lms/lms/test_utils.py b/lms/lms/test_utils.py index ecec9f3e..344667f4 100644 --- a/lms/lms/test_utils.py +++ b/lms/lms/test_utils.py @@ -6,6 +6,7 @@ from .utils import ( get_average_rating, get_chapters, get_instructors, + get_lesson_index, get_lessons, get_membership, get_reviews, @@ -16,13 +17,14 @@ from .utils import ( class TestUtils(unittest.TestCase): def setUp(self): + self.student1 = self.create_user("student1@example.com", "Ashley", "Smith", "LMS Student") + self.student2 = self.create_user("student2@example.com", "John", "Doe", "LMS Student") + self.admin = self.create_user("frappe@example.com", "Frappe", "Admin", "Moderator") + self.create_a_course() self.add_chapters() self.add_lessons() - self.student1 = self.create_student("student1@example.com", "Ashley", "Smith") - self.student2 = self.create_student("student2@example.com", "John", "Doe") - self.add_enrollment(self.course.name, self.student1.email) self.add_enrollment(self.course.name, self.student2.email) @@ -73,15 +75,18 @@ class TestUtils(unittest.TestCase): chapterDoc.append("lessons", {"lesson": lesson.name}) chapterDoc.save() - def create_student(self, email, first_name, last_name): - student = frappe.new_doc("User") - student.email = email - student.first_name = first_name - student.last_name = last_name - student.user_type = "Website User" - student.append("roles", {"role": "LMS Student"}) - student.save() - return student + def create_user(self, email, first_name, last_name, role): + if not frappe.db.exists("User", email): + student = frappe.new_doc("User") + student.email = email + student.first_name = first_name + student.last_name = last_name + student.user_type = "Website User" + student.append("roles", {"role": role}) + student.save() + return student + else: + return frappe.get_doc("User", email) def test_simple_slugs(self): self.assertEqual(slugify("hello-world"), "hello-world") @@ -121,7 +126,7 @@ class TestUtils(unittest.TestCase): self.assertEqual(len(chapter_lessons), 2) for j, lesson in enumerate(chapter_lessons, start=1): self.assertEqual(lesson.title, f"Lesson {j} of {chapter.chapter}") - self.assertEqual(lesson.number, f"{chapter.idx}.{j}") + self.assertEqual(lesson.number, f"{chapter.idx}-{j}") def test_get_tags(self): tags = get_tags(self.course.name) @@ -158,6 +163,11 @@ class TestUtils(unittest.TestCase): self.assertEqual(review.member, self.student2.email) self.assertEqual(review.review, "Excellent course") + def test_get_lesson_index(self): + lessons = get_lessons(self.course.name) + for lesson in lessons: + self.assertEqual(get_lesson_index(lesson.name), lesson.number) + def tearDown(self): if frappe.db.exists("LMS Course", self.course.name): frappe.db.delete("LMS Enrollment", {"course": self.course.name}) @@ -168,3 +178,4 @@ class TestUtils(unittest.TestCase): frappe.delete_doc("User", "student1@example.com") frappe.delete_doc("User", "student2@example.com") + frappe.delete_doc("User", "frappe@example.com") diff --git a/lms/lms/utils.py b/lms/lms/utils.py index 7ccd44af..ba4d75f5 100644 --- a/lms/lms/utils.py +++ b/lms/lms/utils.py @@ -154,7 +154,7 @@ def get_lesson_details(chapter, progress=False): ], as_dict=True, ) - lesson_details.number = f"{chapter.idx}.{row.idx}" + lesson_details.number = f"{chapter.idx}-{row.idx}" lesson_details.icon = get_lesson_icon(lesson_details.body, lesson_details.content) if progress: @@ -259,22 +259,6 @@ def get_reviews(course): return reviews -def get_sorted_reviews(course): - rating_count = rating_percent = frappe._dict() - keys = ["5.0", "4.0", "3.0", "2.0", "1.0"] - for key in keys: - rating_count[key] = 0 - - reviews = get_reviews(course) - for review in reviews: - rating_count[cstr(review.rating)] += 1 - - for key in keys: - rating_percent[key] = rating_count[key] / len(reviews) * 100 - - return rating_percent - - def get_lesson_index(lesson_name): """Returns the {chapter_index}.{lesson_index} for the lesson.""" lesson = frappe.db.get_value("Lesson Reference", {"lesson": lesson_name}, ["idx", "parent"], as_dict=True) diff --git a/lms/templates/reviews.html b/lms/templates/reviews.html deleted file mode 100644 index e6c1a6be..00000000 --- a/lms/templates/reviews.html +++ /dev/null @@ -1,167 +0,0 @@ -{% if not course.upcoming %} -