Merge branch 'main' of https://github.com/frappe/lms into lms-frappe-ui
This commit is contained in:
@@ -28,6 +28,10 @@ frappe.ui.form.on("LMS Batch", {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (frm.doc.timetable.length && !frm.doc.timetable_legends.length) {
|
||||||
|
set_default_legends(frm);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
timetable_template: function (frm) {
|
timetable_template: function (frm) {
|
||||||
@@ -127,3 +131,37 @@ const add_legend_rows = (frm, legends) => {
|
|||||||
frm.refresh_field("timetable_legends");
|
frm.refresh_field("timetable_legends");
|
||||||
frm.save();
|
frm.save();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const set_default_legends = (frm) => {
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
reference_doctype: "Course Lesson",
|
||||||
|
label: "Lesson",
|
||||||
|
color: "#449CF0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
reference_doctype: "LMS Quiz",
|
||||||
|
label: "LMS Quiz",
|
||||||
|
color: "#39E4A5",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
reference_doctype: "LMS Assignment",
|
||||||
|
label: "LMS Assignment",
|
||||||
|
color: "#ECAD4B",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
reference_doctype: "LMS Live Class",
|
||||||
|
label: "LMS Live Class",
|
||||||
|
color: "#bb8be8",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
data.forEach((detail) => {
|
||||||
|
let child = frm.add_child("timetable_legends");
|
||||||
|
child.reference_doctype = detail.reference_doctype;
|
||||||
|
child.label = detail.label;
|
||||||
|
child.color = detail.color;
|
||||||
|
});
|
||||||
|
frm.refresh_field("timetable_legends");
|
||||||
|
frm.save();
|
||||||
|
};
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
"category",
|
"category",
|
||||||
"column_break_flwy",
|
"column_break_flwy",
|
||||||
"seat_count",
|
"seat_count",
|
||||||
|
"evaluation_end_date",
|
||||||
"section_break_6",
|
"section_break_6",
|
||||||
"description",
|
"description",
|
||||||
"batch_details_raw",
|
"batch_details_raw",
|
||||||
@@ -279,11 +280,16 @@
|
|||||||
"fieldname": "allow_future",
|
"fieldname": "allow_future",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Allow accessing future dates"
|
"label": "Allow accessing future dates"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "evaluation_end_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"label": "Evaluation End Date"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-11-17 10:41:00.340418",
|
"modified": "2023-11-29 12:06:58.776479",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Batch",
|
"name": "LMS Batch",
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class LMSBatch(Document):
|
|||||||
self.validate_membership()
|
self.validate_membership()
|
||||||
self.validate_timetable()
|
self.validate_timetable()
|
||||||
self.send_confirmation_mail()
|
self.send_confirmation_mail()
|
||||||
|
self.validate_evaluation_end_date()
|
||||||
|
|
||||||
def validate_duplicate_students(self):
|
def validate_duplicate_students(self):
|
||||||
students = [row.student for row in self.students]
|
students = [row.student for row in self.students]
|
||||||
@@ -68,6 +69,10 @@ class LMSBatch(Document):
|
|||||||
self.send_mail(student)
|
self.send_mail(student)
|
||||||
student.confirmation_email_sent = 1
|
student.confirmation_email_sent = 1
|
||||||
|
|
||||||
|
def validate_evaluation_end_date(self):
|
||||||
|
if self.evaluation_end_date and self.evaluation_end_date < self.end_date:
|
||||||
|
frappe.throw(_("Evaluation end date cannot be less than the batch end date."))
|
||||||
|
|
||||||
def send_mail(self, student):
|
def send_mail(self, student):
|
||||||
subject = _("Enrollment Confirmation for the Next Training Batch")
|
subject = _("Enrollment Confirmation for the Next Training Batch")
|
||||||
template = "batch_confirmation"
|
template = "batch_confirmation"
|
||||||
@@ -253,6 +258,7 @@ def create_batch(
|
|||||||
currency=None,
|
currency=None,
|
||||||
name=None,
|
name=None,
|
||||||
published=0,
|
published=0,
|
||||||
|
evaluation_end_date=None,
|
||||||
):
|
):
|
||||||
frappe.only_for("Moderator")
|
frappe.only_for("Moderator")
|
||||||
if name:
|
if name:
|
||||||
@@ -278,6 +284,7 @@ def create_batch(
|
|||||||
"amount": amount,
|
"amount": amount,
|
||||||
"currency": currency,
|
"currency": currency,
|
||||||
"published": published,
|
"published": published,
|
||||||
|
"evaluation_end_date": evaluation_end_date,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
doc.save()
|
doc.save()
|
||||||
|
|||||||
@@ -103,13 +103,13 @@
|
|||||||
"fieldname": "batch_name",
|
"fieldname": "batch_name",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Batch Name",
|
"label": "Batch",
|
||||||
"options": "LMS Batch"
|
"options": "LMS Batch"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-08-23 14:50:37.618352",
|
"modified": "2023-11-29 15:00:30.617298",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Certificate Request",
|
"name": "LMS Certificate Request",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ from lms.lms.utils import get_evaluator
|
|||||||
class LMSCertificateRequest(Document):
|
class LMSCertificateRequest(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_if_existing_requests()
|
self.validate_if_existing_requests()
|
||||||
|
self.validate_evaluation_date()
|
||||||
|
|
||||||
def validate_if_existing_requests(self):
|
def validate_if_existing_requests(self):
|
||||||
existing_requests = frappe.get_all(
|
existing_requests = frappe.get_all(
|
||||||
@@ -32,6 +33,20 @@ class LMSCertificateRequest(Document):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def validate_evaluation_date(self):
|
||||||
|
if self.batch_name:
|
||||||
|
evaluation_end_date = frappe.db.get_value(
|
||||||
|
"LMS Batch", self.batch_name, "evaluation_end_date"
|
||||||
|
)
|
||||||
|
|
||||||
|
if evaluation_end_date:
|
||||||
|
if getdate(self.date) > getdate(evaluation_end_date):
|
||||||
|
frappe.throw(
|
||||||
|
_("You cannot schedule evaluations after {0}.").format(
|
||||||
|
format_date(evaluation_end_date, "medium")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def schedule_evals():
|
def schedule_evals():
|
||||||
if frappe.db.get_single_value("LMS Settings", "send_calendar_invite_for_evaluations"):
|
if frappe.db.get_single_value("LMS Settings", "send_calendar_invite_for_evaluations"):
|
||||||
@@ -104,7 +119,9 @@ def update_meeting_details(eval, event, calendar):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create_certificate_request(course, date, day, start_time, end_time, batch=None):
|
def create_certificate_request(
|
||||||
|
course, date, day, start_time, end_time, batch_name=None
|
||||||
|
):
|
||||||
is_member = frappe.db.exists(
|
is_member = frappe.db.exists(
|
||||||
{"doctype": "LMS Enrollment", "course": course, "member": frappe.session.user}
|
{"doctype": "LMS Enrollment", "course": course, "member": frappe.session.user}
|
||||||
)
|
)
|
||||||
@@ -115,13 +132,13 @@ def create_certificate_request(course, date, day, start_time, end_time, batch=No
|
|||||||
eval.update(
|
eval.update(
|
||||||
{
|
{
|
||||||
"course": course,
|
"course": course,
|
||||||
"evaluator": get_evaluator(course, batch),
|
"evaluator": get_evaluator(course, batch_name),
|
||||||
"member": frappe.session.user,
|
"member": frappe.session.user,
|
||||||
"date": date,
|
"date": date,
|
||||||
"day": day,
|
"day": day,
|
||||||
"start_time": start_time,
|
"start_time": start_time,
|
||||||
"end_time": end_time,
|
"end_time": end_time,
|
||||||
"batch": batch,
|
"batch_name": batch_name,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
eval.save(ignore_permissions=True)
|
eval.save(ignore_permissions=True)
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"message": "{% set title = frappe.db.get_value(\"LMS Course\", doc.course, \"title\") %}\n\n<p> {{ _(\"Hey {0}\").format(doc.member_name) }} </p>\n<p> {{ _('Your evaluation for the course {0} has been scheduled on {1} at {2}.').format(title, frappe.utils.format_date(doc.date, \"medium\"), frappe.utils.format_time(doc.start_time, \"short\")) }}</p>\n<p> {{ _(\"Please prepare well and be on time for the evaluations.\") }} </p>\n",
|
"message": "{% set title = frappe.db.get_value(\"LMS Course\", doc.course, \"title\") %}\n\n<p> {{ _(\"Hey {0}\").format(doc.member_name) }} </p>\n<p> {{ _('Your evaluation for the course {0} has been scheduled on {1} at {2}.').format(title, frappe.utils.format_date(doc.date, \"medium\"), frappe.utils.format_time(doc.start_time, \"short\")) }}</p>\n<p> {{ _(\"Please prepare well and be on time for the evaluations.\") }} </p>\n",
|
||||||
"modified": "2023-02-28 19:53:47.716135",
|
"message_type": "HTML",
|
||||||
|
"modified": "2023-11-29 17:34:54.514031",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "Certificate Request Creation",
|
"name": "Certificate Request Creation",
|
||||||
@@ -27,4 +28,4 @@
|
|||||||
"send_system_notification": 0,
|
"send_system_notification": 0,
|
||||||
"send_to_all_assignees": 0,
|
"send_to_all_assignees": 0,
|
||||||
"subject": "Your evaluation slot has been booked"
|
"subject": "Your evaluation slot has been booked"
|
||||||
}
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
<p> {{ _("Please prepare well and be on time for the evaluations.") }} </p>
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{% set title = frappe.db.get_value("LMS Course", doc.course, "title") %}
|
{% set title = frappe.db.get_value("LMS Course", doc.course, "title") %}
|
||||||
|
|
||||||
<p> {{ _("Hey {0}").format(doc.member_name) }} </p>
|
<p> {{ _('Your evaluation for the course ${0} has been scheduled on ${1} at ${2}.').format(title, frappe.utils.format_date(doc.date, "medium"), frappe.utils.format_time(doc.start_time, "short")) }}</p>
|
||||||
<p> {{ _('Your evaluation for the course {0} has been scheduled on {1} at {2}.').format(title, frappe.utils.format_date(doc.date, "medium"), frappe.utils.format_time(doc.start_time, "short")) }}</p>
|
|
||||||
<p> {{ _("Please prepare well and be on time for the evaluations.") }} </p>
|
<p> {{ _("Please prepare well and be on time for the evaluations.") }} </p>
|
||||||
|
|||||||
@@ -11,8 +11,9 @@
|
|||||||
"event": "Days Before",
|
"event": "Days Before",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"message": "{% set title = frappe.db.get_value(\"LMS Course\", doc.course, \"title\") %}\n<p> {{ _('Your evaluation for the course ${0} has been scheduled on ${1} at ${2}.').format(title, frappe.utils.format_date(doc.date, \"medium\"), frappe.utils.format_time(doc.start_time, \"short\")) }}</p>\n<p> {{ _(\"Please prepare well and be on time for the evaluations.\") }} </p>\n",
|
"message": "{% set title = frappe.db.get_value(\"LMS Course\", doc.course, \"title\") %}\n\n<p> {{ _('Your evaluation for the course ${0} has been scheduled on ${1} at ${2}.').format(title, frappe.utils.format_date(doc.date, \"medium\"), frappe.utils.format_time(doc.start_time, \"short\")) }}</p>\n\n<p> {{ _(\"Please prepare well and be on time for the evaluations.\") }} </p>\n",
|
||||||
"modified": "2022-06-03 11:51:02.681803",
|
"message_type": "HTML",
|
||||||
|
"modified": "2023-11-29 17:26:53.355501",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "Certificate Request Reminder",
|
"name": "Certificate Request Reminder",
|
||||||
@@ -20,6 +21,9 @@
|
|||||||
"recipients": [
|
"recipients": [
|
||||||
{
|
{
|
||||||
"receiver_by_document_field": "member"
|
"receiver_by_document_field": "member"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"receiver_by_document_field": "evaluator"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"send_system_notification": 0,
|
"send_system_notification": 0,
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
{% set title = frappe.db.get_value("LMS Course", doc.course, "title") %}
|
|
||||||
<p> {{ _('Your evaluation for the course ${0} has been scheduled on ${1} at ${2}.').format(title, frappe.utils.format_date(doc.date, "medium"), frappe.utils.format_time(doc.start_time, "short")) }}</p>
|
|
||||||
<p> {{ _("Please prepare well and be on time for the evaluations.") }} </p>
|
|
||||||
@@ -2482,4 +2482,8 @@ select {
|
|||||||
|
|
||||||
.text-color {
|
.text-color {
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toastui-calendar-weekday-event-block {
|
||||||
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
@@ -267,15 +267,6 @@ const open_batch_dialog = () => {
|
|||||||
fieldname: "published",
|
fieldname: "published",
|
||||||
default: batch_info && batch_info.published,
|
default: batch_info && batch_info.published,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
fieldtype: "Column Break",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldtype: "Int",
|
|
||||||
label: __("Seat Count"),
|
|
||||||
fieldname: "seat_count",
|
|
||||||
default: batch_info && batch_info.seat_count,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
fieldtype: "Section Break",
|
fieldtype: "Section Break",
|
||||||
},
|
},
|
||||||
@@ -293,13 +284,6 @@ const open_batch_dialog = () => {
|
|||||||
reqd: 1,
|
reqd: 1,
|
||||||
default: batch_info && batch_info.end_date,
|
default: batch_info && batch_info.end_date,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
fieldtype: "Select",
|
|
||||||
label: __("Medium"),
|
|
||||||
fieldname: "medium",
|
|
||||||
options: ["Online", "Offline"],
|
|
||||||
default: (batch_info && batch_info.medium) || "Online",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
fieldtype: "Column Break",
|
fieldtype: "Column Break",
|
||||||
},
|
},
|
||||||
@@ -317,6 +301,16 @@ const open_batch_dialog = () => {
|
|||||||
default: batch_info && batch_info.end_time,
|
default: batch_info && batch_info.end_time,
|
||||||
reqd: 1,
|
reqd: 1,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
fieldtype: "Section Break",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldtype: "Select",
|
||||||
|
label: __("Medium"),
|
||||||
|
fieldname: "medium",
|
||||||
|
options: ["Online", "Offline"],
|
||||||
|
default: (batch_info && batch_info.medium) || "Online",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
fieldtype: "Link",
|
fieldtype: "Link",
|
||||||
label: __("Category"),
|
label: __("Category"),
|
||||||
@@ -325,6 +319,21 @@ const open_batch_dialog = () => {
|
|||||||
only_select: 1,
|
only_select: 1,
|
||||||
default: batch_info && batch_info.category,
|
default: batch_info && batch_info.category,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
fieldtype: "Column Break",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldtype: "Int",
|
||||||
|
label: __("Seat Count"),
|
||||||
|
fieldname: "seat_count",
|
||||||
|
default: batch_info && batch_info.seat_count,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldtype: "Date",
|
||||||
|
label: __("Evaluation End Date"),
|
||||||
|
fieldname: "evaluation_end_date",
|
||||||
|
default: batch_info && batch_info.evaluation_end_date,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
fieldtype: "Section Break",
|
fieldtype: "Section Break",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -639,6 +639,7 @@
|
|||||||
let courses = {{ course_list | json }};
|
let courses = {{ course_list | json }};
|
||||||
const legends = {{ legends | json }};
|
const legends = {{ legends | json }};
|
||||||
const allow_future = {{ batch_info.allow_future }}
|
const allow_future = {{ batch_info.allow_future }}
|
||||||
|
const evaluation_end_date = "{{ batch_info.evaluation_end_date if batch_info.evaluation_end_date else '' }}"
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://uicdn.toast.com/calendar/latest/toastui-calendar.min.css" />
|
<link rel="stylesheet" href="https://uicdn.toast.com/calendar/latest/toastui-calendar.min.css" />
|
||||||
|
|||||||
@@ -530,6 +530,9 @@ const open_evaluation_form = (e) => {
|
|||||||
min_date: new Date(
|
min_date: new Date(
|
||||||
frappe.datetime.add_days(frappe.datetime.get_today(), 1)
|
frappe.datetime.add_days(frappe.datetime.get_today(), 1)
|
||||||
),
|
),
|
||||||
|
max_date: evaluation_end_date
|
||||||
|
? new Date(evaluation_end_date)
|
||||||
|
: "",
|
||||||
change: () => {
|
change: () => {
|
||||||
if (this.eval_form.get_value("date")) get_slots();
|
if (this.eval_form.get_value("date")) get_slots();
|
||||||
},
|
},
|
||||||
@@ -691,7 +694,11 @@ const get_calendar_options = (element, calendar_id) => {
|
|||||||
template: {
|
template: {
|
||||||
time: function (event) {
|
time: function (event) {
|
||||||
let hide = event.raw.completed ? "" : "hide";
|
let hide = event.raw.completed ? "" : "hide";
|
||||||
return `<div class="calendar-event-time">
|
return `<div class="calendar-event-time" title="${
|
||||||
|
event.title
|
||||||
|
} - ${frappe.datetime.get_time(
|
||||||
|
event.start.d.d
|
||||||
|
)} - ${frappe.datetime.get_time(event.end.d.d)}">
|
||||||
<img class='icon icon-sm pull-right ${hide}' src="/assets/lms/icons/check.svg">
|
<img class='icon icon-sm pull-right ${hide}' src="/assets/lms/icons/check.svg">
|
||||||
<div> ${frappe.datetime.get_time(event.start.d.d)} -
|
<div> ${frappe.datetime.get_time(event.start.d.d)} -
|
||||||
${frappe.datetime.get_time(event.end.d.d)} </div>
|
${frappe.datetime.get_time(event.end.d.d)} </div>
|
||||||
@@ -736,6 +743,7 @@ const create_events = (calendar, events, calendar_id) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const format_time = (time) => {
|
const format_time = (time) => {
|
||||||
|
if (!time) return "00:00:00";
|
||||||
let time_arr = time.split(":");
|
let time_arr = time.split(":");
|
||||||
if (time_arr[0] < 10) time_arr[0] = "0" + time_arr[0];
|
if (time_arr[0] < 10) time_arr[0] = "0" + time_arr[0];
|
||||||
return time_arr.join(":");
|
return time_arr.join(":");
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ def get_context(context):
|
|||||||
"batch_details",
|
"batch_details",
|
||||||
"published",
|
"published",
|
||||||
"allow_future",
|
"allow_future",
|
||||||
|
"evaluation_end_date",
|
||||||
],
|
],
|
||||||
as_dict=True,
|
as_dict=True,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ def get_context(context):
|
|||||||
"published",
|
"published",
|
||||||
"meta_image",
|
"meta_image",
|
||||||
"batch_details_raw",
|
"batch_details_raw",
|
||||||
|
"evaluation_end_date",
|
||||||
],
|
],
|
||||||
as_dict=1,
|
as_dict=1,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user