feat: certificate evaluation
This commit is contained in:
0
lms/lms/doctype/course_evaluator/__init__.py
Normal file
0
lms/lms/doctype/course_evaluator/__init__.py
Normal file
6
lms/lms/doctype/course_evaluator/course_evaluator.js
Normal file
6
lms/lms/doctype/course_evaluator/course_evaluator.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// Copyright (c) 2022, Frappe and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Course Evaluator', {
|
||||||
|
|
||||||
|
});
|
||||||
51
lms/lms/doctype/course_evaluator/course_evaluator.json
Normal file
51
lms/lms/doctype/course_evaluator/course_evaluator.json
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_rename": 1,
|
||||||
|
"creation": "2022-03-29 10:51:47.667284",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"evaluator",
|
||||||
|
"schedule"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "evaluator",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Evaluator",
|
||||||
|
"options": "User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "schedule",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"label": "Schedule",
|
||||||
|
"options": "Evaluator Schedule"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2022-03-29 12:47:10.975155",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "Course Evaluator",
|
||||||
|
"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",
|
||||||
|
"states": [],
|
||||||
|
"title_field": "evaluator"
|
||||||
|
}
|
||||||
33
lms/lms/doctype/course_evaluator/course_evaluator.py
Normal file
33
lms/lms/doctype/course_evaluator/course_evaluator.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Copyright (c) 2022, Frappe and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class CourseEvaluator(Document):
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
self.validate_time_slots()
|
||||||
|
|
||||||
|
def validate_time_slots(self):
|
||||||
|
for schedule in self.schedule:
|
||||||
|
if schedule.start_time >= schedule.end_time:
|
||||||
|
frappe.throw(_("Start Time cannot be greater than End Time"))
|
||||||
|
|
||||||
|
self.validate_overlaps(schedule)
|
||||||
|
|
||||||
|
def validate_overlaps(self, schedule):
|
||||||
|
same_day_slots = list(filter(lambda x: x.day == schedule.day and x.name != schedule.name , self.schedule))
|
||||||
|
overlap = False
|
||||||
|
|
||||||
|
for slot in same_day_slots:
|
||||||
|
if schedule.start_time < slot.start_time < schedule.end_time:
|
||||||
|
overlap = True
|
||||||
|
if schedule.start_time < slot.end_time < schedule.end_time:
|
||||||
|
overlap = True
|
||||||
|
if slot.start_time < schedule.start_time and schedule.end_time < slot.end_time:
|
||||||
|
overlap = True
|
||||||
|
|
||||||
|
if overlap:
|
||||||
|
frappe.throw(_("Slot Times are overlapping for some schedules."))
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2022, Frappe and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestCourseEvaluator(FrappeTestCase):
|
||||||
|
pass
|
||||||
0
lms/lms/doctype/evaluator_schedule/__init__.py
Normal file
0
lms/lms/doctype/evaluator_schedule/__init__.py
Normal file
50
lms/lms/doctype/evaluator_schedule/evaluator_schedule.json
Normal file
50
lms/lms/doctype/evaluator_schedule/evaluator_schedule.json
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"autoname": "autoincrement",
|
||||||
|
"creation": "2022-03-29 11:09:47.726629",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"day",
|
||||||
|
"start_time",
|
||||||
|
"end_time"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "day",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Day",
|
||||||
|
"options": "Sunday\nMonday\nTuesday\nWednesday\nThursday\nFriday\nSaturday",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "start_time",
|
||||||
|
"fieldtype": "Time",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Start Time",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "end_time",
|
||||||
|
"fieldtype": "Time",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "End Time",
|
||||||
|
"reqd": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"istable": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2022-03-29 12:58:22.229033",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "Evaluator Schedule",
|
||||||
|
"naming_rule": "Autoincrement",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"states": []
|
||||||
|
}
|
||||||
8
lms/lms/doctype/evaluator_schedule/evaluator_schedule.py
Normal file
8
lms/lms/doctype/evaluator_schedule/evaluator_schedule.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2022, Frappe and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class EvaluatorSchedule(Document):
|
||||||
|
pass
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-03-09 15:17:15.386067",
|
"modified": "2022-03-29 09:47:05.007133",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Batch Membership",
|
"name": "LMS Batch Membership",
|
||||||
@@ -135,7 +135,9 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
|
"show_title_field_in_link": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": []
|
"states": [],
|
||||||
|
"title_field": "member"
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (c) 2022, Frappe and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('LMS Certificate Evaluation', {
|
||||||
|
onload: function(frm) {
|
||||||
|
frm.set_query("course", function(doc) {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
"enable_certification": true,
|
||||||
|
"grant_certificate_after": "Evaluation"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
frm.set_query("member", function(doc) {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
"course": doc.course,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_rename": 1,
|
||||||
|
"creation": "2022-03-29 09:32:16.769951",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"course",
|
||||||
|
"member",
|
||||||
|
"start",
|
||||||
|
"end",
|
||||||
|
"column_break_5",
|
||||||
|
"rating",
|
||||||
|
"summary"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "course",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "Course",
|
||||||
|
"options": "LMS Course",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "member",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "Member",
|
||||||
|
"options": "LMS Batch Membership",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "start",
|
||||||
|
"fieldtype": "Datetime",
|
||||||
|
"label": "Start"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "end",
|
||||||
|
"fieldtype": "Datetime",
|
||||||
|
"label": "End"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_5",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "rating",
|
||||||
|
"fieldtype": "Rating",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Rating"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "summary",
|
||||||
|
"fieldtype": "Text",
|
||||||
|
"label": "Summary"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2022-03-29 09:48:45.682678",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "LMS Certificate Evaluation",
|
||||||
|
"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",
|
||||||
|
"states": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2022, Frappe and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class LMSCertificateEvaluation(Document):
|
||||||
|
pass
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2022, Frappe and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestLMSCertificateEvaluation(FrappeTestCase):
|
||||||
|
pass
|
||||||
0
lms/lms/doctype/lms_certificate_request/__init__.py
Normal file
0
lms/lms/doctype/lms_certificate_request/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2022, Frappe and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('LMS Certificate Request', {
|
||||||
|
// refresh: function(frm) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
});
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_rename": 1,
|
||||||
|
"creation": "2022-03-29 10:43:50.889723",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"course",
|
||||||
|
"member",
|
||||||
|
"evaluator",
|
||||||
|
"slot"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "course",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Course",
|
||||||
|
"options": "LMS Course",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "member",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Member",
|
||||||
|
"options": "LMS Batch Membership",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "evaluator",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Evaluator"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "slot",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Slot"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2022-03-29 10:43:50.889723",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "LMS Certificate 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",
|
||||||
|
"states": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2022, Frappe and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class LMSCertificateRequest(Document):
|
||||||
|
pass
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2022, Frappe and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestLMSCertificateRequest(FrappeTestCase):
|
||||||
|
pass
|
||||||
@@ -34,7 +34,11 @@
|
|||||||
"related_courses",
|
"related_courses",
|
||||||
"certification_section",
|
"certification_section",
|
||||||
"enable_certification",
|
"enable_certification",
|
||||||
"expiry"
|
"expiry",
|
||||||
|
"column_break_22",
|
||||||
|
"paid_certificate",
|
||||||
|
"grant_certificate_after",
|
||||||
|
"evaluator"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -129,9 +133,8 @@
|
|||||||
"default": "0",
|
"default": "0",
|
||||||
"depends_on": "enable_certification",
|
"depends_on": "enable_certification",
|
||||||
"fieldname": "expiry",
|
"fieldname": "expiry",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Int",
|
||||||
"label": "Certification Expires After Years",
|
"label": "Certification Expires After (Years)"
|
||||||
"options": "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "related_courses",
|
"fieldname": "related_courses",
|
||||||
@@ -161,6 +164,31 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "column_break_12",
|
"fieldname": "column_break_12",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"depends_on": "enable_certification",
|
||||||
|
"fieldname": "paid_certificate",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Paid Certificate"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_22",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "enable_certification",
|
||||||
|
"fieldname": "grant_certificate_after",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Grant Certificate After",
|
||||||
|
"options": "Completion\nEvaluation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval: doc.grant_certificate_after == \"Evaluation\"",
|
||||||
|
"fieldname": "evaluator",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Evaluator",
|
||||||
|
"options": "Course Evaluator"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_published_field": "published",
|
"is_published_field": "published",
|
||||||
@@ -186,7 +214,7 @@
|
|||||||
"link_fieldname": "course"
|
"link_fieldname": "course"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2022-03-24 13:09:37.228855",
|
"modified": "2022-03-29 14:56:03.989375",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Course",
|
"name": "LMS Course",
|
||||||
@@ -225,4 +253,4 @@
|
|||||||
"states": [],
|
"states": [],
|
||||||
"title_field": "title",
|
"title_field": "title",
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@@ -189,15 +189,21 @@
|
|||||||
|
|
||||||
{% set certificate = is_certified(course.name) %}
|
{% set certificate = is_certified(course.name) %}
|
||||||
{% set progress = frappe.utils.cint(membership.progress) %}
|
{% set progress = frappe.utils.cint(membership.progress) %}
|
||||||
|
{% if membership and course.enable_certification %}
|
||||||
{% if certificate %}
|
{% if certificate %}
|
||||||
<a class="button wide-button is-secondary mt-2" href="/courses/{{ course.name }}/{{ certificate }}">
|
<a class="button wide-button is-secondary mt-2" href="/courses/{{ course.name }}/{{ certificate }}">
|
||||||
{{ _("Get Certificate") }}
|
{{ _("Get Certificate") }}
|
||||||
</a>
|
</a>
|
||||||
{% elif course.enable_certification and progress == 100 %}
|
{% elif course.grant_certificate_after == "Evaluation" %}
|
||||||
|
<a class="button wide-button is-secondary mt-2" href="/courses/{{ course.name }}/{{ certificate }}">
|
||||||
|
{{ _("Apply for Certificate") }}
|
||||||
|
</a>
|
||||||
|
{% elif progress == 100 %}
|
||||||
<div class="button wide-button is-secondary mt-4" id="certification" data-course="{{ course.name }}">
|
<div class="button wide-button is-secondary mt-4" id="certification" data-course="{{ course.name }}">
|
||||||
{{ _("Get Certificate") }}
|
{{ _("Get Certificate") }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ def get_context(context):
|
|||||||
|
|
||||||
course = frappe.db.get_value("LMS Course", course_name,
|
course = frappe.db.get_value("LMS Course", course_name,
|
||||||
["name", "title", "image", "short_introduction", "description", "published", "upcoming",
|
["name", "title", "image", "short_introduction", "description", "published", "upcoming",
|
||||||
"disable_self_learning", "video_link", "enable_certification", "status"],
|
"disable_self_learning", "video_link", "enable_certification", "status", "grant_certificate_after"],
|
||||||
as_dict=True)
|
as_dict=True)
|
||||||
|
|
||||||
related_courses = frappe.get_all("Related Courses", {"parent": course.name}, ["course"])
|
related_courses = frappe.get_all("Related Courses", {"parent": course.name}, ["course"])
|
||||||
|
|||||||
Reference in New Issue
Block a user