fix: renamed class to batch

This commit is contained in:
Jannat Patel
2023-08-28 10:59:52 +05:30
parent 9376b0b010
commit 27101ffd31
40 changed files with 406 additions and 383 deletions

View File

@@ -152,7 +152,7 @@ website_route_rules = [
},
{"from_route": "/quizzes", "to_route": "batch/quiz_list"},
{"from_route": "/quizzes/<quizname>", "to_route": "batch/quiz"},
{"from_route": "/classes/<classname>", "to_route": "classes/class"},
{"from_route": "/batches/<batchname>", "to_route": "batches/batch"},
{"from_route": "/courses/<course>/progress", "to_route": "batch/progress"},
{"from_route": "/courses/<course>/join", "to_route": "batch/join"},
{"from_route": "/courses/<course>/manage", "to_route": "cohorts"},
@@ -176,8 +176,8 @@ website_route_rules = [
{"from_route": "/users", "to_route": "profiles/profile"},
{"from_route": "/jobs/<job>", "to_route": "jobs/job"},
{
"from_route": "/classes/<classname>/students/<username>",
"to_route": "/classes/progress",
"from_route": "/batches/<batchname>/students/<username>",
"to_route": "/batches/progress",
},
{"from_route": "/assignments/<assignment>", "to_route": "assignments/assignment"},
{
@@ -193,8 +193,8 @@ website_route_rules = [
"to_route": "billing/billing",
},
{
"from_route": "/classes/details/<classname>",
"to_route": "classes/class_details",
"from_route": "/batches/details/<batchname>",
"to_route": "batches/batch_details",
},
]

View File

@@ -38,10 +38,10 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2023-07-13 17:51:36.278393",
"modified": "2023-08-28 10:03:02.960844",
"modified_by": "Administrator",
"module": "LMS",
"name": "Class Course",
"name": "Batch Course",
"naming_rule": "Autoincrement",
"owner": "Administrator",
"permissions": [],

View File

@@ -5,5 +5,5 @@
from frappe.model.document import Document
class ClassCourse(Document):
class BatchCourse(Document):
pass

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2022, Frappe and contributors
// For license information, please see license.txt
frappe.ui.form.on("Class Student", {
frappe.ui.form.on("Batch Student", {
// refresh: function(frm) {
// }
});

View File

@@ -60,7 +60,7 @@
"modified": "2023-08-24 17:48:53.045539",
"modified_by": "Administrator",
"module": "LMS",
"name": "Class Student",
"name": "Batch Student",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",

View File

@@ -5,5 +5,5 @@
from frappe.model.document import Document
class ClassStudent(Document):
class BatchStudent(Document):
pass

View File

@@ -5,5 +5,5 @@
from frappe.tests.utils import FrappeTestCase
class TestClassStudent(FrappeTestCase):
class TestBatchStudent(FrappeTestCase):
pass

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2022, Frappe and contributors
// For license information, please see license.txt
frappe.ui.form.on("LMS Class", {
frappe.ui.form.on("LMS Batch", {
onload: function (frm) {
frm.set_query("student", "students", function (doc) {
return {
@@ -15,7 +15,7 @@ frappe.ui.form.on("LMS Class", {
fetch_lessons: (frm) => {
frm.clear_table("scheduled_flow");
frappe.call({
method: "lms.lms.doctype.lms_class.lms_class.fetch_lessons",
method: "lms.lms.doctype.lms_batch.lms_batch.fetch_lessons",
args: {
courses: frm.doc.courses,
},

View File

@@ -21,11 +21,11 @@
"seat_count",
"section_break_6",
"description",
"class_details",
"batch_details",
"students",
"courses",
"section_break_gsac",
"paid_class",
"paid_batch",
"column_break_iens",
"amount",
"currency",
@@ -70,13 +70,13 @@
"fieldname": "students",
"fieldtype": "Table",
"label": "Students",
"options": "Class Student"
"options": "Batch Student"
},
{
"fieldname": "courses",
"fieldtype": "Table",
"label": "Courses",
"options": "Class Course"
"options": "Batch Course"
},
{
"fieldname": "start_date",
@@ -86,7 +86,7 @@
"reqd": 1
},
{
"description": "The HTML code entered here will be displayed on the class details page.",
"description": "The HTML code entered here will be displayed on the batch details page.",
"fieldname": "custom_component",
"fieldtype": "Code",
"label": "Custom Component",
@@ -94,10 +94,10 @@
},
{
"default": "0",
"description": "Students will be enrolled in a paid class once they complete the payment",
"fieldname": "paid_class",
"description": "Students will be enrolled in a paid batch once they complete the payment",
"fieldname": "paid_batch",
"fieldtype": "Check",
"label": "Paid Class"
"label": "Paid Batch"
},
{
"fieldname": "seat_count",
@@ -175,22 +175,22 @@
"fieldtype": "Column Break"
},
{
"depends_on": "paid_class",
"depends_on": "paid_batch",
"fieldname": "amount",
"fieldtype": "Currency",
"label": "Amount"
},
{
"depends_on": "paid_class",
"depends_on": "paid_batch",
"fieldname": "currency",
"fieldtype": "Link",
"label": "Currency",
"options": "Currency"
},
{
"fieldname": "class_details",
"fieldname": "batch_details",
"fieldtype": "Text Editor",
"label": "Class Details",
"label": "Batch Details",
"reqd": 1
}
],
@@ -199,7 +199,7 @@
"modified": "2023-08-23 17:35:42.750754",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Class",
"name": "LMS Batch",
"naming_rule": "Expression (old style)",
"owner": "Administrator",
"permissions": [

View File

@@ -11,7 +11,7 @@ from frappe.utils import cint, format_date, format_datetime
from lms.lms.utils import get_lessons
class LMSClass(Document):
class LMSBatch(Document):
def validate(self):
if self.seat_count:
self.validate_seats_left()
@@ -26,7 +26,7 @@ class LMSClass(Document):
duplicates = {student for student in students if students.count(student) > 1}
if len(duplicates):
frappe.throw(
_("Student {0} has already been added to this class.").format(
_("Student {0} has already been added to this batch.").format(
frappe.bold(next(iter(duplicates)))
)
)
@@ -37,7 +37,7 @@ class LMSClass(Document):
if len(duplicates):
title = frappe.db.get_value("LMS Course", next(iter(duplicates)), "title")
frappe.throw(
_("Course {0} has already been added to this class.").format(frappe.bold(title))
_("Course {0} has already been added to this batch.").format(frappe.bold(title))
)
def validate_duplicate_assessments(self):
@@ -48,7 +48,7 @@ class LMSClass(Document):
assessment.assessment_type, assessment.assessment_name, "title"
)
frappe.throw(
_("Assessment {0} has already been added to this class.").format(
_("Assessment {0} has already been added to this batch.").format(
frappe.bold(title)
)
)
@@ -66,7 +66,7 @@ class LMSClass(Document):
def validate_seats_left(self):
if cint(self.seat_count) < len(self.students):
frappe.throw(_("There are no seats available in this class."))
frappe.throw(_("There are no seats available in this batch."))
def validate_schedule(self):
for schedule in self.scheduled_flow:
@@ -82,32 +82,32 @@ class LMSClass(Document):
if schedule.start_time < self.start_time or schedule.start_time > self.end_time:
frappe.throw(
_("Row #{0} Start time cannot be outside the class duration.").format(
_("Row #{0} Start time cannot be outside the batch duration.").format(
schedule.idx
)
)
if schedule.end_time < self.start_time or schedule.end_time > self.end_time:
frappe.throw(
_("Row #{0} End time cannot be outside the class duration.").format(schedule.idx)
_("Row #{0} End time cannot be outside the batch duration.").format(schedule.idx)
)
if schedule.date < self.start_date or schedule.date > self.end_date:
frappe.throw(
_("Row #{0} Date cannot be outside the class duration.").format(schedule.idx)
_("Row #{0} Date cannot be outside the batch duration.").format(schedule.idx)
)
@frappe.whitelist()
def remove_student(student, class_name):
def remove_student(student, batch_name):
frappe.only_for("Moderator")
frappe.db.delete("Class Student", {"student": student, "parent": class_name})
frappe.db.delete("Batch Student", {"student": student, "parent": batch_name})
@frappe.whitelist()
def remove_course(course, parent):
frappe.only_for("Moderator")
frappe.db.delete("Class Course", {"course": course, "parent": parent})
frappe.db.delete("Batch Course", {"course": course, "parent": parent})
@frappe.whitelist()
@@ -118,7 +118,7 @@ def remove_assessment(assessment, parent):
@frappe.whitelist()
def create_live_class(
class_name, title, duration, date, time, timezone, auto_recording, description=None
batch_name, title, duration, date, time, timezone, auto_recording, description=None
):
date = format_date(date, "yyyy-mm-dd", True)
frappe.only_for("Moderator")
@@ -152,7 +152,7 @@ def create_live_class(
"host": frappe.session.user,
"date": date,
"time": time,
"class_name": class_name,
"batch_name": batch_name,
"password": data.get("password"),
"description": description,
"auto_recording": auto_recording,
@@ -186,27 +186,27 @@ def authenticate():
@frappe.whitelist()
def create_class(
def create_batch(
title,
start_date,
end_date,
description=None,
class_details=None,
batch_details=None,
seat_count=0,
start_time=None,
end_time=None,
medium="Online",
category=None,
paid_class=0,
paid_batch=0,
amount=0,
currency=None,
name=None,
):
frappe.only_for("Moderator")
if name:
doc = frappe.get_doc("LMS Class", name)
doc = frappe.get_doc("LMS Batch", name)
else:
doc = frappe.get_doc({"doctype": "LMS Class"})
doc = frappe.get_doc({"doctype": "LMS Batch"})
doc.update(
{
@@ -214,13 +214,13 @@ def create_class(
"start_date": start_date,
"end_date": end_date,
"description": description,
"class_details": class_details,
"batch_details": batch_details,
"seat_count": seat_count,
"start_time": start_time,
"end_time": end_time,
"medium": medium,
"category": category,
"paid_class": paid_class,
"paid_batch": paid_batch,
"amount": amount,
"currency": currency,
}

View File

@@ -11,7 +11,7 @@
"column_break_3",
"issue_date",
"expiry_date",
"class_name"
"batch_name"
],
"fields": [
{
@@ -55,16 +55,16 @@
"read_only": 1
},
{
"fieldname": "class_name",
"fieldname": "batch_name",
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Class Name",
"options": "LMS Class"
"label": "Batch Name",
"options": "LMS Batch"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-08-23 14:48:49.351394",
"modified": "2023-08-23 14:48:49.351395",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Certificate",

View File

@@ -13,7 +13,7 @@
"date",
"start_time",
"end_time",
"class_name",
"batch_name",
"section_break_6",
"rating",
"status",
@@ -97,16 +97,16 @@
"fieldtype": "Column Break"
},
{
"fieldname": "class_name",
"fieldname": "batch_name",
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Class Name",
"options": "LMS Class"
"label": "Batch Name",
"options": "LMS Batch"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-08-23 14:51:21.947160",
"modified": "2023-08-23 14:51:21.947169",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Certificate Evaluation",

View File

@@ -8,7 +8,7 @@
"field_order": [
"course",
"evaluator",
"class_name",
"batch_name",
"column_break_4",
"member",
"member_name",
@@ -100,16 +100,16 @@
"read_only": 1
},
{
"fieldname": "class_name",
"fieldname": "batch_name",
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Class Name",
"options": "LMS Class"
"label": "Batch Name",
"options": "LMS Batch"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-08-23 14:50:37.618350",
"modified": "2023-08-23 14:50:37.618352",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Certificate Request",

View File

@@ -9,7 +9,7 @@
"field_order": [
"title",
"host",
"class_name",
"batch_name",
"password",
"auto_recording",
"column_break_astv",
@@ -111,10 +111,10 @@
"reqd": 1
},
{
"fieldname": "class_name",
"fieldname": "batch_name",
"fieldtype": "Link",
"label": "Class",
"options": "LMS Class"
"label": "Batch",
"options": "LMS Batch"
},
{
"default": "No Recording",
@@ -126,7 +126,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-03-14 18:44:48.813102",
"modified": "2023-03-14 18:44:48.813103",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Live Class",

View File

@@ -34,7 +34,7 @@ class LMSLiveClass(Document):
def add_event_participants(self, event, calendar):
participants = frappe.get_all(
"Class Student", {"parent": self.class_name}, pluck="student"
"Batch Student", {"parent": self.class_name}, pluck="student"
)
participants.append(frappe.session.user)

View File

@@ -800,7 +800,7 @@ def get_evaluator(course, class_name=None):
if class_name:
evaluator = frappe.db.get_value(
"Class Course",
"Batch Course",
{"parent": class_name, "course": course},
"evaluator",
)
@@ -869,7 +869,7 @@ def get_details(doctype, docname):
frappe.throw(_("This course is free."))
else:
details = frappe.db.get_value(
"LMS Class",
"LMS Batch",
docname,
["name", "title", "paid_class", "currency", "amount"],
as_dict=True,
@@ -996,13 +996,13 @@ def create_membership(course, payment):
def add_student_to_class(classname, payment):
student = frappe.new_doc("Class Student")
student = frappe.new_doc("Batch Student")
student.update(
{
"student": frappe.session.user,
"payment": payment,
"parent": classname,
"parenttype": "LMS Class",
"parenttype": "LMS Batch",
"parentfield": "students",
}
)

View File

@@ -22,7 +22,7 @@
"login_required": 1,
"max_attachment_size": 0,
"meta_image": "/files/og_image_web_form_evaluation_68ddf18e.png",
"modified": "2023-08-23 14:37:03.086303",
"modified": "2023-08-23 14:37:03.086304",
"modified_by": "Administrator",
"module": "LMS",
"name": "evaluation",
@@ -63,13 +63,13 @@
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "class_name",
"fieldname": "batch_name",
"fieldtype": "Link",
"hidden": 0,
"label": "Class Name",
"label": "Batch Name",
"max_length": 0,
"max_value": 0,
"options": "LMS Class",
"options": "LMS Batch",
"read_only": 0,
"reqd": 0,
"show_in_filter": 0

View File

@@ -64,4 +64,5 @@ execute:frappe.permissions.reset_perms("LMS Certificate Evaluation")
lms.patches.v1_0.paid_certificate_to_paid_course #18-08-2023
lms.patches.v1_0.revert_class_registration #18-08-2023
lms.patches.v1_0.rename_lms_batch_doctype
lms.patches.v1_0.rename_lms_batch_membership_doctype
lms.patches.v1_0.rename_lms_batch_membership_doctype
lms.patches.v1_0.rename_lms_class_to_lms_batch

View File

@@ -0,0 +1,32 @@
import frappe
from frappe.model.rename_doc import rename_doc
def execute():
if frappe.db.exists("DocField", {"fieldname": "students", "parent": "LMS Batch"}):
return
rename_lms_class()
rename_class_student()
rename_class_courses()
def rename_lms_class():
frappe.flags.ignore_route_conflict_validation = True
rename_doc("DocType", "LMS Class", "LMS Batch")
frappe.flags.ignore_route_conflict_validation = False
frappe.reload_doctype("LMS Batch", force=True)
def rename_class_student():
frappe.flags.ignore_route_conflict_validation = True
rename_doc("DocType", "Class Student", "Batch Student")
frappe.flags.ignore_route_conflict_validation = False
frappe.reload_doctype("Batch Student", force=True)
def rename_class_courses():
frappe.flags.ignore_route_conflict_validation = True
rename_doc("DocType", "Class Course", "Batch Course")
frappe.flags.ignore_route_conflict_validation = False
frappe.reload_doctype("Batch Course", force=True)

View File

@@ -37,8 +37,8 @@ frappe.ready(() => {
show_no_preview_dialog(e);
});
$("#create-class").click((e) => {
open_class_dialog(e);
$("#create-batch").click((e) => {
open_batch_dialog(e);
});
$("#course-filter").change((e) => {
@@ -250,37 +250,37 @@ const show_no_preview_dialog = (e) => {
$("#no-preview-modal").modal("show");
};
const open_class_dialog = () => {
this.class_dialog = new frappe.ui.Dialog({
title: __("New Class"),
const open_batch_dialog = () => {
this.batch_dialog = new frappe.ui.Dialog({
title: __("New Batch"),
fields: [
{
fieldtype: "Data",
label: __("Title"),
fieldname: "title",
reqd: 1,
default: class_info && class_info.title,
default: batch_info && batch_info.title,
},
{
fieldtype: "Date",
label: __("Start Date"),
fieldname: "start_date",
reqd: 1,
default: class_info && class_info.start_date,
default: batch_info && batch_info.start_date,
},
{
fieldtype: "Date",
label: __("End Date"),
fieldname: "end_date",
reqd: 1,
default: class_info && class_info.end_date,
default: batch_info && batch_info.end_date,
},
{
fieldtype: "Select",
label: __("Medium"),
fieldname: "medium",
options: ["Online", "Offline"],
default: (class_info && class_info.medium) || "Online",
default: (batch_info && batch_info.medium) || "Online",
},
{
fieldtype: "Column Break",
@@ -289,26 +289,26 @@ const open_class_dialog = () => {
fieldtype: "Time",
label: __("Start Time"),
fieldname: "start_time",
default: class_info && class_info.start_time,
default: batch_info && batch_info.start_time,
},
{
fieldtype: "Time",
label: __("End Time"),
fieldname: "end_time",
default: class_info && class_info.end_time,
default: batch_info && batch_info.end_time,
},
{
fieldtype: "Int",
label: __("Seat Count"),
fieldname: "seat_count",
default: class_info && class_info.seat_count,
default: batch_info && batch_info.seat_count,
},
{
fieldtype: "Link",
label: __("Category"),
fieldname: "category",
options: "LMS Category",
default: class_info && class_info.category,
default: batch_info && batch_info.category,
},
{
fieldtype: "Section Break",
@@ -317,14 +317,14 @@ const open_class_dialog = () => {
fieldtype: "Small Text",
label: __("Description"),
fieldname: "description",
default: class_info && class_info.description,
default: batch_info && batch_info.description,
reqd: 1,
},
{
fieldtype: "Text Editor",
label: __("Class Details"),
fieldname: "class_details",
default: class_info && class_info.class_details,
label: __("Batch Details"),
fieldname: "batch_details",
default: batch_info && batch_info.batch_details,
reqd: 1,
},
{
@@ -334,57 +334,57 @@ const open_class_dialog = () => {
},
{
fieldtype: "Check",
label: __("Paid Class"),
fieldname: "paid_class",
default: class_info && class_info.paid_class,
label: __("Paid Batch"),
fieldname: "paid_batch",
default: batch_info && batch_info.paid_batch,
},
{
fieldtype: "Currency",
label: __("Amount"),
fieldname: "amount",
default: class_info && class_info.amount,
mandatory_depends_on: "paid_class",
depends_on: "paid_class",
default: batch_info && batch_info.amount,
mandatory_depends_on: "paid_batch",
depends_on: "paid_batch",
},
{
fieldtype: "Link",
label: __("Currency"),
fieldname: "currency",
options: "Currency",
default: class_info && class_info.currency,
mandatory_depends_on: "paid_class",
depends_on: "paid_class",
default: batch_info && batch_info.currency,
mandatory_depends_on: "paid_batch",
depends_on: "paid_batch",
only_select: 1,
},
],
primary_action_label: __("Save"),
primary_action: (values) => {
save_class(values);
save_batch(values);
},
});
this.class_dialog.show();
this.batch_dialog.show();
};
const save_class = (values) => {
const save_batch = (values) => {
let args = {};
if (class_info) {
args = Object.assign(class_info, values);
if (batch_info) {
args = Object.assign(batch_info, values);
} else {
args = values;
}
frappe.call({
method: "lms.lms.doctype.lms_class.lms_class.create_class",
method: "lms.lms.doctype.lms_batch.lms_batch.create_batch",
args: args,
callback: (r) => {
if (r.message) {
frappe.show_alert({
message: class_info
? __("Class Updated")
: __("Class Created"),
message: batch_info
? __("Batch Updated")
: __("Batch Created"),
indicator: "green",
});
this.class_dialog.hide();
window.location.href = `/classes/details/${r.message.name}`;
this.batch_dialog.hide();
window.location.href = `/batches/details/${r.message.name}`;
}
},
});

View File

@@ -21,7 +21,7 @@ def get_context(context):
context.class_info = frappe._dict(
{
"name": class_name,
"title": frappe.db.get_value("LMS Class", class_name, "title"),
"title": frappe.db.get_value("LMS Batch", class_name, "title"),
}
)

View File

@@ -1,16 +1,16 @@
{% extends "lms/templates/lms_base.html" %}
{% block title %}
{{ _(class_info.title) }}
{{ _(batch_info.title) }}
{% endblock %}
{% block page_content %}
<div class="common-page-style lms-page-style">
<div class="container">
{{ BreadCrumb(class_info) }}
{{ BreadCrumb(batch_info) }}
<div class="">
{{ ClassDetails(class_info) }}
{{ ClassSections(class_info, class_courses, class_students, flow) }}
{{ BatchDetails(batch_info) }}
{{ BatchSections(batch_info, batch_courses, batch_students, flow) }}
</div>
</div>
</div>
@@ -18,26 +18,26 @@
<!-- BreadCrumb -->
{% macro BreadCrumb(class_info) %}
{% macro BreadCrumb(batch_info) %}
<div class="breadcrumb">
<a class="dark-links" href="/classes">{{ _("All Classes") }}</a>
<a class="dark-links" href="/batches">{{ _("All Batches") }}</a>
<img class="ml-1 mr-1" src="/assets/lms/icons/chevron-right.svg">
<span class="breadcrumb-destination">{{ class_info.title }}</span>
<span class="breadcrumb-destination">{{ batch_info.title }}</span>
</div>
{% endmacro %}
<!-- Class Details -->
{% macro ClassDetails(class_info) %}
<div class="class-details" data-class="{{ class_info.name }}">
<!-- Batch Details -->
{% macro BatchDetails(batch_info) %}
<div class="class-details" data-batch="{{ batch_info.name }}">
<div class="page-title">
{{ class_info.title }}
{{ batch_info.title }}
</div>
{% if class_info.description %}
{% if batch_info.description %}
<div class="mb-4">
{{ class_info.description }}
{{ batch_info.description }}
</div>
{% endif %}
@@ -47,10 +47,10 @@
<use href="#icon-calendar"></use>
</svg>
<span>
{{ frappe.utils.format_date(class_info.start_date, "long") }} -
{{ frappe.utils.format_date(batch_info.start_date, "long") }} -
</span>
<span>
{{ frappe.utils.format_date(class_info.end_date, "long") }}
{{ frappe.utils.format_date(batch_info.end_date, "long") }}
</span>
</div>
@@ -60,7 +60,7 @@
<svg class="icon icon-md">
<use href="#icon-education"></use>
</svg>
{{ class_courses | length }} {{ _("Courses") }}
{{ batch_courses | length }} {{ _("Courses") }}
</div>
<span class="seperator"></span>
@@ -69,23 +69,22 @@
<svg class="icon icon-md">
<use href="#icon-users"></use>
</svg>
{{ class_students | length }} {{ _("Students") }}
{{ batch_students | length }} {{ _("Students") }}
</div>
</div>
{% if class_info.custom_component %}
{{ class_info.custom_component }}
{% if batch_info.custom_component %}
{{ batch_info.custom_component }}
{% endif %}
</div>
{% endmacro %}
<!-- Class Sections -->
{% macro ClassSections(class_info, class_courses, class_students, flow) %}
{% macro BatchSections(batch_info, batch_courses, batch_students, flow) %}
<div class="mt-4">
<ul class="nav lms-nav" id="classes-tab">
<ul class="nav lms-nav" id="batches-tab">
{% if is_student %}
<li class="nav-item">
@@ -99,7 +98,7 @@
<a class="nav-link {% if not is_student %} active {% endif %}" data-toggle="tab" href="#courses">
{{ _("Courses") }}
<span class="course-list-count">
{{ class_courses | length }}
{{ batch_courses | length }}
</span>
</a>
</li>
@@ -119,7 +118,7 @@
<a class="nav-link" data-toggle="tab" href="#students">
{{ _("Students") }}
<span class="course-list-count">
{{ class_students | length }}
{{ batch_students | length }}
</span>
</a>
</li>
@@ -135,7 +134,7 @@
</li>
{% endif %}
{% if class_students | length and (is_moderator or is_student) %}
{% if batch_students | length and (is_moderator or is_student) %}
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#discussions">
{{ _("Discussions") }}
@@ -160,12 +159,12 @@
{% if is_student %}
<div class="tab-pane {% if is_student %} active {% endif %}" id="dashboard" role="tabpanel" aria-labelledby="dashboard">
{{ Dashboard(class_info, class_courses, current_student) }}
{{ Dashboard(batch_info, batch_courses, current_student) }}
</div>
{% endif %}
<div class="tab-pane {% if not is_student %} active {% endif %}" id="courses" role="tabpanel" aria-labelledby="courses">
{{ CoursesSection(class_info, class_courses) }}
{{ CoursesSection(batch_info, batch_courses) }}
</div>
{% if flow | length %}
@@ -175,22 +174,22 @@
{% endif %}
<div class="tab-pane" id="students" role="tabpanel" aria-labelledby="students">
{{ StudentsSection(class_info, class_students) }}
{{ StudentsSection(batch_info, batch_students) }}
</div>
{% if is_moderator %}
<div class="tab-pane" id="assessments" role="tabpanel" aria-labelledby="assessments">
{{ AssessmentsSection(class_info) }}
{{ AssessmentsSection(batch_info) }}
</div>
{% endif %}
{% if class_students | length and (is_moderator or is_student or is_evaluator) %}
{% if batch_students | length and (is_moderator or is_student or is_evaluator) %}
<div class="tab-pane" id="discussions" role="tabpanel" aria-labelledby="discussions">
{{ Discussions(class_info) }}
{{ Discussions(batch_info) }}
</div>
<div class="tab-pane" id="live-class" role="tabpanel" aria-labelledby="live-class">
{{ LiveClassSection(class_info, live_classes) }}
{{ LiveClassSection(batch_info, live_classes) }}
</div>
{% endif %}
@@ -198,7 +197,7 @@
</div>
{% endmacro %}
{% macro Dashboard(class_info, class_courses, current_student) %}
{% macro Dashboard(batch_info, batch_courses, current_student) %}
{% set upcoming_evals = current_student.upcoming_evals %}
{% set assessments = current_student.assessments %}
@@ -218,22 +217,22 @@
</div>
{% endmacro %}
{% macro Discussions(class_info) %}
{% macro Discussions(batch_info) %}
<article class="class-discussion">
{% set condition = is_moderator or is_student or is_evaluator %}
{% set doctype, docname = _("LMS Class"), class_info.name %}
{% set doctype, docname = _("LMS Batch"), batch_info.name %}
{% set single_thread = True %}
{% set title = "Discussions" %}
{% set cta_title = "Post" %}
{% set button_name = _("Start Learning") %}
{% set redirect_to = "/classes/" + class_info.name %}
{% set redirect_to = "/batches/" + batch_info.name %}
{% set empty_state_title = _("Have a doubt?") %}
{% set empty_state_subtitle = _("Post it here, our mentors will help you out.") %}
{% include "frappe/templates/discussions/discussions_section.html" %}
</article>
{% endmacro %}
{% macro CoursesSection(class_info, class_courses) %}
{% macro CoursesSection(batch_info, batch_courses) %}
<article>
<header class="mb-5">
<div class="edit-header">
@@ -248,9 +247,9 @@
</div>
</header>
{% if class_courses | length %}
{% if batch_courses | length %}
<div class="cards-parent">
{% for course in class_courses %}
{% for course in batch_courses %}
<div class="h-100">
{{ widgets.CourseCard(course=course, read_only=False) }}
<button class="btn icon-btn btn-default btn-block btn-remove-course" data-course="{{ course.name }}">
@@ -272,7 +271,7 @@
{% endmacro %}
{% macro StudentsSection(class_info, class_students) %}
{% macro StudentsSection(batch_info, batch_students) %}
<article>
<header>
<div class="edit-header mb-5">
@@ -287,7 +286,7 @@
</div>
</header>
{% if class_students | length %}
{% if batch_students | length %}
<div class="form-grid">
<div class="grid-heading-row">
<div class="grid-row">
@@ -317,11 +316,11 @@
</div>
</div>
</div>
{% for student in class_students %}
{% for student in batch_students %}
{% set allow_progress = is_moderator or is_evaluator %}
<div class="grid-row">
<div class="data-row row">
<a class="col grid-static-col button-links {% if allow_progress %} clickable {% endif %}" {% if allow_progress %} href="/classes/{{ class_info.name }}/students/{{ student.username }}" {% endif %}>
<a class="col grid-static-col button-links {% if allow_progress %} clickable {% endif %}" {% if allow_progress %} href="/classes/{{ batch_info.name }}/students/{{ student.username }}" {% endif %}>
{{ student.student_name }}
</a>
<div class="col grid-static-col col-xs-2 text-right">
@@ -354,7 +353,7 @@
{% endmacro %}
{% macro AssessmentsSection(class_info) %}
{% macro AssessmentsSection(batch_info) %}
<article>
<header class="edit-header mb-5">
<div class="bold-heading">
@@ -419,7 +418,7 @@
{% endmacro %}
{% macro LiveClassSection(class_info, live_classes) %}
{% macro LiveClassSection(batch_info, live_classes) %}
<article>
<header class="edit-header">
<div class="bold-heading">
@@ -431,13 +430,13 @@
</button>
{% endif %}
</header>
{{ CreateLiveClass(class_info) }}
{{ LiveClassList(class_info, live_classes) }}
{{ CreateLiveClass(batch_info) }}
{{ LiveClassList(batch_info, live_classes) }}
</div>
{% endmacro %}
{% macro CreateLiveClass(class_info) %}
{% macro CreateLiveClass(batch_info) %}
{% if is_moderator %}
<div class="modal fade live-class-modal" id="live-class-modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
@@ -468,7 +467,7 @@
{% endmacro %}
{% macro LiveClassList(class_info, live_classes) %}
{% macro LiveClassList(batch_info, live_classes) %}
<div class="lms-card-parent mt-5">
{% if live_classes | length %}
{% for class in live_classes %}

View File

@@ -55,7 +55,7 @@ frappe.ready(() => {
});
const create_live_class = (e) => {
let class_name = $(".class-details").data("class");
let class_name = $(".class-details").data("batch");
frappe.call({
method: "lms.lms.doctype.lms_class.lms_class.create_live_class",
args: {
@@ -337,11 +337,11 @@ const add_course = (values) => {
method: "frappe.client.insert",
args: {
doc: {
doctype: "Class Course",
doctype: "Batch Course",
course: values.course,
parenttype: "LMS Class",
parenttype: "LMS Batch",
parentfield: "courses",
parent: $(".class-details").data("class"),
parent: $(".class-details").data("batch"),
},
},
callback(r) {
@@ -363,7 +363,7 @@ const remove_course = (e) => {
method: "lms.lms.doctype.lms_class.lms_class.remove_course",
args: {
course: $(e.currentTarget).data("course"),
parent: $(".class-details").data("class"),
parent: $(".class-details").data("batch"),
},
callback(r) {
frappe.show_alert(
@@ -413,11 +413,11 @@ const add_student = (values) => {
method: "frappe.client.insert",
args: {
doc: {
doctype: "Class Student",
doctype: "Batch Student",
student: values.student,
parenttype: "LMS Class",
parenttype: "LMS Batch",
parentfield: "students",
parent: $(".class-details").data("class"),
parent: $(".class-details").data("batch"),
},
},
callback(r) {
@@ -441,7 +441,7 @@ const remove_student = (e) => {
method: "lms.lms.doctype.lms_class.lms_class.remove_student",
args: {
student: $(e.currentTarget).data("student"),
class_name: $(".class-details").data("class"),
class_name: $(".class-details").data("batch"),
},
callback: (data) => {
frappe.show_alert(
@@ -526,9 +526,9 @@ const add_addessment = (values) => {
doctype: "LMS Assessment",
assessment_type: values.assessment_type,
assessment_name: values.assessment_name,
parenttype: "LMS Class",
parenttype: "LMS Batch",
parentfield: "assessment",
parent: $(".class-details").data("class"),
parent: $(".class-details").data("batch"),
},
},
callback(r) {
@@ -550,7 +550,7 @@ const remove_assessment = (e) => {
method: "lms.lms.doctype.lms_class.lms_class.remove_assessment",
args: {
assessment: $(e.currentTarget).data("assessment"),
parent: $(".class-details").data("class"),
parent: $(".class-details").data("batch"),
},
callback(r) {
frappe.show_alert(
@@ -615,7 +615,7 @@ const get_slots = () => {
args: {
course: this.eval_form.get_value("course"),
date: this.eval_form.get_value("date"),
class_name: $(".class-details").data("class"),
class_name: $(".class-details").data("batch"),
},
callback: (r) => {
if (r.message) {
@@ -677,7 +677,7 @@ const submit_evaluation_form = (values) => {
start_time: this.current_slot.data("start"),
end_time: this.current_slot.data("end"),
day: this.current_slot.data("day"),
class_name: $(".class-details").data("class"),
class_name: $(".class-details").data("batch"),
},
callback: (r) => {
this.eval_form.hide();

View File

@@ -17,12 +17,12 @@ from lms.lms.utils import (
def get_context(context):
context.no_cache = 1
class_name = frappe.form_dict["classname"]
class_name = frappe.form_dict["batchname"]
context.is_moderator = has_course_moderator_role()
context.is_evaluator = has_course_evaluator_role()
context.class_info = frappe.db.get_value(
"LMS Class",
context.batch_info = frappe.db.get_value(
"LMS Batch",
class_name,
[
"name",
@@ -39,37 +39,37 @@ def get_context(context):
"paid_class",
"amount",
"currency",
"class_details",
"batch_details",
],
as_dict=True,
)
context.reference_doctype = "LMS Class"
context.reference_doctype = "LMS Batch"
context.reference_name = class_name
class_courses = frappe.get_all(
"Class Course",
batch_courses = frappe.get_all(
"Batch Course",
{"parent": class_name},
["name", "course", "title"],
order_by="creation desc",
)
class_students = frappe.get_all(
"Class Student",
batch_students = frappe.get_all(
"Batch Student",
{"parent": class_name},
["name", "student", "student_name", "username"],
order_by="creation desc",
)
context.class_courses = get_class_course_details(class_courses)
context.course_list = [course.course for course in context.class_courses]
context.batch_courses = get_class_course_details(batch_courses)
context.course_list = [course.course for course in context.batch_courses]
context.all_courses = frappe.get_all(
"LMS Course", fields=["name", "title"], limit_page_length=0
)
context.course_name_list = [course.course for course in context.class_courses]
context.course_name_list = [course.course for course in context.batch_courses]
context.assessments = get_assessments(class_name)
context.class_students = get_class_student_details(
class_students, class_courses, context.assessments
context.batch_students = get_class_student_details(
batch_students, batch_courses, context.assessments
)
context.is_student = is_student(class_name)
@@ -84,7 +84,7 @@ def get_context(context):
)
context.current_student = (
get_current_student_details(class_courses, class_name) if context.is_student else None
get_current_student_details(batch_courses, class_name) if context.is_student else None
)
context.all_assignments = get_all_assignments(class_name)
context.all_quizzes = get_all_quizzes(class_name)
@@ -121,8 +121,8 @@ def get_all_assignments(class_name):
return all_assignments
def get_class_course_details(class_courses):
for course in class_courses:
def get_class_course_details(batch_courses):
for course in batch_courses:
details = frappe.db.get_value(
"LMS Course",
course.course,
@@ -141,27 +141,27 @@ def get_class_course_details(class_courses):
as_dict=True,
)
course.update(details)
return class_courses
return batch_courses
def get_class_student_details(class_students, class_courses, assessments):
for student in class_students:
def get_class_student_details(batch_students, batch_courses, assessments):
for student in batch_students:
student.update(
frappe.db.get_value(
"User", student.student, ["name", "full_name", "username", "headline"], as_dict=1
)
)
student.update(frappe.db.get_value("User", student.student, "last_active", as_dict=1))
get_progress_info(student, class_courses)
get_progress_info(student, batch_courses)
get_assessment_info(student, assessments)
return sort_students(class_students)
return sort_students(batch_students)
def get_progress_info(student, class_courses):
def get_progress_info(student, batch_courses):
courses_completed = 0
student["courses"] = frappe._dict()
for course in class_courses:
for course in batch_courses:
membership = get_membership(course.course, student.student)
if membership and membership.progress == 100:
courses_completed += 1
@@ -193,11 +193,11 @@ def get_assessment_info(student, assessments):
return student
def sort_students(class_students):
def sort_students(batch_students):
session_user = []
remaining_students = []
for student in class_students:
for student in batch_students:
if student.student == frappe.session.user:
session_user.append(student)
else:
@@ -206,7 +206,7 @@ def sort_students(class_students):
if len(session_user):
return session_user + remaining_students
else:
return class_students
return batch_students
def get_scheduled_flow(class_name):
@@ -256,12 +256,12 @@ def get_lesson_details(lesson, class_name):
return lesson
def get_current_student_details(class_courses, class_name):
def get_current_student_details(batch_courses, class_name):
student_details = frappe._dict()
student_details.courses = frappe._dict()
course_list = [course.course for course in class_courses]
course_list = [course.course for course in batch_courses]
get_course_progress(class_courses, student_details)
get_course_progress(batch_courses, student_details)
student_details.name = frappe.session.user
student_details.assessments = get_assessments(class_name, frappe.session.user)
student_details.upcoming_evals = get_upcoming_evals(frappe.session.user, course_list)
@@ -269,8 +269,8 @@ def get_current_student_details(class_courses, class_name):
return student_details
def get_course_progress(class_courses, student_details):
for course in class_courses:
def get_course_progress(batch_courses, student_details):
for course in batch_courses:
membership = get_membership(course.course, frappe.session.user)
if membership:
student_details.courses[course.course] = membership.progress

View File

@@ -1,54 +1,54 @@
{% extends "lms/templates/lms_base.html" %}
{% block title %}
{{ _(class_info.title) }}
{{ _(batch_info.title) }}
{% endblock %}
{% block page_content %}
<div class="common-page-style lms-page-style">
{{ ClassHeader(class_info) }}
{{ BatchHeader(batch_info) }}
<div class="container">
{{ CourseHeaderOverlay(class_info, courses, students) }}
{{ BatchOverlay(batch_info, courses, students) }}
<div class="pt-10">
{{ ClassDetails(class_info) }}
{{ BatchDetails(batch_info) }}
{{ CourseList(courses) }}
</div>
</div>
</div>
{% endblock %}
{% macro ClassHeader(class_info) %}
{% macro BatchHeader(batch_info) %}
<div class="course-head-container">
<div class="container">
<div class="course-card-wide">
{{ BreadCrumb(class_info) }}
{{ ClassHeaderDetails(class_info, courses, students) }}
{{ BreadCrumb(batch_info) }}
{{ BatchHeaderDetails(batch_info, courses, students) }}
</div>
</div>
</div>
{% endmacro %}
{% macro BreadCrumb(class_info) %}
{% macro BreadCrumb(batch_info) %}
<article class="mb-8">
<a class="dark-links" href="/classes">
{{ _("All Classes") }}
<a class="dark-links" href="/batches">
{{ _("All Batches") }}
</a>
<img class="" src="/assets/lms/icons/chevron-right.svg">
<span class="breadcrumb-destination">
{{ _("Class Details") }}
{{ _("Batch Details") }}
</span>
</article>
{% endmacro %}
{% macro ClassHeaderDetails(class_info, courses, students) %}
<div class="class-details" data-class="{{ class_info.name }}">
{% macro BatchHeaderDetails(batch_info, courses, students) %}
<div class="class-details" data-batch="{{ batch_info.name }}">
<div class="page-title">
{{ class_info.title }}
{{ batch_info.title }}
</div>
<div class="">
{{ class_info.description }}
{{ batch_info.description }}
</div>
<div class="mt-8">
@@ -56,35 +56,35 @@
<use href="#icon-calendar"></use>
</svg>
<span>
{{ frappe.utils.format_date(class_info.start_date, "long") }} -
{{ frappe.utils.format_date(batch_info.start_date, "long") }} -
</span>
<span>
{{ frappe.utils.format_date(class_info.end_date, "long") }}
{{ frappe.utils.format_date(batch_info.end_date, "long") }}
</span>
</div>
{% if class_info.start_time and class_info.end_time %}
{% if batch_info.start_time and batch_info.end_time %}
<div class="mt-1">
<svg class="icon icon-sm">
<use href="#icon-clock"></use>
</svg>
<span>
{{ frappe.utils.format_time(class_info.start_time, "hh:mm a") }} -
{{ frappe.utils.format_time(batch_info.start_time, "hh:mm a") }} -
</span>
<span>
{{ frappe.utils.format_time(class_info.end_time, "hh:mm a") }}
{{ frappe.utils.format_time(batch_info.end_time, "hh:mm a") }}
</span>
</div>
{% endif %}
</div>
{% endmacro %}
{% macro CourseHeaderOverlay(class_info, courses, students) %}
{% macro BatchOverlay(batch_info, courses, students) %}
<div class="course-overlay-card class-overlay">
<div class="course-overlay-content">
{% if class_info.seat_count %}
{% if batch_info.seat_count %}
{% if seats_left %}
<div class="indicator-pill green pull-right">
{{ _("Seats Available") }}: {{ seats_left }}
@@ -96,9 +96,9 @@
{% endif %}
{% endif %}
{% if class_info.paid_class %}
{% if batch_info.paid_batch %}
<div class="bold-heading">
{{ frappe.utils.fmt_money(class_info.amount, 0, class_info.currency) }}
{{ frappe.utils.fmt_money(batch_info.amount, 0, batch_info.currency) }}
</div>
{% endif %}
@@ -114,47 +114,47 @@
<use href="#icon-calendar"></use>
</svg>
<span>
{{ frappe.utils.format_date(class_info.start_date, "long") }} -
{{ frappe.utils.format_date(batch_info.start_date, "long") }} -
</span>
<span>
{{ frappe.utils.format_date(class_info.end_date, "long") }}
{{ frappe.utils.format_date(batch_info.end_date, "long") }}
</span>
</div>
{% if class_info.start_time and class_info.end_time %}
{% if batch_info.start_time and batch_info.end_time %}
<div class="mt-2">
<svg class="icon icon-sm">
<use href="#icon-clock"></use>
</svg>
<span>
{{ frappe.utils.format_time(class_info.start_time, "hh:mm a") }} -
{{ frappe.utils.format_time(batch_info.start_time, "hh:mm a") }} -
</span>
<span>
{{ frappe.utils.format_time(class_info.end_time, "hh:mm a") }}
{{ frappe.utils.format_time(batch_info.end_time, "hh:mm a") }}
</span>
</div>
{% endif %}
<div class="mt-2">
{% if is_moderator or is_evaluator or is_student %}
<a class="btn btn-primary wide-button" href="/classes/{{ class_info.name }}">
{{ _("Checkout Class") }}
<a class="btn btn-primary wide-button" href="/batches/{{ batch_info.name }}">
{{ _("Checkout Batch") }}
</a>
{% elif class_info.paid_class %}
<a class="btn btn-primary wide-button {% if class_info.seat_count and not seats_left %} hide {% endif %}"
href="/billing/class/{{ class_info.name }}">
{% elif batch_info.paid_batch %}
<a class="btn btn-primary wide-button {% if batch_info.seat_count and not seats_left %} hide {% endif %}"
href="/billing/batch/{{ batch_info.name }}">
{{ _("Register Now") }}
</a>
{% else %}
<div class="alert alert-info">
{{ _("To join this class, please contact the Administrator.") }}
{{ _("To join this batch, please contact the Administrator.") }}
</div>
{% endif %}
</div>
{% if is_moderator %}
<div class="mt-2">
<div class="btn btn-secondary wide-button" id="create-class">
{{ _("Edit Class") }}
<div class="btn btn-secondary wide-button" id="create-batch">
{{ _("Edit") }}
</div>
</div>
{% endif %}
@@ -163,10 +163,10 @@
{% endmacro %}
{% macro ClassDetails(class_info) %}
{% macro BatchDetails(batch_info) %}
<div class="course-description-section w-50">
<div class="mt-2">
{{ class_info.class_details }}
{{ batch_info.batch_details }}
</div>
</div>
{% endmacro %}
@@ -203,7 +203,7 @@
{{ super() }}
{% if is_moderator %}
<script>
let class_info = {{ class_info | json }};
let batch_info = {{ batch_info | json }};
</script>
{% endif %}
{% endblock %}

View File

@@ -5,19 +5,19 @@ from lms.www.utils import is_student
def get_context(context):
context.no_cache = 1
class_name = frappe.form_dict["classname"]
batch_name = frappe.form_dict["batchname"]
context.class_info = frappe.db.get_value(
"LMS Class",
class_name,
context.batch_info = frappe.db.get_value(
"LMS Batch",
batch_name,
[
"name",
"title",
"description",
"class_details",
"batch_details",
"start_date",
"end_date",
"paid_class",
"paid_batch",
"amount",
"currency",
"start_time",
@@ -28,8 +28,8 @@ def get_context(context):
)
context.courses = frappe.get_all(
"Class Course",
{"parent": class_name},
"Batch Course",
{"parent": batch_name},
["name", "course", "title"],
order_by="creation desc",
)
@@ -41,9 +41,9 @@ def get_context(context):
)
)
context.student_count = frappe.db.count("Class Student", {"parent": class_name})
context.seats_left = context.class_info.seat_count - context.student_count
context.student_count = frappe.db.count("Batch Student", {"parent": batch_name})
context.seats_left = context.batch_info.seat_count - context.student_count
context.is_moderator = has_course_moderator_role()
context.is_evaluator = has_course_evaluator_role()
context.is_student = is_student(class_name)
context.is_student = is_student(batch_name)

View File

@@ -1,14 +1,14 @@
{% extends "lms/templates/lms_base.html" %}
{% block title %}
{{ _("All Classes") }}
{{ _("All Batches") }}
{% endblock %}
{% block page_content %}
<div class="common-page-style lms-page-style">
<div class="container">
{{ Header() }}
{% if past_classes | length or upcoming_classes | length %}
{{ ClassTabs(past_classes, upcoming_classes, my_classes) }}
{% if past_batches | length or upcoming_batches | length %}
{{ BatchTabs(past_batches, upcoming_batches, my_batches) }}
{% else %}
{{ EmptyState() }}
{% endif %}
@@ -18,16 +18,16 @@
{% macro Header() %}
<header class="edit-header">
<div class="page-title mb-6"> {{ _("All Classes") }} </div>
<div class="page-title mb-6"> {{ _("All Batches") }} </div>
{% if is_moderator %}
<button class="btn btn-default btn-sm pull-right" id="create-class">
{{ _("Create Class") }}
<button class="btn btn-primary btn-sm pull-right" id="create-batch">
{{ _("New Batch") }}
</button>
{% endif %}
</header>
{% endmacro %}
{% macro ClassTabs(past_classes, upcoming_classes, my_classes) %}
{% macro BatchTabs(past_batches, upcoming_batches, my_batches) %}
<article>
<ul class="nav lms-nav" id="courses-tab">
@@ -35,7 +35,7 @@
<a class="nav-link active" data-toggle="tab" href="#upcoming">
{{ _("Upcoming") }}
<span class="course-list-count">
{{ upcoming_classes | length }}
{{ upcoming_batches | length }}
</span>
</a>
</li>
@@ -45,7 +45,7 @@
<a class="nav-link" data-toggle="tab" href="#past">
{{ _("Archived") }}
<span class="course-list-count">
{{ past_classes | length }}
{{ past_batches | length }}
</span>
</a>
</li>
@@ -53,10 +53,10 @@
{% if frappe.session.user != "Guest" %}
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#my-class">
<a class="nav-link" data-toggle="tab" href="#my-batch">
{{ _("Enrolled") }}
<span class="course-list-count">
{{ my_classes | length }}
{{ my_batches | length }}
</span>
</a>
</li>
@@ -68,18 +68,18 @@
<div class="tab-content">
<div class="tab-pane active" id="upcoming" role="tabpanel" aria-labelledby="upcoming">
{{ ClassCards(upcoming_classes, show_price=True) }}
{{ BatchCard(upcoming_batches, show_price=True) }}
</div>
{% if is_moderator %}
<div class="tab-pane" id="past" role="tabpanel" aria-labelledby="past">
{{ ClassCards(past_classes, show_price=False) }}
{{ BatchCard(past_batches, show_price=False) }}
</div>
{% endif %}
{% if frappe.session.user != "Guest" %}
<div class="tab-pane" id="my-class" role="tabpanel" aria-labelledby="my-classes">
{{ ClassCards(my_classes, show_price=False) }}
<div class="tab-pane" id="my-batch" role="tabpanel" aria-labelledby="my-batches">
{{ BatchCard(my_batches, show_price=False) }}
</div>
{% endif %}
@@ -87,16 +87,16 @@
</article>
{% endmacro %}
{% macro ClassCards(classes, show_price=False) %}
{% macro BatchCard(batches, show_price=False) %}
<div class="lms-card-parent">
{% for class in classes %}
{% for batch in batches %}
<div class="common-card-style column-card" style="min-height: 150px;">
{% if class.seat_count %}
{% if class.seats_left > 0 %}
{% if batch.seat_count %}
{% if batch.seats_left > 0 %}
<div class="indicator-pill green align-self-start mb-2">
{{ _("Seats Available") }}: {{ class.seats_left }}
{{ _("Seats Available") }}: {{ batch.seats_left }}
</div>
{% else %}
<div class="indicator-pill red align-self-start mb-2">
@@ -106,18 +106,18 @@
{% endif %}
<div class="bold-heading">
{{ class.title }}
{{ batch.title }}
</div>
{% if class.description %}
{% if batch.description %}
<div class="short-introduction">
{{ class.description }}
{{ batch.description }}
</div>
{% endif %}
{% if show_price and class.paid_class %}
{% if show_price and batch.paid_batch %}
<div class="bold-heading mb-2">
{{ frappe.utils.fmt_money(class.amount, 0, class.currency) }}
{{ frappe.utils.fmt_money(batch.amount, 0, batch.currency) }}
</div>
{% endif %}
@@ -126,10 +126,10 @@
<use href="#icon-calendar"></use>
</svg>
<span>
{{ frappe.utils.format_date(class.start_date, "medium") }} -
{{ frappe.utils.format_date(batch.start_date, "medium") }} -
</span>
<span>
{{ frappe.utils.format_date(class.end_date, "medium") }}
{{ frappe.utils.format_date(batch.end_date, "medium") }}
</span>
</div>
@@ -137,20 +137,13 @@
<svg class="icon icon-md">
<use href="#icon-education"></use>
</svg>
{{ class.course_count }} {{ _("Courses") }}
{{ batch.course_count }} {{ _("Courses") }}
</div>
<!-- <div class="mb-2">
<svg class="icon icon-md">
<use href="#icon-users"></use>
</svg>
{{ student_count }} {{ _("Students") }}
</div> -->
{% if is_student(class.name) %}
<a class="stretched-link" href="/classes/{{ class.name }}"></a>
{% if is_student(batch.name) %}
<a class="stretched-link" href="/batches/{{ batch.name }}"></a>
{% else %}
<a class="stretched-link" href="/classes/details/{{ class.name }}"></a>
<a class="stretched-link" href="/batches/details/{{ batch.name }}"></a>
{% endif %}
</div>
{% endfor %}
@@ -161,7 +154,7 @@
<div class="empty-state">
<img class="icon icon-xl" src="/assets/lms/icons/comment.svg">
<div class="empty-state-text">
<div class="empty-state-heading">{{ _("No Classes") }}</div>
<div class="empty-state-heading">{{ _("No Batches") }}</div>
<div class="course-meta">{{ _("Nothing to see here.") }}</div>
</div>
</div>
@@ -177,7 +170,7 @@
"can_select": ["LMS Category"],
"can_read": ["LMS Category"]
};
let class_info = null;
let batch_info = null;
</script>
{% endif %}
{% endblock %}

74
lms/www/batches/index.py Normal file
View File

@@ -0,0 +1,74 @@
import frappe
from frappe.utils import getdate
from lms.lms.utils import has_course_moderator_role, has_course_evaluator_role
def get_context(context):
context.no_cache = 1
context.is_moderator = has_course_moderator_role()
context.is_evaluator = has_course_evaluator_role()
batches = frappe.get_all(
"LMS Batch",
fields=[
"name",
"title",
"description",
"start_date",
"end_date",
"paid_batch",
"amount",
"currency",
"seat_count",
],
order_by="start_date",
)
past_batches, upcoming_batches = [], []
for batch in batches:
batch.student_count = frappe.db.count("Batch Student", {"parent": batch.name})
batch.course_count = frappe.db.count("Batch Course", {"parent": batch.name})
batch.seats_left = (
batch.seat_count - batch.student_count if batch.seat_count else None
)
print(batch.seat_count, batch.student_count, batch.seats_left)
if getdate(batch.start_date) < getdate():
past_batches.append(batch)
else:
upcoming_batches.append(batch)
context.past_batches = sorted(past_batches, key=lambda d: d.start_date)
context.upcoming_batches = sorted(upcoming_batches, key=lambda d: d.start_date)
if frappe.session.user != "Guest":
my_batches_info = []
my_batches = frappe.get_all(
"Batch Student", {"student": frappe.session.user}, pluck="parent"
)
for batch in my_batches:
batchinfo = frappe.db.get_value(
"LMS Batch",
batch,
[
"name",
"title",
"description",
"start_date",
"end_date",
"paid_batch",
"amount",
"currency",
"seat_count",
],
as_dict=True,
)
batchinfo.student_count = frappe.db.count(
"Batch Student", {"parent": batchinfo.name}
)
batchinfo.course_count = frappe.db.count("Batch Course", {"parent": batchinfo.name})
batchinfo.seats_left = batchinfo.seat_count - batchinfo.student_count
my_batches_info.append(batchinfo)
context.my_batches = my_batches_info

View File

@@ -30,11 +30,11 @@ def get_context(context):
raise frappe.PermissionError(_("You don't have permission to access this page."))
context.class_info = frappe.db.get_value(
"LMS Class", class_name, ["name"], as_dict=True
"LMS Batch", class_name, ["name"], as_dict=True
)
context.courses = frappe.get_all(
"Class Course", {"parent": class_name}, pluck="course"
"Batch Course", {"parent": class_name}, pluck="course"
)
context.assessments = get_assessments(class_name, context.student.name)

View File

@@ -12,7 +12,7 @@ def get_context(context):
if module not in ["course", "class"]:
raise ValueError(_("Module is incorrect."))
doctype = "LMS Course" if module == "course" else "LMS Class"
doctype = "LMS Course" if module == "course" else "LMS Batch"
context.module = module
context.docname = docname
context.doctype = doctype
@@ -29,7 +29,7 @@ def get_context(context):
else:
membership = frappe.db.exists(
"Class Student", {"student": frappe.session.user, "parent": docname}
"Batch Student", {"student": frappe.session.user, "parent": docname}
)
if membership:
raise frappe.PermissionError(_("You are already enrolled for this class"))
@@ -51,7 +51,7 @@ def get_context(context):
else:
class_info = frappe.db.get_value(
"LMS Class",
"LMS Batch",
docname,
["title", "name", "paid_class", "amount", "currency"],
as_dict=True,

View File

@@ -1,76 +0,0 @@
import frappe
from frappe.utils import getdate
from lms.lms.utils import has_course_moderator_role, has_course_evaluator_role
def get_context(context):
context.no_cache = 1
context.is_moderator = has_course_moderator_role()
context.is_evaluator = has_course_evaluator_role()
classes = frappe.get_all(
"LMS Class",
fields=[
"name",
"title",
"description",
"start_date",
"end_date",
"paid_class",
"amount",
"currency",
"seat_count",
],
order_by="start_date",
)
past_classes, upcoming_classes = [], []
for class_ in classes:
class_.student_count = frappe.db.count("Class Student", {"parent": class_.name})
class_.course_count = frappe.db.count("Class Course", {"parent": class_.name})
class_.seats_left = (
class_.seat_count - class_.student_count if class_.seat_count else None
)
print(class_.seat_count, class_.student_count, class_.seats_left)
if getdate(class_.start_date) < getdate():
past_classes.append(class_)
else:
upcoming_classes.append(class_)
context.past_classes = sorted(past_classes, key=lambda d: d.start_date)
context.upcoming_classes = sorted(upcoming_classes, key=lambda d: d.start_date)
if frappe.session.user != "Guest":
my_classes_info = []
my_classes = frappe.get_all(
"Class Student", {"student": frappe.session.user}, pluck="parent"
)
for class_ in my_classes:
class_info = frappe.db.get_value(
"LMS Class",
class_,
[
"name",
"title",
"description",
"start_date",
"end_date",
"paid_class",
"amount",
"currency",
"seat_count",
],
as_dict=True,
)
class_info.student_count = frappe.db.count(
"Class Student", {"parent": class_info.name}
)
class_info.course_count = frappe.db.count(
"Class Course", {"parent": class_info.name}
)
class_info.seats_left = class_info.seat_count - class_info.student_count
my_classes_info.append(class_info)
context.my_classes = my_classes_info

View File

@@ -137,7 +137,7 @@ def is_student(class_name, member=None):
member = frappe.session.user
return frappe.db.exists(
"Class Student",
"Batch Student",
{
"student": member,
"parent": class_name,