From 66e8ac9cae4009e3f67c3e56cefa336f8126d031 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Wed, 20 Oct 2021 12:05:13 +0530 Subject: [PATCH 01/10] fix: get progress from membership --- .../doctype/course_lesson/course_lesson.py | 16 +++++++++----- .../lms_batch_membership.json | 18 ++++++++++----- .../lms/doctype/lms_course/lms_course.py | 2 +- .../course_progress_summary.py | 15 +++++-------- community/lms/widgets/CourseCard.html | 2 +- community/overrides/user.py | 7 +++--- community/patches.txt | 1 + .../v0_0/add_progress_to_membership.py | 22 +++++++++++++++++++ community/www/batch/learn.html | 2 +- community/www/courses/course.html | 2 +- 10 files changed, 58 insertions(+), 29 deletions(-) create mode 100644 community/patches/v0_0/add_progress_to_membership.py diff --git a/community/lms/doctype/course_lesson/course_lesson.py b/community/lms/doctype/course_lesson/course_lesson.py index 25427c87..d2251669 100644 --- a/community/lms/doctype/course_lesson/course_lesson.py +++ b/community/lms/doctype/course_lesson/course_lesson.py @@ -65,11 +65,12 @@ class CourseLesson(Document): @frappe.whitelist() def save_progress(lesson, course, status): - if not frappe.db.exists("LMS Batch Membership", - { - "member": frappe.session.user, - "course": course - }): + membership = frappe.db.exists("LMS Batch Membership", + { + "member": frappe.session.user, + "course": course + }) + if not membership: return if frappe.db.exists("LMS Course Progress", @@ -92,5 +93,8 @@ def save_progress(lesson, course, status): "lesson": lesson, "status": status, }).save(ignore_permissions=True) + course_details = frappe.get_doc("LMS Course", course) - return course_details.get_course_progress() + progress = course_details.get_course_progress() + frappe.db.set_value("LMS Batch Memebership", membership, "progress", progress) + return progress diff --git a/community/lms/doctype/lms_batch_membership/lms_batch_membership.json b/community/lms/doctype/lms_batch_membership/lms_batch_membership.json index 7a6a8497..18e660b8 100644 --- a/community/lms/doctype/lms_batch_membership/lms_batch_membership.json +++ b/community/lms/doctype/lms_batch_membership/lms_batch_membership.json @@ -5,15 +5,16 @@ "editable_grid": 1, "engine": "InnoDB", "field_order": [ - "batch", + "course", "member", "member_name", "member_username", "column_break_3", - "course", + "batch", "member_type", - "role", - "current_lesson" + "progress", + "current_lesson", + "role" ], "fields": [ { @@ -80,11 +81,18 @@ "fieldtype": "Data", "label": "Memeber Username", "read_only": 1 + }, + { + "fieldname": "progress", + "fieldtype": "Data", + "label": "Progress", + "read_only": 1 } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-09-29 15:27:58.765399", + "migration_hash": "10fbeeba76887ba1dc94e7ac19ea637d", + "modified": "2021-10-20 10:08:04.071690", "modified_by": "Administrator", "module": "LMS", "name": "LMS Batch Membership", diff --git a/community/lms/doctype/lms_course/lms_course.py b/community/lms/doctype/lms_course/lms_course.py index feebe8f3..3c559211 100644 --- a/community/lms/doctype/lms_course/lms_course.py +++ b/community/lms/doctype/lms_course/lms_course.py @@ -251,7 +251,7 @@ class LMSCourse(Document): membership = frappe.db.get_value("LMS Batch Membership", filters, - ["name", "batch", "current_lesson", "member_type"], + ["name", "batch", "current_lesson", "member_type", "progress"], as_dict=True) if membership and membership.batch: diff --git a/community/lms/report/course_progress_summary/course_progress_summary.py b/community/lms/report/course_progress_summary/course_progress_summary.py index efda989f..a54249e4 100644 --- a/community/lms/report/course_progress_summary/course_progress_summary.py +++ b/community/lms/report/course_progress_summary/course_progress_summary.py @@ -2,7 +2,7 @@ # License: MIT. See LICENSE import frappe -from frappe.utils import rounded +from frappe.utils import cint from frappe import _ def execute(filters=None): @@ -23,21 +23,16 @@ def get_data(filters=None): memberships = frappe.get_all( "LMS Batch Membership", query_filter, - ["name", "course", "member", "member_name"], + ["name", "course", "member", "member_name", "progress"], order_by="course") - current_course = memberships[0].course for membership in memberships: - if current_course != membership.course: - current_course = membership.course - - course_details = frappe.get_doc("LMS Course", current_course) summary.append(frappe._dict({ - "course": course_details.name, - "course_name": course_details.title, + "course": membership.name, + "course_name": frappe.db.get_value("LMS Course", membership.course, "title"), "member": membership.member, "member_name": membership.member_name, - "progress": rounded(course_details.get_course_progress(membership.member)) + "progress": cint(membership.progress) })) return summary diff --git a/community/lms/widgets/CourseCard.html b/community/lms/widgets/CourseCard.html index 38736ab0..b709ce90 100644 --- a/community/lms/widgets/CourseCard.html +++ b/community/lms/widgets/CourseCard.html @@ -1,5 +1,5 @@ {% set membership = course.get_membership(frappe.session.user) %} -{% set progress = course.get_course_progress() %} +{% set progress = membership.progress %}
{% elif course.enable_certification %} -
+
Get Certificate
{% endif %} diff --git a/community/www/courses/course.html b/community/www/courses/course.html index 9bb06343..48448c69 100644 --- a/community/www/courses/course.html +++ b/community/www/courses/course.html @@ -111,7 +111,7 @@
{{ widgets.MemberCard(member=course.get_instructor(), show_course_count=True, dimension_class="member-card-large") }}
- {% set progress = course.get_course_progress() %} + {% set progress = membership.progress %} {% if progress %}
From 049c374ece7583df00f16de07266439e94db8c03 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Wed, 20 Oct 2021 16:12:41 +0530 Subject: [PATCH 02/10] fix: convert progress to int for comparision --- community/lms/doctype/course_lesson/course_lesson.py | 2 +- .../lms_batch_membership/lms_batch_membership.json | 8 ++++---- community/lms/widgets/CourseCard.html | 2 +- community/overrides/user.py | 1 + community/www/courses/course.html | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/community/lms/doctype/course_lesson/course_lesson.py b/community/lms/doctype/course_lesson/course_lesson.py index d2251669..8fbfb0e9 100644 --- a/community/lms/doctype/course_lesson/course_lesson.py +++ b/community/lms/doctype/course_lesson/course_lesson.py @@ -96,5 +96,5 @@ def save_progress(lesson, course, status): course_details = frappe.get_doc("LMS Course", course) progress = course_details.get_course_progress() - frappe.db.set_value("LMS Batch Memebership", membership, "progress", progress) + frappe.db.set_value("LMS Batch Membership", membership, "progress", progress) return progress diff --git a/community/lms/doctype/lms_batch_membership/lms_batch_membership.json b/community/lms/doctype/lms_batch_membership/lms_batch_membership.json index 18e660b8..69720d29 100644 --- a/community/lms/doctype/lms_batch_membership/lms_batch_membership.json +++ b/community/lms/doctype/lms_batch_membership/lms_batch_membership.json @@ -66,6 +66,7 @@ "fieldname": "course", "fieldtype": "Link", "in_list_view": 1, + "in_standard_filter": 1, "label": "Course", "options": "LMS Course" }, @@ -91,8 +92,8 @@ ], "index_web_pages_for_search": 1, "links": [], - "migration_hash": "10fbeeba76887ba1dc94e7ac19ea637d", - "modified": "2021-10-20 10:08:04.071690", + "migration_hash": "fe10c462acf5e727d864305d7ce90e73", + "modified": "2021-10-20 15:10:33.767419", "modified_by": "Administrator", "module": "LMS", "name": "LMS Batch Membership", @@ -113,6 +114,5 @@ ], "quick_entry": 1, "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 + "sort_order": "DESC" } \ No newline at end of file diff --git a/community/lms/widgets/CourseCard.html b/community/lms/widgets/CourseCard.html index b709ce90..33783870 100644 --- a/community/lms/widgets/CourseCard.html +++ b/community/lms/widgets/CourseCard.html @@ -1,5 +1,5 @@ {% set membership = course.get_membership(frappe.session.user) %} -{% set progress = membership.progress %} +{% set progress = frappe.utils.cint(membership.progress) %}
{{ widgets.MemberCard(member=course.get_instructor(), show_course_count=True, dimension_class="member-card-large") }}
- {% set progress = membership.progress %} + {% set progress = frappe.utils.cint(membership.progress) %} {% if progress %}
From 58fe403bd0fe5e45d84c0b022039006dd6042fcc Mon Sep 17 00:00:00 2001 From: Anand Chitipothu Date: Thu, 21 Oct 2021 09:49:23 +0530 Subject: [PATCH 03/10] fix: docker-compose setup The new image of anandology/frappe-bench has the following changes: - the bench directoy is changed from /home/bench/frappe-bench to /opt/frappe-bench - dependency on external redis service is removed Updated the docker-compose.yml to reflect these changes. Also pinned the docker image to anandology/frappe-bench:2021.10 --- docker-compose.yml | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 6700698e..48dde0f9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,6 @@ version: "3" services: - redis-cache: - image: redis:alpine - redis-queue: - image: redis:alpine - redis-socketio: - image: redis:alpine mariadb: image: mariadb volumes: @@ -15,18 +9,15 @@ services: - MYSQL_ROOT_PASSWORD=root command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci bench: - image: anandology/frappe-bench + image: anandology/frappe-bench:2021.10 volumes: - - .:/home/bench/frappe-bench/apps/community + - .:/opt/frappe-bench/apps/community environment: - FRAPPE_APPS=community - FRAPPE_ALLOW_TESTS=true - FRAPPE_SITE_NAME=frappe.localhost depends_on: - mariadb - - redis-cache - - redis-queue - - redis-socketio ports: - 8000:8000 - 9000:9000 From bb62f626fd2096887b9f21845047f85cf2a21e45 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Thu, 21 Oct 2021 12:53:36 +0530 Subject: [PATCH 04/10] feat: dashboard web templates --- .../web_template/courses_enrolled/__init__.py | 0 .../courses_enrolled/courses_enrolled.html | 28 +++ .../courses_enrolled/courses_enrolled.json | 16 ++ .../web_template/courses_mentored/__init__.py | 0 .../courses_mentored/courses_mentored.html | 11 + .../courses_mentored/courses_mentored.json | 16 ++ community/lms/widgets/CourseCard.html | 196 +++++++++--------- community/overrides/user.py | 3 +- community/public/css/style.css | 1 - community/www/profiles/profile.html | 5 +- 10 files changed, 174 insertions(+), 102 deletions(-) create mode 100644 community/lms/web_template/courses_enrolled/__init__.py create mode 100644 community/lms/web_template/courses_enrolled/courses_enrolled.html create mode 100644 community/lms/web_template/courses_enrolled/courses_enrolled.json create mode 100644 community/lms/web_template/courses_mentored/__init__.py create mode 100644 community/lms/web_template/courses_mentored/courses_mentored.html create mode 100644 community/lms/web_template/courses_mentored/courses_mentored.json diff --git a/community/lms/web_template/courses_enrolled/__init__.py b/community/lms/web_template/courses_enrolled/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/web_template/courses_enrolled/courses_enrolled.html b/community/lms/web_template/courses_enrolled/courses_enrolled.html new file mode 100644 index 00000000..c09babc1 --- /dev/null +++ b/community/lms/web_template/courses_enrolled/courses_enrolled.html @@ -0,0 +1,28 @@ +{% set member = frappe.get_doc("User", frappe.session.user) %} +
+ {% set enrolled = member.get_enrolled_courses().in_progress + member.get_enrolled_courses().completed %} + {% if enrolled | length %} +
+
+ {{ _("Courses Enrolled") }} +
+
+ {% for course in enrolled %} + {{ widgets.CourseCard(course=course) }} + {% endfor %} +
+
+ {% else %} +
+
+ No Enrolled Courses +
+ You have not enrolled in any course yet. +
+ + Explore Courses + +
+
+ {% endif %} +
diff --git a/community/lms/web_template/courses_enrolled/courses_enrolled.json b/community/lms/web_template/courses_enrolled/courses_enrolled.json new file mode 100644 index 00000000..8edc57b1 --- /dev/null +++ b/community/lms/web_template/courses_enrolled/courses_enrolled.json @@ -0,0 +1,16 @@ +{ + "__unsaved": 1, + "creation": "2021-10-21 11:29:50.424865", + "docstatus": 0, + "doctype": "Web Template", + "fields": [], + "idx": 0, + "modified": "2021-10-21 12:02:23.837501", + "modified_by": "Administrator", + "module": "LMS", + "name": "Courses Enrolled", + "owner": "Administrator", + "standard": 1, + "template": "", + "type": "Section" +} \ No newline at end of file diff --git a/community/lms/web_template/courses_mentored/__init__.py b/community/lms/web_template/courses_mentored/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/web_template/courses_mentored/courses_mentored.html b/community/lms/web_template/courses_mentored/courses_mentored.html new file mode 100644 index 00000000..c40697a8 --- /dev/null +++ b/community/lms/web_template/courses_mentored/courses_mentored.html @@ -0,0 +1,11 @@ +{% set member = frappe.get_doc("User", frappe.session.user) %} +
+ {% if member.get_mentored_courses() | length %} +
{{ _("Courses Mentored") }}
+
+ {% for course in member.get_mentored_courses() %} + {{ widgets.CourseCard(course=course) }} + {% endfor %} +
+ {% endif %} +
diff --git a/community/lms/web_template/courses_mentored/courses_mentored.json b/community/lms/web_template/courses_mentored/courses_mentored.json new file mode 100644 index 00000000..9903e1fc --- /dev/null +++ b/community/lms/web_template/courses_mentored/courses_mentored.json @@ -0,0 +1,16 @@ +{ + "__unsaved": 1, + "creation": "2021-10-21 11:32:57.411626", + "docstatus": 0, + "doctype": "Web Template", + "fields": [], + "idx": 0, + "modified": "2021-10-21 12:01:56.270656", + "modified_by": "Administrator", + "module": "LMS", + "name": "Courses Mentored", + "owner": "Administrator", + "standard": 1, + "template": "", + "type": "Section" +} \ No newline at end of file diff --git a/community/lms/widgets/CourseCard.html b/community/lms/widgets/CourseCard.html index 33783870..614c7f6e 100644 --- a/community/lms/widgets/CourseCard.html +++ b/community/lms/widgets/CourseCard.html @@ -2,115 +2,117 @@ {% set progress = frappe.utils.cint(membership.progress) %}
-
+
{% for tag in course.get_tags() %}
{{ tag }}
{% endfor %} {% if membership and not read_only %} - {% if progress < 100 %} -  
{{ frappe.utils.rounded(progress) }}% {{ _("Completed") }}
- {% else %} -
{{ _("Completed") }}
- {% endif %} - {% endif %} + {% if progress < 100 %}  
{{ frappe.utils.rounded(progress) }}% + {{ _("Completed") }}
- {% if not course.image %} -
{{ course.title[0] }}
+ {% else %} +
{{ _("Completed") + }}
+ {% endif %} {% endif %}
+ {% if not course.image %} +
{{ course.title[0] }}
+ {% endif %} +
-
-
- {% if course.get_chapters() | length %} - - {{ course.get_chapters() | length }} {{ _("Chapters") }} - - {% endif %} - {% if course.get_chapters() | length and course.get_upcoming_batches() | length %} - . - {% endif %} - {% if course.get_upcoming_batches() | length %} - - {{ course.get_upcoming_batches() | length }} {{ _("Open Batches") }} - - {% endif %} -
-
{{ course.title }}
-
- - {{ widgets.Avatar(member=course.get_instructor(), avatar_class="avatar-small") }} - - - {{ course.get_instructor().full_name }} - - - - - {% if course.get_students() | length %} - - - {{ course.get_students() | length }} - {% endif %} - {% set avg_rating = course.get_average_rating() %} - {% if avg_rating %} - - - {{ frappe.utils.flt(avg_rating, frappe.get_system_settings("float_precision") or 3) }} +
+
+ {% if course.get_chapters() | length %} + + {{ course.get_chapters() | length }} {{ _("Chapters") }} + + {% endif %} + {% if course.get_chapters() | length and course.get_upcoming_batches() | length %} + . + {% endif %} + {% if course.get_upcoming_batches() | length %} + + {{ course.get_upcoming_batches() | length }} {{ _("Open Batches") }} + + {% endif %} +
+
{{ course.title }}
+
+ + {{ widgets.Avatar(member=course.get_instructor(), avatar_class="avatar-small") }} + + + {{ course.get_instructor().full_name }} - {% endif %} + + + + {% if course.get_students() | length %} + + + {{ course.get_students() | length }} + {% endif %} + {% set avg_rating = course.get_average_rating() %} + {% if avg_rating %} + + + {{ frappe.utils.flt(avg_rating, frappe.get_system_settings("float_precision") or 3) }} -
- - {% if read_only %} - - {% else %} - - {% set lesson_index = course.get_lesson_index(membership.current_lesson) if membership and - membership.current_lesson else '1.1' %} - {% set query_parameter = "?batch=" + membership.batch if membership and - membership.batch else "" %} - {% set certificate = course.is_certified() %} - - {% if certificate %} - - - - {% elif course.enable_certification and progress == 100 %} - - - {% elif progress == 100 %} - - - - {% elif course.upcoming %} - - - - {% elif membership %} - - - - {% else %} - - - - {% endif %} - {% endif %} + {% endif %} +
+ + {% if read_only %} + + {% else %} + + {% set lesson_index = course.get_lesson_index(membership.current_lesson) if membership and + membership.current_lesson else '1.1' %} + {% set query_parameter = "?batch=" + membership.batch if membership and + membership.batch else "" %} + {% set certificate = course.is_certified() %} + + {% if certificate %} + + + + {% elif course.enable_certification and progress == 100 %} + + + {% elif progress == 100 %} + + + + {% elif course.upcoming %} + + + + {% elif membership %} + + + + {% else %} + + + + {% endif %} + {% endif %} +