From 93f019a0d03c09eb075a843e03e13f9ee41e98ca Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Mon, 2 Mar 2026 18:02:25 +0530 Subject: [PATCH 01/57] feat: demo data --- lms/demo/demo_data.py | 357 ++++++++++++++++++++++++++++++++++++++++++ lms/install.py | 3 +- 2 files changed, 359 insertions(+), 1 deletion(-) create mode 100644 lms/demo/demo_data.py diff --git a/lms/demo/demo_data.py b/lms/demo/demo_data.py new file mode 100644 index 00000000..829b3caa --- /dev/null +++ b/lms/demo/demo_data.py @@ -0,0 +1,357 @@ +import json + +import frappe + + +def create_demo_data(): + course = create_course() + create_chapter(course) + create_lessons(course) + + +def create_course(): + title = "A guide to Frappe Learning" + filters = {"title": title} + if frappe.db.exists("LMS Course", filters): + return frappe.get_doc("LMS Course", filters) + + instructor = create_instructor() + course = frappe.new_doc("LMS Course") + course.update( + { + "title": title, + "category": "Business", + "tags": "Frappe, Demo", + "published": 1, + "published_on": frappe.utils.now(), + "video_link": "VIt_bsbBjLI", + "instructors": [{"instructor": instructor.name}], + "short_introduction": "Learn the basics of Frappe Learning and how to get started.", + } + ) + + course.description = """ + This course will cover the fundamentals of Frappe Learning, including how to create and manage courses, enroll students, and track progress. + + You will learn about the following key features of the app: + +

Key Features

+ + 1. Structured Learning + Design a course with a 3-level hierarchy, where your courses have chapters and you can group your lessons within these chapters. This ensures that the context of each lesson is clearly defined by its chapter. + + 2. Live Classes + Group learners into batches based on courses and duration. You can then create Zoom live classes for these batches directly from the app. Learners can view all the live classes they need to attend as part of their batch. + + 3. Quizzes and Assignments + Create quizzes with single-choice, multiple-choice, or open-ended questions. Instructors can also add assignments that learners can submit as PDFs or documents. + + 4. Getting Certified + Once a learner completes the course or batch, you can grant them a certificate. The app provides an inbuilt certificate template that you can use as-is or customize by creating your own template. + + To know more about the app and its features, check out the documentation: https://docs.frappe.io/learning + + """ + course.save() + return course + + +def create_instructor(): + filters = {"first_name": "Jannat", "last_name": "Patel", "email": "jannat@example.com"} + if frappe.db.exists("User", filters): + return frappe.get_doc("User", filters) + + instructor = frappe.new_doc("User") + instructor.first_name = "Jannat" + instructor.last_name = "Patel" + instructor.email = "jannat@example.com" + instructor.save() + return instructor + + +def create_chapter(course): + prepare_chapter(course, "Introduction") + prepare_chapter(course, "Adding content to your lessons") + + +def prepare_chapter(course, chapter_title): + chapter_exists = check_if_chapter_exists(course, chapter_title) + if chapter_exists: + return frappe.get_doc("Course Chapter", chapter_exists) + + chapter1 = frappe.new_doc("Course Chapter") + chapter1.course = course.name + chapter1.title = chapter_title + chapter1.save() + add_chapter_to_course(course, chapter1) + + +def check_if_chapter_exists(course, chapter_title): + filters = {"course": course.name, "title": chapter_title} + return frappe.db.exists("Course Chapter", filters) + + +def add_chapter_to_course(course, chapter): + course.reload() + course.append("chapters", {"chapter": chapter.name}) + course.save() + + +def create_lessons(course): + create_intro_lesson_1(course) + create_intro_lesson_2(course) + create_content_lesson_1(course) + create_content_lesson_2(course) + + +def get_chapter(course, chapter_title): + filters = {"course": course.name, "title": chapter_title} + return frappe.get_doc("Course Chapter", filters) + + +def create_lesson(course, chapter, title, content): + filters = {"course": course.name, "chapter": chapter.name, "title": title} + + if frappe.db.exists("Course Lesson", filters): + return frappe.get_doc("Course Lesson", filters) + + lesson = frappe.new_doc("Course Lesson") + lesson.course = course.name + lesson.chapter = chapter.name + lesson.title = title + lesson.content = content + lesson.save() + add_lesson_to_chapter(chapter, lesson) + + +def add_lesson_to_chapter(chapter, lesson): + chapter.reload() + chapter.append("lessons", {"lesson": lesson.name}) + chapter.save() + + +def create_intro_lesson_1(course): + title = "What is a Learning Management System?" + chapter = get_chapter(course, "Introduction") + content = """ + {"time":1772449622100,"blocks":[{"id":"vYTdcXYVgI","type":"embed","data":{"service":"youtube","source":"http://youtube.com/watch?v=SauviPVDItU","embed":"SauviPVDItU","caption":""}}],"version":"2.29.0"} + """ + create_lesson(course, chapter, title, content) + + +def create_intro_lesson_2(course): + title = "What is Frappe Learning?" + chapter = get_chapter(course, "Introduction") + content = """ + {"time":1772449622100,"blocks":[{"id":"vYTdcXYVgI","type":"embed","data":{"service":"youtube","source":"http://youtube.com/watch?v=SauviPVDItU","embed":"SauviPVDItU","caption":""}}],"version":"2.29.0"} + """ + create_lesson(course, chapter, title, content) + + +def create_content_lesson_1(course): + title = "Video Content" + chapter = get_chapter(course, "Adding content to your lessons") + content = json.dumps(get_video_content()) + create_lesson(course, chapter, title, content) + + +def create_content_lesson_2(course): + title = "Content from Google Suite" + chapter = get_chapter(course, "Adding content to your lessons") + content = json.dumps(get_google_suite_content()) + create_lesson(course, chapter, title, content) + + +def get_video_content(): + return { + "time": 1772450228627, + "blocks": [ + { + "id": "bj6mK0D36z", + "type": "paragraph", + "data": { + "text": "Frappe Learning allows you to embed videos in lessons using popular video hosting platforms." + }, + }, + { + "id": "1ooWPn5Zmq", + "type": "paragraph", + "data": { + "text": "You don't need to upload videos directly into Frappe Learning - simply copy the video URL from your preferred provider and paste it into the Lesson Editor." + }, + }, + { + "id": "tCJD0yMAGd", + "type": "paragraph", + "data": { + "text": "Frappe Learning automatically detects the video source and embeds it for learners." + }, + }, + {"id": "KpfuszbA09", "type": "markdown", "data": {"text": ""}}, + {"id": "PZYmdlzQj2", "type": "header", "data": {"text": "YouTube", "level": 2}}, + { + "id": "mJsIbQSHYO", + "type": "paragraph", + "data": {"text": "YouTube videos can be embedded using the standard watch URL."}, + }, + {"id": "-H8fLBsAMk", "type": "paragraph", "data": {"text": "Supported URL format"}}, + { + "id": "Aiq-BfQkwZ", + "type": "paragraph", + "data": { + "text": 'https://www.youtube.com/watch?v=<video-id>' + }, + }, + {"id": "8hMi323AbM", "type": "paragraph", "data": {"text": "Example"}}, + { + "id": "3H6BzIshWg", + "type": "paragraph", + "data": { + "text": 'https://www.youtube.com/watch?v=SLNSSz41v_o' + }, + }, + {"id": "yGSuw7Im0i", "type": "markdown", "data": {"text": ""}}, + {"id": "WRVOABPAZO", "type": "header", "data": {"text": "Vimeo", "level": 2}}, + { + "id": "AabHQjaQvo", + "type": "paragraph", + "data": {"text": "Vimeo videos are supported using the video URL."}, + }, + {"id": "q_9aNfNHEP", "type": "paragraph", "data": {"text": "Supported URL format"}}, + { + "id": "1YYctmoyod", + "type": "paragraph", + "data": {"text": 'https://vimeo.com/<video-id>'}, + }, + {"id": "OX_NGBxJTY", "type": "paragraph", "data": {"text": "Example"}}, + { + "id": "KZYnrs_Dnf", + "type": "paragraph", + "data": {"text": 'https://vimeo.com/825334862'}, + }, + {"id": "-mkC711EdF", "type": "markdown", "data": {"text": ""}}, + {"id": "nSzyGY6f68", "type": "header", "data": {"text": "Cloudflare Stream", "level": 2}}, + { + "id": "-cpNtfvP5T", + "type": "paragraph", + "data": {"text": "Cloudflare Stream provides secure video hosting with adaptive streaming."}, + }, + {"id": "e2fQ-DG6Nd", "type": "paragraph", "data": {"text": "Supported URL format"}}, + { + "id": "av_Q4P66hb", + "type": "paragraph", + "data": { + "text": 'https://customer-<account-id>.cloudflarestream.com/<video-id>/watch' + }, + }, + {"id": "8KCsx40NpJ", "type": "paragraph", "data": {"text": "Example"}}, + { + "id": "USi0pW91df", + "type": "paragraph", + "data": { + "text": 'https://customer-f33zs165nr7gyfy4.cloudflarestream.com/6b9e68b07dfee8cc2d116e4c51d6a957/watch' + }, + }, + {"id": "e6I0VuwXx9", "type": "markdown", "data": {"text": ""}}, + {"id": "C-u44GnaTz", "type": "header", "data": {"text": "Bunny Stream", "level": 2}}, + { + "id": "uR8XZtPVC5", + "type": "paragraph", + "data": {"text": "Bunny Stream allows fast, global video delivery with built-in analytics."}, + }, + {"id": "BYkm4Hy_v8", "type": "paragraph", "data": {"text": "Supported URL format"}}, + { + "id": "TCM9COabp8", + "type": "paragraph", + "data": { + "text": 'https://iframe.mediadelivery.net/play/<library-id>/<video-id>' + }, + }, + {"id": "KCiA6zVRYf", "type": "paragraph", "data": {"text": "Example"}}, + { + "id": "kYDFL8Dn1v", + "type": "paragraph", + "data": { + "text": 'https://iframe.mediadelivery.net/play/579970/54b3e5a1-cf95-4f88-96d3-8387d93dc2f2' + }, + }, + {"id": "jfnSgNAv5Q", "type": "markdown", "data": {"text": ""}}, + {"id": "NCY3opj8uc", "type": "header", "data": {"text": "Important Notes", "level": 2}}, + { + "id": "xHWE56ECqw", + "type": "paragraph", + "data": {"text": "Paste only the video URL, not iframe embed code"}, + }, + { + "id": "ZzrV99rSxJ", + "type": "paragraph", + "data": {"text": "The URL must match one of the supported formats above"}, + }, + { + "id": "jjg_inGE2B", + "type": "paragraph", + "data": { + "text": "Video privacy, access control, and streaming limits are managed by the video provider" + }, + }, + ], + "version": "2.29.0", + } + + +def get_google_suite_content(): + return { + "time": 1772450743148, + "blocks": [ + { + "id": "73fFo3DS18", + "type": "paragraph", + "data": { + "text": "You can integrate live Google Docs, Sheets, and Slides into your lessons to provide dynamic, up-to-date documentation and presentations." + }, + }, + {"id": "Z6I1ZV7Fvr", "type": "markdown", "data": {"text": ""}}, + { + "id": "hiJVoYEhfN", + "type": "header", + "data": {"text": "How to Embed Google Workspace Files", "level": 3}, + }, + { + "id": "v9_hXM3d8b", + "type": "list", + "data": { + "style": "ordered", + "items": [ + {"content": "Open your Google Doc, Sheet, or Slide.", "items": []}, + {"content": "Make sure your permissions are set properly", "items": []}, + {"content": "Copy your URL from the top browser address bar", "items": []}, + {"content": "Now paste it in your lesson", "items": []}, + ], + }, + }, + {"id": "ycS1sd-0us", "type": "markdown", "data": {"text": ""}}, + {"id": "NjN6_ixXRW", "type": "header", "data": {"text": "Integration Options", "level": 3}}, + { + "id": "MgXDT0xV4X", + "type": "list", + "data": { + "style": "unordered", + "items": [ + { + "content": "Google Slides: Perfect for presentations. These render with full navigation controls for the student.", + "items": [], + }, + { + "content": "Google Sheets: Useful for sharing live data tables or interactive calculators.", + "items": [], + }, + { + "content": "Google Docs: Best for course handouts, reading material, or live-updating documentation.", + "items": [], + }, + ], + }, + }, + ], + "version": "2.29.0", + } diff --git a/lms/install.py b/lms/install.py index 9862f0dd..683d087d 100644 --- a/lms/install.py +++ b/lms/install.py @@ -1,6 +1,6 @@ import frappe -from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to +from lms.demo.demo_data import create_demo_data from lms.lms.api import give_discussions_permission @@ -14,6 +14,7 @@ def after_sync(): create_lms_roles() set_default_certificate_print_format() give_lms_roles_to_admin() + create_demo_data() def before_uninstall(): From 2a2e937876c485fbbbbe5589d88cdcc48147e257 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Tue, 3 Mar 2026 12:46:40 +0530 Subject: [PATCH 02/57] feat: added course card image for demo course --- frontend/src/pages/Lesson.vue | 5 ++ lms/demo/demo_data.py | 2 + lms/public/images/course_card.jpeg | Bin 0 -> 122408 bytes lms/public/images/instructor.png | Bin 0 -> 5933 bytes lms/workspace_sidebar/lms.json | 116 ----------------------------- 5 files changed, 7 insertions(+), 116 deletions(-) create mode 100644 lms/public/images/course_card.jpeg create mode 100644 lms/public/images/instructor.png delete mode 100644 lms/workspace_sidebar/lms.json diff --git a/frontend/src/pages/Lesson.vue b/frontend/src/pages/Lesson.vue index 81aadeb7..02e24b94 100644 --- a/frontend/src/pages/Lesson.vue +++ b/frontend/src/pages/Lesson.vue @@ -627,6 +627,7 @@ const resetLessonState = (newChapterNumber, newLessonNumber) => { chapter: newChapterNumber, lesson: newLessonNumber, }) + console.log('resetting lesson state') clearInterval(timerInterval) timer.value = 0 } @@ -741,14 +742,18 @@ const updateVideoTime = (video) => { } const startTimer = () => { + console.log(lesson.data?.membership) if (!lesson.data?.membership) return + console.log('past') timerInterval = setInterval(() => { + console.log(`Timer: ${timer.value} seconds`) timer.value++ if (timer.value == 30) { clearInterval(timerInterval) markProgress() } }, 1000) + console.log(timerInterval) } onBeforeUnmount(() => { diff --git a/lms/demo/demo_data.py b/lms/demo/demo_data.py index 829b3caa..9f287e53 100644 --- a/lms/demo/demo_data.py +++ b/lms/demo/demo_data.py @@ -27,6 +27,7 @@ def create_course(): "video_link": "VIt_bsbBjLI", "instructors": [{"instructor": instructor.name}], "short_introduction": "Learn the basics of Frappe Learning and how to get started.", + "image": "/assets/lms/images/course_card.jpeg", } ) @@ -64,6 +65,7 @@ def create_instructor(): instructor = frappe.new_doc("User") instructor.first_name = "Jannat" instructor.last_name = "Patel" + instructor.user_image = "/assets/lms/images/instructor.png" instructor.email = "jannat@example.com" instructor.save() return instructor diff --git a/lms/public/images/course_card.jpeg b/lms/public/images/course_card.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..0d1f41bfc64f43758d4ab645dd7e17707db4f92e GIT binary patch literal 122408 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 G&VK^26Y)#{ literal 0 HcmV?d00001 diff --git a/lms/public/images/instructor.png b/lms/public/images/instructor.png new file mode 100644 index 0000000000000000000000000000000000000000..df171a39853085e08b72a9b7d82dc4a156278e5d GIT binary patch literal 5933 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 Date: Thu, 5 Mar 2026 02:03:24 +0530 Subject: [PATCH 03/57] fix: add get_field_meta function to get doctype field metadata --- lms/lms/api.py | 50 +++++++++++++++++++++++++++++++++++++++++++++++- lms/lms/utils.py | 17 ++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/lms/lms/api.py b/lms/lms/api.py index 5140bf60..bf973d9a 100644 --- a/lms/lms/api.py +++ b/lms/lms/api.py @@ -37,6 +37,7 @@ from lms.lms.utils import ( get_average_rating, get_batch_details, get_course_details, + get_field_meta, get_instructors, get_lesson_count, get_lms_route, @@ -103,7 +104,54 @@ def validate_billing_access(billing_type: str, name: str): as_dict=1, ) - return {"access": access, "message": message, "address": address} + payment_fields = get_payment_field_meta() + address_fields = get_field_meta( + "Address", + [ + "address_line1", + "address_line2", + "city", + "state", + "country", + "pincode", + "phone", + ], + ) + billing_field_meta = {**payment_fields, **address_fields} + + return { + "access": access, + "message": message, + "address": address, + "billing_field_meta": billing_field_meta, + } + + +@frappe.whitelist() +def get_payment_field_meta(): + return get_field_meta( + "LMS Payment", + [ + "member", + "billing_name", + "source", + "payment_for_document_type", + "payment_for_document", + "currency", + "amount", + "amount_with_gst", + "original_amount", + "discount_amount", + "coupon", + "coupon_code", + "address", + "gstin", + "pan", + "payment_id", + "order_id", + "member_consent", + ], + ) def verify_billing_access(doctype, name, billing_type): diff --git a/lms/lms/utils.py b/lms/lms/utils.py index 513512ba..7788b0ff 100644 --- a/lms/lms/utils.py +++ b/lms/lms/utils.py @@ -2328,3 +2328,20 @@ def recalculate_course_progress(course: str, member: str): ) frappe.db.set_value("LMS Enrollment", membership, "progress", progress) update_program_progress(member) + + +def get_field_meta(doctype, fieldnames): + """Returns field metadata for 'fieldnames' from 'doctype'""" + meta = frappe.get_meta(doctype) + fieldnames_meta = {} + + for fieldname in fieldnames: + field = meta.get_field(fieldname) + if field: + fieldnames_meta[fieldname] = { + "reqd": field.reqd, + "default": field.default, + "description": field.description, + } + + return fieldnames_meta From a893c405d14bdd7d3609ecf9c38c8d1ca090641a Mon Sep 17 00:00:00 2001 From: raizasafeel <89463672+raizasafeel@users.noreply.github.com> Date: Thu, 5 Mar 2026 02:05:00 +0530 Subject: [PATCH 04/57] fix: replace hardcoded meta fields with validation from backend --- .../Transactions/TransactionDetails.vue | 79 ++++++++++++------- .../Settings/Transactions/Transactions.vue | 9 ++- frontend/src/pages/Billing.vue | 56 ++++++++----- 3 files changed, 95 insertions(+), 49 deletions(-) diff --git a/frontend/src/components/Settings/Transactions/TransactionDetails.vue b/frontend/src/components/Settings/Transactions/TransactionDetails.vue index efd2cc88..5ad0ebba 100644 --- a/frontend/src/components/Settings/Transactions/TransactionDetails.vue +++ b/frontend/src/components/Settings/Transactions/TransactionDetails.vue @@ -55,17 +55,18 @@ :label="__('Member')" doctype="User" v-model="transactionData.member" - :required="true" + :required="!!fieldMeta.member?.reqd" /> @@ -90,17 +93,18 @@ :label="__('Currency')" v-model="transactionData.currency" doctype="Currency" - :required="true" + :required="!!fieldMeta.currency?.reqd" /> @@ -113,21 +117,25 @@ v-if="transactionData.coupon" :label="__('Coupon Code')" v-model="transactionData.coupon" + :required="!!fieldMeta.coupon?.reqd" /> @@ -140,17 +148,27 @@ :label="__('Address')" v-model="transactionData.address" doctype="Address" - :required="true" + :required="!!fieldMeta.address?.reqd" + /> + + - - @@ -171,6 +189,10 @@ const show = defineModel('show') const props = defineProps<{ transactions: any data: any + fieldMeta: Record< + string, + { reqd?: number; default?: string; description?: string } + > }>() const saveTransaction = () => { @@ -226,33 +248,36 @@ const openDetails = () => { } } -const emptyTransactionData = { +const getDefault = (fieldname: string) => + props.fieldMeta[fieldname]?.default || null + +const getEmptyTransactionData = () => ({ payment_received: false, payment_for_certificate: false, - member: null, - billing_name: null, - source: null, - payment_for_document_type: null, - payment_for_document: null, + member: getDefault('member'), + billing_name: getDefault('billing_name'), + source: getDefault('source'), + payment_for_document_type: getDefault('payment_for_document_type'), + payment_for_document: getDefault('payment_for_document'), member_consent: false, - currency: null, - amount: null, - amount_with_gst: null, - coupon: null, - coupon_code: null, - discount_amount: null, - original_amount: null, - order_id: null, - payment_id: null, - gstin: null, - pan: null, - address: null, -} + currency: getDefault('currency'), + amount: getDefault('amount'), + amount_with_gst: getDefault('amount_with_gst'), + coupon: getDefault('coupon'), + coupon_code: getDefault('coupon_code'), + discount_amount: getDefault('discount_amount'), + original_amount: getDefault('original_amount'), + order_id: getDefault('order_id'), + payment_id: getDefault('payment_id'), + gstin: getDefault('gstin'), + pan: getDefault('pan'), + address: getDefault('address'), +}) watch( () => props.data, (newVal) => { - transactionData.value = newVal ? { ...newVal } : emptyTransactionData + transactionData.value = newVal ? { ...newVal } : getEmptyTransactionData() }, { immediate: true } ) diff --git a/frontend/src/components/Settings/Transactions/Transactions.vue b/frontend/src/components/Settings/Transactions/Transactions.vue index d2045b8a..eeb0d2a5 100644 --- a/frontend/src/components/Settings/Transactions/Transactions.vue +++ b/frontend/src/components/Settings/Transactions/Transactions.vue @@ -3,6 +3,7 @@ v-if="step == 'new'" :transactions="transactions" :data="data" + :fieldMeta="fieldMeta.data || {}" v-model:show="show" @updateStep="updateStep" /> @@ -17,13 +18,14 @@ v-else-if="step == 'details'" :transactions="transactions" :data="data" + :fieldMeta="fieldMeta.data || {}" v-model:show="show" @updateStep="updateStep" /> diff --git a/frontend/src/pages/Batches/BatchDetail.vue b/frontend/src/pages/Batches/BatchDetail.vue index 6803f5ca..c90f80da 100644 --- a/frontend/src/pages/Batches/BatchDetail.vue +++ b/frontend/src/pages/Batches/BatchDetail.vue @@ -18,7 +18,7 @@ { } const batchMenu = computed(() => { + if (!batch.data?.certification && !canMakeAnnouncement()) { + return [] + } let options = [ { label: __('Generate Certificates'), diff --git a/frontend/src/pages/Batches/components/BatchOverlay.vue b/frontend/src/pages/Batches/components/BatchOverlay.vue index d7b88e00..f034f3f3 100644 --- a/frontend/src/pages/Batches/components/BatchOverlay.vue +++ b/frontend/src/pages/Batches/components/BatchOverlay.vue @@ -56,7 +56,7 @@ -
+
-