diff --git a/community/community/doctype/community_member/community_member.json b/community/community/doctype/community_member/community_member.json index d7a4cc03..d82d2fd7 100644 --- a/community/community/doctype/community_member/community_member.json +++ b/community/community/doctype/community_member/community_member.json @@ -20,7 +20,8 @@ "photo", "column_break_12", "email_preference", - "route" + "route", + "abbr" ], "fields": [ { @@ -102,12 +103,18 @@ { "fieldname": "column_break_12", "fieldtype": "Column Break" + }, + { + "fieldname": "abbr", + "fieldtype": "Data", + "label": "Abbr", + "read_only": 1 } ], "has_web_view": 1, "index_web_pages_for_search": 1, "links": [], - "modified": "2021-04-14 09:36:27.813085", + "modified": "2021-04-16 10:22:46.837311", "modified_by": "Administrator", "module": "Community", "name": "Community Member", diff --git a/community/community/doctype/community_member/community_member.py b/community/community/doctype/community_member/community_member.py index 4966535a..a8a9ce9d 100644 --- a/community/community/doctype/community_member/community_member.py +++ b/community/community/doctype/community_member/community_member.py @@ -10,12 +10,10 @@ from frappe import _ from frappe.model.rename_doc import rename_doc class CommunityMember(WebsiteGenerator): - def get_context(self, context): - context.abbr = ("").join([ s[0] for s in self.full_name.split() ]) - return context def validate(self): self.validate_username() + self.abbr = ("").join([ s[0] for s in self.full_name.split() ]) if self.route != self.username: self.route = self.username diff --git a/community/hooks.py b/community/hooks.py index 3c1172ea..1f06cd18 100644 --- a/community/hooks.py +++ b/community/hooks.py @@ -135,7 +135,8 @@ primary_rules = [ {"from_route": "/hackathons", "to_route": "hackathons"}, {"from_route": "/hackathons/", "to_route": "hackathons/hackathon"}, {"from_route": "/hackathons//", "to_route": "hackathons/project"}, - {"from_route": "/dashboard", "to_route": ""} + {"from_route": "/dashboard", "to_route": ""}, + {"from_route": "/add-a-new-batch", "to_route": "add-a-new-batch"} ] # Any frappe default URL is blocked by profile-rules, add it here to unblock it @@ -152,6 +153,7 @@ whitelist = [ "/hackathons", "/dashboard", "/join-request" + "/add-a-new-batch" ] whitelist_rules = [{"from_route": p, "to_route": p[1:]} for p in whitelist] diff --git a/community/lms/doctype/lms_batch/lms_batch.json b/community/lms/doctype/lms_batch/lms_batch.json index ca79b127..d03edaaa 100644 --- a/community/lms/doctype/lms_batch/lms_batch.json +++ b/community/lms/doctype/lms_batch/lms_batch.json @@ -8,8 +8,12 @@ "field_order": [ "course", "title", + "start_date", + "start_time", "column_break_3", "code", + "sessions_on", + "end_time", "section_break_5", "description", "section_break_7", @@ -83,11 +87,32 @@ { "fieldname": "section_break_7", "fieldtype": "Section Break" + }, + { + "fieldname": "start_date", + "fieldtype": "Date", + "label": "Start Date" + }, + { + "fieldname": "start_time", + "fieldtype": "Time", + "label": "Start Time" + }, + { + "description": "Enter Days of the week comma separated.", + "fieldname": "sessions_on", + "fieldtype": "Data", + "label": "Sessions On" + }, + { + "fieldname": "end_time", + "fieldtype": "Time", + "label": "End Time" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-03-19 12:56:33.054884", + "modified": "2021-04-15 10:52:24.358628", "modified_by": "Administrator", "module": "LMS", "name": "LMS Batch", 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 23e29f50..1b339282 100644 --- a/community/lms/doctype/lms_batch_membership/lms_batch_membership.json +++ b/community/lms/doctype/lms_batch_membership/lms_batch_membership.json @@ -6,9 +6,11 @@ "engine": "InnoDB", "field_order": [ "batch", + "role", + "column_break_3", "member", - "member_type", - "role" + "member_name", + "member_type" ], "fields": [ { @@ -38,11 +40,23 @@ "in_list_view": 1, "label": "Role", "options": "\nMember\nAdmin" + }, + { + "fetch_from": "member.full_name", + "fieldname": "member_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Member Name", + "read_only": 1 + }, + { + "fieldname": "column_break_3", + "fieldtype": "Column Break" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-03-19 15:06:21.374601", + "modified": "2021-04-16 09:57:52.926943", "modified_by": "Administrator", "module": "LMS", "name": "LMS Batch Membership", diff --git a/community/lms/doctype/lms_batch_membership/lms_batch_membership.py b/community/lms/doctype/lms_batch_membership/lms_batch_membership.py index d7639fcd..913b206e 100644 --- a/community/lms/doctype/lms_batch_membership/lms_batch_membership.py +++ b/community/lms/doctype/lms_batch_membership/lms_batch_membership.py @@ -26,4 +26,17 @@ class LMSBatchMembership(Document): batch_course = frappe.db.get_value("LMS Batch", membership.batch, "course") if batch_course == course and (membership.member_type == "Student" or self.member_type == "Student"): member_name = frappe.db.get_value("Community Member", self.member, "full_name") - frappe.throw(_("{0} is already a {1} of {2} course through {3} batch").format(member_name, membership.member_type, course, membership.batch)) \ No newline at end of file + frappe.throw(_("{0} is already a {1} of {2} course through {3} batch").format(member_name, membership.member_type, course, membership.batch)) + +@frappe.whitelist() +def create_member(batch, member=None, member_type="Student", role="Member"): + if not member: + member = frappe.db.get_value("Community Member", {"email": frappe.session.user}, "name") + frappe.get_doc({ + "doctype": "LMS Batch Membership", + "batch": batch, + "role": role, + "member_type": member_type, + "member": member + }).save(ignore_permissions=True) + return "OK" \ No newline at end of file diff --git a/community/lms/doctype/lms_course/lms_course.json b/community/lms/doctype/lms_course/lms_course.json index 33c582b7..e03e90b6 100644 --- a/community/lms/doctype/lms_course/lms_course.json +++ b/community/lms/doctype/lms_course/lms_course.json @@ -58,7 +58,7 @@ { "fieldname": "video_link", "fieldtype": "Data", - "label": "Video Link" + "label": "Video Embed Link" }, { "fieldname": "section_break_5", @@ -73,7 +73,7 @@ "index_web_pages_for_search": 1, "is_published_field": "is_published", "links": [], - "modified": "2021-04-14 15:23:39.592341", + "modified": "2021-04-15 10:09:25.608422", "modified_by": "Administrator", "module": "LMS", "name": "LMS Course", diff --git a/community/lms/doctype/lms_course_mentor_mapping/__init__.py b/community/lms/doctype/lms_course_mentor_mapping/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/doctype/lms_course_mentor_mapping/lms_course_mentor_mapping.js b/community/lms/doctype/lms_course_mentor_mapping/lms_course_mentor_mapping.js new file mode 100644 index 00000000..5b17f61a --- /dev/null +++ b/community/lms/doctype/lms_course_mentor_mapping/lms_course_mentor_mapping.js @@ -0,0 +1,8 @@ +// Copyright (c) 2021, FOSS United and contributors +// For license information, please see license.txt + +frappe.ui.form.on('LMS Course Mentor Mapping', { + // refresh: function(frm) { + + // } +}); diff --git a/community/lms/doctype/lms_course_mentor_mapping/lms_course_mentor_mapping.json b/community/lms/doctype/lms_course_mentor_mapping/lms_course_mentor_mapping.json new file mode 100644 index 00000000..a9026aec --- /dev/null +++ b/community/lms/doctype/lms_course_mentor_mapping/lms_course_mentor_mapping.json @@ -0,0 +1,61 @@ +{ + "actions": [], + "creation": "2021-04-20 12:45:33.369767", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "course", + "mentor", + "mentor_name" + ], + "fields": [ + { + "fieldname": "course", + "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Course", + "options": "LMS Course" + }, + { + "fieldname": "mentor", + "fieldtype": "Link", + "in_standard_filter": 1, + "label": "Mentor", + "options": "Community Member" + }, + { + "fetch_from": "mentor.full_name", + "fieldname": "mentor_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Mentor Name", + "read_only": 1 + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2021-04-20 12:46:48.460934", + "modified_by": "Administrator", + "module": "LMS", + "name": "LMS Course Mentor Mapping", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/community/lms/doctype/lms_course_mentor_mapping/lms_course_mentor_mapping.py b/community/lms/doctype/lms_course_mentor_mapping/lms_course_mentor_mapping.py new file mode 100644 index 00000000..33ff05b0 --- /dev/null +++ b/community/lms/doctype/lms_course_mentor_mapping/lms_course_mentor_mapping.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2021, FOSS United and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +# import frappe +from frappe.model.document import Document + +class LMSCourseMentorMapping(Document): + pass diff --git a/community/lms/doctype/lms_course_mentor_mapping/test_lms_course_mentor_mapping.py b/community/lms/doctype/lms_course_mentor_mapping/test_lms_course_mentor_mapping.py new file mode 100644 index 00000000..e0ba2be5 --- /dev/null +++ b/community/lms/doctype/lms_course_mentor_mapping/test_lms_course_mentor_mapping.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2021, FOSS United and Contributors +# See license.txt +from __future__ import unicode_literals + +# import frappe +import unittest + +class TestLMSCourseMentorMapping(unittest.TestCase): + pass diff --git a/community/lms/doctype/lms_mentor_request/__init__.py b/community/lms/doctype/lms_mentor_request/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/doctype/lms_mentor_request/lms_mentor_request.js b/community/lms/doctype/lms_mentor_request/lms_mentor_request.js new file mode 100644 index 00000000..338e39b1 --- /dev/null +++ b/community/lms/doctype/lms_mentor_request/lms_mentor_request.js @@ -0,0 +1,8 @@ +// Copyright (c) 2021, FOSS United and contributors +// For license information, please see license.txt + +frappe.ui.form.on('LMS Mentor Request', { + // refresh: function(frm) { + + // } +}); diff --git a/community/lms/doctype/lms_mentor_request/lms_mentor_request.json b/community/lms/doctype/lms_mentor_request/lms_mentor_request.json new file mode 100644 index 00000000..00949bed --- /dev/null +++ b/community/lms/doctype/lms_mentor_request/lms_mentor_request.json @@ -0,0 +1,87 @@ +{ + "actions": [], + "creation": "2021-04-18 11:48:02.635688", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "member", + "course", + "reviewed_by", + "column_break_3", + "member_name", + "status", + "comments" + ], + "fields": [ + { + "fieldname": "member", + "fieldtype": "Link", + "in_standard_filter": 1, + "label": "Member", + "options": "Community Member" + }, + { + "fieldname": "course", + "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Course", + "options": "LMS Course" + }, + { + "fieldname": "column_break_3", + "fieldtype": "Column Break" + }, + { + "fetch_from": "member.full_name", + "fieldname": "member_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Member Name" + }, + { + "fieldname": "status", + "fieldtype": "Select", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Status", + "options": "Pending\nApproved\nRejected\nWithdrawn" + }, + { + "fieldname": "reviewed_by", + "fieldtype": "Link", + "label": "Reviewed By", + "options": "Community Member" + }, + { + "fieldname": "comments", + "fieldtype": "Small Text", + "label": "Comments" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2021-04-19 09:27:03.814016", + "modified_by": "Administrator", + "module": "LMS", + "name": "LMS Mentor Request", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/community/lms/doctype/lms_mentor_request/lms_mentor_request.py b/community/lms/doctype/lms_mentor_request/lms_mentor_request.py new file mode 100644 index 00000000..ac76ef50 --- /dev/null +++ b/community/lms/doctype/lms_mentor_request/lms_mentor_request.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2021, FOSS United and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document +from frappe import _ + +class LMSMentorRequest(Document): + def on_update(self): + if self.has_value_changed('status'): + template = frappe.db.get_single_value('LMS Settings', 'mentor_request_status_update') + email_template = frappe.get_doc('Email Template', template) + message = frappe.render_template(email_template.response, {'member_name': self.member_name, 'status': self.status}) + subject = _('The status of your application has changed.') + member_email = frappe.db.get_value("Community Member", self.member, "email") + if self.status == 'Approved' or self.status == 'Rejected': + reviewed_by = frappe.db.get_value('Community Member', self.reviewed_by, 'email') + send_email(member_email, [get_course_author(self.course), reviewed_by], subject, message) + elif self.status == 'Withdrawn': + send_email([member_email, get_course_author(self.course)], None, subject, message) + +@frappe.whitelist() +def has_requested(course): + return len(frappe.get_all('LMS Mentor Request', + filters = { + 'member': get_member().name, + 'course': course, + 'status': ['in', ('Pending', 'Approved')] + } + ) + ) + +@frappe.whitelist() +def create_request(course): + if not has_requested(course): + member = get_member() + frappe.get_doc({ + 'doctype': 'LMS Mentor Request', + 'member': member.name, + 'course': course, + 'status': 'Pending' + }).save(ignore_permissions=True) + send_creation_email(course, member) + return 'OK' + else: + return 'Already Applied' + +@frappe.whitelist() +def cancel_request(course): + request = frappe.get_doc('LMS Mentor Request', {'member': get_member().name, 'course': course, 'status': ['in', ('Pending', 'Approved')]}) + request.status = 'Withdrawn' + request.save(ignore_permissions=True) + return 'OK' + +def get_member(): + try: + return frappe.get_doc('Community Member', {'email': frappe.session.user}) + except frappe.DoesNotExistError: + return + +def get_course_author(course): + return frappe.db.get_value('LMS Course', course, 'owner') + +def send_creation_email(course, member): + template = frappe.db.get_single_value('LMS Settings', 'mentor_request_creation') + email_template = frappe.get_doc('Email Template', template) + member_name = member.full_name + message = frappe.render_template(email_template.response, {'member_name': member_name}) + subject = _('Request for Mentorship') + send_email([frappe.session.user, get_course_author(course)], None, subject, message) + +def send_email(recipients, cc, subject, message): + frappe.sendmail( + recipients = recipients, + cc = cc, + sender = frappe.db.get_single_value('LMS Settings', 'email_sender'), + subject = subject, + send_priority = 0, + queue_separately = True, + message = message + ) \ No newline at end of file diff --git a/community/lms/doctype/lms_mentor_request/test_lms_mentor_request.py b/community/lms/doctype/lms_mentor_request/test_lms_mentor_request.py new file mode 100644 index 00000000..3441f72f --- /dev/null +++ b/community/lms/doctype/lms_mentor_request/test_lms_mentor_request.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2021, FOSS United and Contributors +# See license.txt +from __future__ import unicode_literals + +# import frappe +import unittest + +class TestLMSMentorRequest(unittest.TestCase): + pass diff --git a/community/lms/doctype/lms_settings/lms_settings.json b/community/lms/doctype/lms_settings/lms_settings.json index 07789ef2..ae306ca6 100644 --- a/community/lms/doctype/lms_settings/lms_settings.json +++ b/community/lms/doctype/lms_settings/lms_settings.json @@ -5,7 +5,10 @@ "editable_grid": 1, "engine": "InnoDB", "field_order": [ - "livecode_url" + "livecode_url", + "mentor_request_creation", + "mentor_request_status_update", + "email_sender" ], "fields": [ { @@ -13,12 +16,30 @@ "fieldname": "livecode_url", "fieldtype": "Data", "label": "LiveCode URL" + }, + { + "fieldname": "mentor_request_creation", + "fieldtype": "Link", + "label": "Mentor Request Creation", + "options": "Email Template" + }, + { + "fieldname": "mentor_request_status_update", + "fieldtype": "Link", + "label": "Mentor Request Status update", + "options": "Email Template" + }, + { + "fieldname": "email_sender", + "fieldtype": "Data", + "label": "Email Sender", + "options": "Email" } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2021-03-09 14:30:15.807410", + "modified": "2021-04-19 13:18:40.497636", "modified_by": "Administrator", "module": "LMS", "name": "LMS Settings", diff --git a/community/lms/web_form/add_a_new_batch/__init__.py b/community/lms/web_form/add_a_new_batch/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/web_form/add_a_new_batch/add_a_new_batch.js b/community/lms/web_form/add_a_new_batch/add_a_new_batch.js new file mode 100644 index 00000000..699703c5 --- /dev/null +++ b/community/lms/web_form/add_a_new_batch/add_a_new_batch.js @@ -0,0 +1,3 @@ +frappe.ready(function() { + // bind events here +}) \ No newline at end of file diff --git a/community/lms/web_form/add_a_new_batch/add_a_new_batch.json b/community/lms/web_form/add_a_new_batch/add_a_new_batch.json new file mode 100644 index 00000000..b2db5878 --- /dev/null +++ b/community/lms/web_form/add_a_new_batch/add_a_new_batch.json @@ -0,0 +1,124 @@ +{ + "accept_payment": 0, + "allow_comments": 0, + "allow_delete": 0, + "allow_edit": 0, + "allow_incomplete": 0, + "allow_multiple": 0, + "allow_print": 0, + "amount": 0.0, + "amount_based_on_field": 0, + "apply_document_permissions": 0, + "button_label": "Save", + "creation": "2021-04-20 11:37:49.135114", + "doc_type": "LMS Batch", + "docstatus": 0, + "doctype": "Web Form", + "idx": 0, + "is_standard": 1, + "login_required": 1, + "max_attachment_size": 0, + "modified": "2021-04-20 11:51:35.815876", + "modified_by": "Administrator", + "module": "LMS", + "name": "add-a-new-batch", + "owner": "Administrator", + "payment_button_label": "Buy Now", + "published": 1, + "route": "add-a-new-batch", + "route_to_success_link": 0, + "show_attachments": 0, + "show_in_grid": 0, + "show_sidebar": 0, + "sidebar_items": [], + "success_url": "/add-a-new-batch", + "title": "Add a new batch", + "web_form_fields": [ + { + "allow_read_on_all_link_options": 0, + "fieldname": "course", + "fieldtype": "Link", + "hidden": 0, + "label": "Course", + "max_length": 0, + "max_value": 0, + "options": "LMS Course", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "start_date", + "fieldtype": "Date", + "hidden": 0, + "label": "Start Date", + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "start_time", + "fieldtype": "Data", + "hidden": 0, + "label": "Start Time", + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "", + "fieldtype": "Column Break", + "hidden": 0, + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "title", + "fieldtype": "Data", + "hidden": 0, + "label": "Title", + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "description": "Enter Days of the week comma separated.", + "fieldname": "sessions_on", + "fieldtype": "Data", + "hidden": 0, + "label": "Sessions On", + "max_length": 0, + "max_value": 0, + "options": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "end_time", + "fieldtype": "Data", + "hidden": 0, + "label": "End Time", + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + } + ] +} \ No newline at end of file diff --git a/community/lms/web_form/add_a_new_batch/add_a_new_batch.py b/community/lms/web_form/add_a_new_batch/add_a_new_batch.py new file mode 100644 index 00000000..2334f8b2 --- /dev/null +++ b/community/lms/web_form/add_a_new_batch/add_a_new_batch.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +import frappe + +def get_context(context): + # do your magic here + pass diff --git a/community/lms/web_form/join_a_batch/__init__.py b/community/lms/web_form/join_a_batch/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/web_form/join_a_batch/join_a_batch.js b/community/lms/web_form/join_a_batch/join_a_batch.js new file mode 100644 index 00000000..699703c5 --- /dev/null +++ b/community/lms/web_form/join_a_batch/join_a_batch.js @@ -0,0 +1,3 @@ +frappe.ready(function() { + // bind events here +}) \ No newline at end of file diff --git a/community/lms/web_form/join_a_batch/join_a_batch.json b/community/lms/web_form/join_a_batch/join_a_batch.json new file mode 100644 index 00000000..9afd7801 --- /dev/null +++ b/community/lms/web_form/join_a_batch/join_a_batch.json @@ -0,0 +1,48 @@ +{ + "accept_payment": 0, + "allow_comments": 0, + "allow_delete": 0, + "allow_edit": 0, + "allow_incomplete": 0, + "allow_multiple": 0, + "allow_print": 0, + "amount": 0.0, + "amount_based_on_field": 0, + "apply_document_permissions": 0, + "button_label": "Save", + "creation": "2021-04-15 13:32:14.171328", + "doc_type": "LMS Batch Membership", + "docstatus": 0, + "doctype": "Web Form", + "idx": 0, + "is_standard": 1, + "login_required": 1, + "max_attachment_size": 0, + "modified": "2021-04-15 13:32:14.171328", + "modified_by": "Administrator", + "module": "LMS", + "name": "join-a-batch", + "owner": "Administrator", + "payment_button_label": "Buy Now", + "published": 1, + "route": "join-a-batch", + "route_to_success_link": 0, + "show_attachments": 0, + "show_in_grid": 0, + "show_sidebar": 0, + "sidebar_items": [], + "success_url": "/join-a-batch", + "title": "Join a Batch", + "web_form_fields": [ + { + "allow_read_on_all_link_options": 0, + "fieldtype": "Attach", + "hidden": 0, + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + } + ] +} \ No newline at end of file diff --git a/community/lms/web_form/join_a_batch/join_a_batch.py b/community/lms/web_form/join_a_batch/join_a_batch.py new file mode 100644 index 00000000..2334f8b2 --- /dev/null +++ b/community/lms/web_form/join_a_batch/join_a_batch.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +import frappe + +def get_context(context): + # do your magic here + pass diff --git a/community/patches.txt b/community/patches.txt index fa60560e..8ec78bbd 100644 --- a/community/patches.txt +++ b/community/patches.txt @@ -1,2 +1,3 @@ community.patches.set_email_preferences -community.patches.change_name_for_community_members \ No newline at end of file +community.patches.change_name_for_community_members +community.patches.save_abbr_for_community_members \ No newline at end of file diff --git a/community/patches/save_abbr_for_community_members.py b/community/patches/save_abbr_for_community_members.py new file mode 100644 index 00000000..ccf3783d --- /dev/null +++ b/community/patches/save_abbr_for_community_members.py @@ -0,0 +1,11 @@ +from __future__ import unicode_literals +import frappe + +def execute(): + frappe.reload_doc("community", "doctype", "community_member") + docs = frappe.get_all("Community Member") + for doc in docs: + member = frappe.get_doc("Community Member", doc.name) + if not member.abbr: + abbr = ("").join([ s[0] for s in member.full_name.split() ]) + frappe.db.set_value("Community Member", member.name, "abbr", abbr) diff --git a/community/www/courses/course.html b/community/www/courses/course.html index c51f98c3..91a874a1 100644 --- a/community/www/courses/course.html +++ b/community/www/courses/course.html @@ -1,28 +1,257 @@ {% extends "templates/base.html" %} -{% block title %}{{ 'Courses' }}{% endblock %} +{% from "www/macros/profile.html" import profile %} +{% block title %}{{ "Courses" }}{% endblock %} {% block head_include %} {% endblock %} {% block content %}
-
+
Enrolled
-
- -

{{ course.title }}

+
+
+ +

{{ course.title }}

+ {{course.short_introduction}} +
+
+ +
-
{% endblock %} \ No newline at end of file diff --git a/community/www/courses/course.js b/community/www/courses/course.js index 0e586f1c..3ccfefb3 100644 --- a/community/www/courses/course.js +++ b/community/www/courses/course.js @@ -1,4 +1,19 @@ frappe.ready(() => { + if (frappe.session.user != "Guest") { + frappe.call({ + 'method': 'community.lms.doctype.lms_mentor_request.lms_mentor_request.has_requested', + 'args': { + course: $(".course-title").attr("data-course"), + }, + 'callback': (data) => { + if (data.message) { + $(".mentor-request").addClass("hide"); + $(".already-applied").removeClass("hide") + } + } + }) + } + $(".list-batch").click((e) => { var batch = decodeURIComponent($(e.currentTarget).attr("data-label")) $(".current-batch").text(batch) @@ -13,6 +28,7 @@ frappe.ready(() => { } }) }) + $(".send-message").click((e) => { var message = $(".message-text").val().trim(); if (message) { @@ -34,6 +50,61 @@ frappe.ready(() => { $(".message-text").val(""); } }) + + $(".apply-now").click((e) => { + if (frappe.session.user == "Guest") { + window.location.href = "/login"; + return; + } + frappe.call({ + "method": "community.lms.doctype.lms_mentor_request.lms_mentor_request.create_request", + "args": { + "course": decodeURIComponent($(e.currentTarget).attr("data-course")) + }, + "callback": (data) => { + if (data.message == "OK") { + $(".mentor-request").addClass("hide"); + $(".already-applied").removeClass("hide") + } + } + }) + }) + + $(".cancel-request").click((e) => { + frappe.call({ + "method": "community.lms.doctype.lms_mentor_request.lms_mentor_request.cancel_request", + "args": { + "course": decodeURIComponent($(e.currentTarget).attr("data-course")) + }, + "callback": (data) => { + if (data.message == "OK") { + $(".mentor-request").removeClass("hide"); + $(".already-applied").addClass("hide") + } + } + }) + }) + + $(".join-batch").click((e) => { + if (frappe.session.user == "Guest") { + window.location.href = "/login"; + return; + } + batch = decodeURIComponent($(e.currentTarget).attr("data-batch")) + frappe.call({ + "method": "community.lms.doctype.lms_batch_membership.lms_batch_membership.create_member", + "args": { + "batch": batch + }, + "callback": (data) => { + if (data.message == "OK") { + frappe.msgprint(__("You are now a student of this course.")) + $(".upcoming-batches").addClass("hide") + } + } + }) + }) + var add_message = (message, session_user = false) => { var author_name = session_user ? "You" : message.author_name return `
@@ -42,13 +113,6 @@ frappe.ready(() => {
${message.creation}
`; } - /* if(frappe.session.user != "Guest"){ - frappe.call('community.www.courses.course.has_enrolled', { course: get_search_params().get("course") }, (data) => { - if (data.message) { - show_enrollment_badge() - } - }) - } */ }) /* var show_enrollment_badge = () => { diff --git a/community/www/courses/course.py b/community/www/courses/course.py index d34eb3b5..fa3b4271 100644 --- a/community/www/courses/course.py +++ b/community/www/courses/course.py @@ -1,19 +1,27 @@ import frappe +from frappe.utils import nowdate, getdate def get_context(context): context.no_cache = 1 try: - course_id = frappe.form_dict['course'] + course_id = frappe.form_dict["course"] except KeyError: - frappe.local.flags.redirect_location = '/courses' + frappe.local.flags.redirect_location = "/courses" raise frappe.Redirect context.course = get_course(course_id) + context.batches = get_course_batches(context.course.name) + context.upcoming_batches = get_upcoming_batches(context.course.name, context.batches) #context.course_enrolled = has_enrolled(course_id) - context.discussions, context.memberships = get_discussions(course_id) + context.discussions, context.memberships = get_discussions(context.batches) + context.instructor = get_instructor(course_id) + context.mentors = get_mentors(context.course.name) if context.memberships: context.member_type = context.memberships[0].member_type if context.member_type != "Student": context.batches = [membership.batch for membership in context.memberships] + if context.member_type == "Mentor": + context.is_mentor = True + context.mentor_batches = get_mentor_batches(context.memberships) context.current_batch = context.memberships[0].batch context.author = context.memberships[0].member else: @@ -23,34 +31,87 @@ def get_context(context): context.author = None def get_course(slug): - course = frappe.db.get_value('LMS Course', {"slug": slug}, - ['name', 'slug', 'title', 'description'], as_dict=1) + course = frappe.db.get_value("LMS Course", {"slug": slug}, + ["name", "slug", "title", "description", "short_introduction", "video_link"], as_dict=1) - course['topics'] = frappe.db.get_all('LMS Topic', + course["topics"] = frappe.db.get_all("LMS Topic", filters={ - 'course': course['name'] + "course": course["name"] }, - fields=['name', 'slug', 'title', 'preview'], - order_by='creation' + fields=["name", "slug", "title", "preview"], + order_by="creation" ) return course -def get_discussions(slug): - memberships = get_membership(slug) - messages = get_messages(memberships[0].batch) +def get_upcoming_batches(course, all_batches): + memberships = get_membership(all_batches) + if not len(memberships): + batches = frappe.get_all("LMS Batch", {"course": course, "start_date": [">", nowdate()]}, ["start_date", "start_time", "end_time", "sessions_on", "name"]) + batches = get_batch_mentors(batches) + return batches + return [] + +def get_batch_mentors(batches): + for batch in batches: + batch.mentors = [] + mentors = frappe.get_all("LMS Batch Membership", {"batch": batch.name, "member_type": "Mentor"}, ["member"]) + for mentor in mentors: + member = frappe.db.get_value("Community Member", mentor.member, ["full_name", "photo", "abbr"], as_dict=1) + batch.mentors.append(member) + return batches + +def get_discussions(batches): + messages = [] + memberships = get_membership(batches) + if len(memberships): + messages = get_messages(memberships[0].batch) return messages, memberships -def get_membership(slug): +def get_membership(batches): memberships = [] - course = frappe.db.get_value("LMS Course", {"slug": slug}, "name") member = frappe.db.get_value("Community Member", {"email": frappe.session.user}, "name") - batches = frappe.get_all("LMS Batch", {"course": course}, ["name"]) for batch in batches: membership = frappe.db.get_value("LMS Batch Membership", {"member": member, "batch": batch.name}, ["batch", "member", "member_type"], as_dict=1) if membership: memberships.append(membership) return memberships +def get_instructor(slug): + owner = frappe.db.get_value("LMS Course", {"slug":slug}, ["owner"]) + instructor = frappe.get_doc("Community Member", {"email": owner}) + instructor.course_count = len(frappe.get_all("LMS Course", {"owner": owner})) + return instructor + +def get_mentors(course): + course_mentors = [] + mentors = frappe.get_all("LMS Course Mentor Mapping", {"course": course}, ["member"]) + for mentor in mentors: + member = frappe.get_doc("Community Member", mentor.member) + member_in_list = list(filter(lambda x: x.name == member.name, course_mentors)) + if not member_in_list: + member.batch_count = len(frappe.get_all("LMS Batch Membership", {"member": member.name, "member_type": "Mentor"})) + course_mentors.append(member) + return course_mentors + +def get_course_batches(course): + return frappe.get_all("LMS Batch", {"course": course}, ["name"]) + +def get_mentor_batches(memberships): + mentor_batches = [] + memberships_as_mentor = list(filter(lambda x: x.member_type == "Mentor", memberships)) + for membership in memberships_as_mentor: + batch = frappe.get_doc("LMS Batch", membership.batch) + mentor_batches.append(batch) + for batch in mentor_batches: + if getdate(batch.start_date) < getdate(): + batch.status = "active" + batch.badge_class = "green_badge" + else: + batch.status = "scheduled" + batch.badge_class = "yellow_badge" + mentor_batches = get_batch_mentors(mentor_batches) + return mentor_batches + @frappe.whitelist() def get_messages(batch): messages = frappe.get_all("LMS Message", {"batch": batch}, ["*"], order_by="creation desc") diff --git a/community/www/dashboard/index.html b/community/www/dashboard/index.html index 7ad5e8a9..b9358fb3 100644 --- a/community/www/dashboard/index.html +++ b/community/www/dashboard/index.html @@ -91,7 +91,7 @@
- {{ profile(member.photo, member.full_name, abbr, "large")}} + {{ profile(member.photo, member.full_name, member.abbr, "large")}}
diff --git a/community/www/dashboard/index.py b/community/www/dashboard/index.py index 7f78ef39..9ca3df4f 100644 --- a/community/www/dashboard/index.py +++ b/community/www/dashboard/index.py @@ -3,8 +3,7 @@ from ...lms.doctype.lms_sketch.lms_sketch import get_recent_sketches def get_context(context): context.no_cache = 1 - context.member = frappe.get_all("Community Member", {"email": frappe.session.user}, ["name", "email", "photo", "full_name"])[0] - context.abbr = "".join([s[0] for s in context.member.full_name.split()]) + context.member = frappe.get_all("Community Member", {"email": frappe.session.user}, ["name", "email", "photo", "full_name", "abbr"])[0] context.memberships = get_memberships(context.member.name) context.courses = get_courses(context.memberships) context.activity = get_activity(context.memberships) @@ -35,7 +34,5 @@ def get_activity(memberships): messages = frappe.get_all("LMS Message", {"batch": ["in", ",".join(batches)]}, ["message", "author", "creation", "batch"], order_by='creation desc') for message in messages: message.course = courses[message.batch] - message.profile, message.full_name = frappe.db.get_value("Community Member", message.author, ["photo", "full_name"]) - if not message.profile: - message.abbr = "".join([s[0] for s in message.full_name.split()]) + message.profile, message.full_name, message.abbr = frappe.db.get_value("Community Member", message.author, ["photo", "full_name", "abbr"]) return messages \ No newline at end of file diff --git a/community/www/hackathons/project.html b/community/www/hackathons/project.html index 77666f58..8625dcea 100644 --- a/community/www/hackathons/project.html +++ b/community/www/hackathons/project.html @@ -159,7 +159,7 @@ {% for update in updates %} {{ add_update(update.project_update, update.creation) }} - {% endfor %} + {% {{ add_update("Project created by " + frappe.db.get_value('User', project.owner, 'full_name'), diff --git a/community/www/profiles/profile.html b/community/www/profiles/profile.html index 3fe8c4db..6631f039 100644 --- a/community/www/profiles/profile.html +++ b/community/www/profiles/profile.html @@ -89,7 +89,7 @@
- {{ profile(member.photo, member.full_name, abbr, "large")}} + {{ profile(member.photo, member.full_name, member.abbr, "large")}}
@@ -131,7 +131,7 @@ {% endif %}
{% if not sketches %} -

{{member.full_name}} has not created any skecth yet.

+

{{member.full_name}} has not created any skecth yet.

{% endif %}
diff --git a/community/www/profiles/profile.py b/community/www/profiles/profile.py index 427574be..31aa1be0 100644 --- a/community/www/profiles/profile.py +++ b/community/www/profiles/profile.py @@ -8,7 +8,6 @@ def get_context(context): if not context.member: context.template = "www/404.html" else: - context.abbr = "".join([s[0] for s in context.member.full_name.split()]) context.sketches = list(filter(lambda x: x.owner == context.member.email, get_recent_sketches())) def get_member(username):