feat: gst fields in class student
This commit is contained in:
@@ -7,16 +7,25 @@
|
|||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
|
"student_details_section",
|
||||||
"student",
|
"student",
|
||||||
|
"column_break_oduu",
|
||||||
"student_name",
|
"student_name",
|
||||||
"username",
|
"username",
|
||||||
"address",
|
"payment_details_section",
|
||||||
"column_break_zvlp",
|
"column_break_zvlp",
|
||||||
"amount",
|
"amount",
|
||||||
"currency",
|
"currency",
|
||||||
|
"column_break_clem",
|
||||||
"order_id",
|
"order_id",
|
||||||
"payment_id",
|
"payment_id",
|
||||||
"payment_received"
|
"payment_received",
|
||||||
|
"address_details_section",
|
||||||
|
"address",
|
||||||
|
"pan",
|
||||||
|
"column_break_rqoj",
|
||||||
|
"gstin",
|
||||||
|
"gst_category"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -78,12 +87,54 @@
|
|||||||
"fieldname": "payment_received",
|
"fieldname": "payment_received",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Payment Received"
|
"label": "Payment Received"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "student_details_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Student Details"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_oduu",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "payment_details_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Payment Details"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_clem",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "address_details_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Address Details"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "pan",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "PAN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_rqoj",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "gstin",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "GSTIN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "gst_category",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "GST Category"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-08-22 10:41:40.577437",
|
"modified": "2023-08-22 21:59:16.678547",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "Class Student",
|
"name": "Class Student",
|
||||||
|
|||||||
@@ -185,6 +185,50 @@ def authenticate():
|
|||||||
return response.json()["access_token"]
|
return response.json()["access_token"]
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def create_class(
|
||||||
|
title,
|
||||||
|
start_date,
|
||||||
|
end_date,
|
||||||
|
description=None,
|
||||||
|
prerequisite=None,
|
||||||
|
seat_count=0,
|
||||||
|
start_time=None,
|
||||||
|
end_time=None,
|
||||||
|
medium="Online",
|
||||||
|
category=None,
|
||||||
|
paid_class=0,
|
||||||
|
amount=0,
|
||||||
|
currency=None,
|
||||||
|
name=None,
|
||||||
|
):
|
||||||
|
frappe.only_for("Moderator")
|
||||||
|
if name:
|
||||||
|
class_details = frappe.get_doc("LMS Class", name)
|
||||||
|
else:
|
||||||
|
class_details = frappe.get_doc({"doctype": "LMS Class"})
|
||||||
|
|
||||||
|
class_details.update(
|
||||||
|
{
|
||||||
|
"title": title,
|
||||||
|
"start_date": start_date,
|
||||||
|
"end_date": end_date,
|
||||||
|
"description": description,
|
||||||
|
"prerequisite": prerequisite,
|
||||||
|
"seat_count": seat_count,
|
||||||
|
"start_time": start_time,
|
||||||
|
"end_time": end_time,
|
||||||
|
"medium": medium,
|
||||||
|
"category": category,
|
||||||
|
"paid_class": paid_class,
|
||||||
|
"amount": amount,
|
||||||
|
"currency": currency,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
class_details.save()
|
||||||
|
return class_details
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def fetch_lessons(courses):
|
def fetch_lessons(courses):
|
||||||
lessons = []
|
lessons = []
|
||||||
|
|||||||
@@ -987,5 +987,5 @@ def add_student_to_class(address, response, classname, client):
|
|||||||
return f"/classes/{classname}"
|
return f"/classes/{classname}"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_("Error during payment: {0}. Please contact the Administrator.").format(e)
|
_("Error during payment: {0} Please contact the Administrator.").format(e)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -354,6 +354,7 @@ const open_class_dialog = () => {
|
|||||||
default: class_info && class_info.currency,
|
default: class_info && class_info.currency,
|
||||||
mandatory_depends_on: "paid_class",
|
mandatory_depends_on: "paid_class",
|
||||||
depends_on: "paid_class",
|
depends_on: "paid_class",
|
||||||
|
only_select: 1,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
primary_action_label: __("Save"),
|
primary_action_label: __("Save"),
|
||||||
@@ -365,20 +366,15 @@ const open_class_dialog = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const save_class = (values) => {
|
const save_class = (values) => {
|
||||||
let method, args;
|
let args = {};
|
||||||
if (class_info) {
|
if (class_info) {
|
||||||
method = "frappe.client.save";
|
|
||||||
args = Object.assign(class_info, values);
|
args = Object.assign(class_info, values);
|
||||||
} else {
|
} else {
|
||||||
method = "frappe.client.insert";
|
|
||||||
args = values;
|
args = values;
|
||||||
args.doctype = "LMS Class";
|
|
||||||
}
|
}
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: method,
|
method: "lms.lms.doctype.lms_class.lms_class.create_class",
|
||||||
args: {
|
args: args,
|
||||||
doc: args,
|
|
||||||
},
|
|
||||||
callback: (r) => {
|
callback: (r) => {
|
||||||
if (r.message) {
|
if (r.message) {
|
||||||
frappe.show_alert({
|
frappe.show_alert({
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
{{ _("Order Details") }}
|
{{ _("Order Details") }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{{ _("Enter the billing information and complete the payment to purchase this {0}.").format(module) }}
|
{{ _("Enter the billing information to complete the payment.").format(module) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
@@ -59,11 +59,4 @@
|
|||||||
{%- block script %}
|
{%- block script %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
|
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
|
||||||
<script>
|
|
||||||
frappe.boot.user = {
|
|
||||||
"can_create": [],
|
|
||||||
"can_select": ["Country"],
|
|
||||||
"can_read": ["Country"]
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ const setup_billing = () => {
|
|||||||
fieldname: "country",
|
fieldname: "country",
|
||||||
options: "Country",
|
options: "Country",
|
||||||
reqd: 1,
|
reqd: 1,
|
||||||
|
only_select: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldtype: "Data",
|
fieldtype: "Data",
|
||||||
@@ -57,6 +58,18 @@ const setup_billing = () => {
|
|||||||
fieldname: "phone",
|
fieldname: "phone",
|
||||||
reqd: 1,
|
reqd: 1,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
fieldtype: "Data",
|
||||||
|
fieldname: "gstin",
|
||||||
|
label: __("GSTIN"),
|
||||||
|
depends_on: (doc) => console.log(doc.country),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldtype: "Data",
|
||||||
|
fieldname: "pan",
|
||||||
|
label: __("PAN"),
|
||||||
|
depends_on: (doc) => console.log(doc.country),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
body: $("#billing-form").get(0),
|
body: $("#billing-form").get(0),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -600,26 +600,8 @@
|
|||||||
|
|
||||||
{%- block script %}
|
{%- block script %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
{% if is_moderator %}
|
|
||||||
<script>
|
<script>
|
||||||
frappe.boot.user = {
|
|
||||||
"can_create": [],
|
|
||||||
"can_select": ["User", "LMS Assignment", "LMS Quiz"],
|
|
||||||
"can_read": ["User", "LMS Assignment", "LMS Quiz"]
|
|
||||||
};
|
|
||||||
|
|
||||||
frappe.boot.single_types = []
|
frappe.boot.single_types = []
|
||||||
|
|
||||||
</script>
|
|
||||||
{% else %}
|
|
||||||
<script>
|
|
||||||
frappe.boot.user= {
|
|
||||||
"can_create": [],
|
|
||||||
"can_select": ["LMS Course"],
|
|
||||||
"can_read": ["LMS Course"]
|
|
||||||
};
|
|
||||||
let courses = {{ course_list | json }};
|
let courses = {{ course_list | json }};
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
frappe.ready(() => {
|
frappe.ready(() => {
|
||||||
let self = this;
|
let self = this;
|
||||||
|
frappe.require("controls.bundle.js");
|
||||||
|
|
||||||
if ($("#live-class-form").length) {
|
if ($("#live-class-form").length) {
|
||||||
frappe.require("controls.bundle.js", () => {
|
setTimeout(() => {
|
||||||
make_live_class_form();
|
make_live_class_form();
|
||||||
});
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
$(".btn-add-student").click((e) => {
|
$(".btn-add-student").click((e) => {
|
||||||
show_student_modal(e);
|
show_student_modal(e);
|
||||||
});
|
});
|
||||||
@@ -308,12 +310,14 @@ const show_course_modal = () => {
|
|||||||
label: __("Course"),
|
label: __("Course"),
|
||||||
fieldname: "course",
|
fieldname: "course",
|
||||||
reqd: 1,
|
reqd: 1,
|
||||||
|
only_select: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldtype: "Link",
|
fieldtype: "Link",
|
||||||
options: "Course Evaluator",
|
options: "Course Evaluator",
|
||||||
label: __("Course Evaluator"),
|
label: __("Course Evaluator"),
|
||||||
fieldname: "evaluator",
|
fieldname: "evaluator",
|
||||||
|
only_select: 1,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
primary_action_label: __("Add"),
|
primary_action_label: __("Add"),
|
||||||
@@ -385,6 +389,7 @@ const show_student_modal = () => {
|
|||||||
label: __("Student"),
|
label: __("Student"),
|
||||||
fieldname: "student",
|
fieldname: "student",
|
||||||
reqd: 1,
|
reqd: 1,
|
||||||
|
only_select: 1,
|
||||||
filters: {
|
filters: {
|
||||||
ignore_user_type: 1,
|
ignore_user_type: 1,
|
||||||
},
|
},
|
||||||
@@ -463,6 +468,7 @@ const show_assessment_modal = (e) => {
|
|||||||
label: __("Assessment Type"),
|
label: __("Assessment Type"),
|
||||||
fieldname: "assessment_type",
|
fieldname: "assessment_type",
|
||||||
reqd: 1,
|
reqd: 1,
|
||||||
|
only_select: 1,
|
||||||
filters: {
|
filters: {
|
||||||
name: ["in", ["LMS Assignment", "LMS Quiz"]],
|
name: ["in", ["LMS Assignment", "LMS Quiz"]],
|
||||||
},
|
},
|
||||||
@@ -474,6 +480,7 @@ const show_assessment_modal = (e) => {
|
|||||||
label: __("Assessment"),
|
label: __("Assessment"),
|
||||||
fieldname: "assessment_name",
|
fieldname: "assessment_name",
|
||||||
reqd: 1,
|
reqd: 1,
|
||||||
|
only_select: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldtype: "Section Break",
|
fieldtype: "Section Break",
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
<div class="common-page-style lms-page-style">
|
<div class="common-page-style lms-page-style">
|
||||||
{{ ClassHeader(class_info) }}
|
{{ ClassHeader(class_info) }}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
{{ CourseHeaderOverlay(class_info) }}
|
{{ CourseHeaderOverlay(class_info, courses, students) }}
|
||||||
<div class="pt-10">
|
<div class="pt-10">
|
||||||
{{ Prerequisites(class_info) }}
|
{{ Prerequisites(class_info) }}
|
||||||
{{ CourseList(class_info) }}
|
{{ CourseList(courses) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="course-card-wide">
|
<div class="course-card-wide">
|
||||||
{{ BreadCrumb(class_info) }}
|
{{ BreadCrumb(class_info) }}
|
||||||
{{ ClassHeaderDetails(class_info) }}
|
{{ ClassHeaderDetails(class_info, courses, students) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -40,15 +40,15 @@
|
|||||||
</article>
|
</article>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro ClassHeaderDetails(class_info) %}
|
{% macro ClassHeaderDetails(class_info, courses, students) %}
|
||||||
<div class="class-details" data-class="{{ class_info.name }}">
|
<div class="class-details" data-class="{{ class_info.name }}">
|
||||||
<div class="flex align-center">
|
<div class="flex align-center">
|
||||||
<span>
|
<span>
|
||||||
{{ class_info.courses | length }} {{ _("Courses") }}
|
{{ courses | length }} {{ _("Courses") }}
|
||||||
</span>
|
</span>
|
||||||
<span class="px-2"> · </span>
|
<span class="px-2"> · </span>
|
||||||
<span>
|
<span>
|
||||||
{{ class_info.students | length }} {{ _("Students") }}
|
{{ students | length }} {{ _("Students") }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro CourseHeaderOverlay(class_info) %}
|
{% macro CourseHeaderOverlay(class_info, courses, students) %}
|
||||||
<div class="course-overlay-card class-overlay">
|
<div class="course-overlay-card class-overlay">
|
||||||
|
|
||||||
<div class="course-overlay-content">
|
<div class="course-overlay-content">
|
||||||
@@ -102,14 +102,14 @@
|
|||||||
<svg class="icon icon-md mr-1">
|
<svg class="icon icon-md mr-1">
|
||||||
<use href="#icon-education"></use>
|
<use href="#icon-education"></use>
|
||||||
</svg>
|
</svg>
|
||||||
{{ class_info.courses | length }} {{ _("Courses") }}
|
{{ courses | length }} {{ _("Courses") }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="vertically-center mt-2">
|
<div class="vertically-center mt-2">
|
||||||
<svg class="icon icon-md mr-1">
|
<svg class="icon icon-md mr-1">
|
||||||
<use class="" href="#icon-users">
|
<use class="" href="#icon-users">
|
||||||
</svg>
|
</svg>
|
||||||
{{ class_info.students | length }} {{ _("Students") }}
|
{{ students | length }} {{ _("Students") }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
@@ -177,14 +177,14 @@
|
|||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
{% macro CourseList(class_info) %}
|
{% macro CourseList(courses) %}
|
||||||
<div>
|
<div>
|
||||||
<div class="page-title">
|
<div class="page-title">
|
||||||
{{ _("Courses") }}
|
{{ _("Courses") }}
|
||||||
</div>
|
</div>
|
||||||
{% if class_info.courses | length %}
|
{% if courses | length %}
|
||||||
<div class="cards-parent mt-2">
|
<div class="cards-parent mt-2">
|
||||||
{% for course in class_info.courses %}
|
{% for course in courses %}
|
||||||
<div class="h-100">
|
<div class="h-100">
|
||||||
{{ widgets.CourseCard(course=course, read_only=False) }}
|
{{ widgets.CourseCard(course=course, read_only=False) }}
|
||||||
<button class="btn icon-btn btn-default btn-block btn-remove-course" data-course="{{ course.name }}">
|
<button class="btn icon-btn btn-default btn-block btn-remove-course" data-course="{{ course.name }}">
|
||||||
|
|||||||
@@ -7,15 +7,46 @@ def get_context(context):
|
|||||||
context.no_cache = 1
|
context.no_cache = 1
|
||||||
class_name = frappe.form_dict["classname"]
|
class_name = frappe.form_dict["classname"]
|
||||||
|
|
||||||
context.class_info = frappe.get_doc("LMS Class", class_name)
|
context.class_info = frappe.db.get_value(
|
||||||
|
"LMS Class",
|
||||||
|
class_name,
|
||||||
|
[
|
||||||
|
"name",
|
||||||
|
"title",
|
||||||
|
"description",
|
||||||
|
"prerequisite",
|
||||||
|
"start_date",
|
||||||
|
"end_date",
|
||||||
|
"paid_class",
|
||||||
|
"amount",
|
||||||
|
"currency",
|
||||||
|
"start_time",
|
||||||
|
"end_time",
|
||||||
|
],
|
||||||
|
as_dict=1,
|
||||||
|
)
|
||||||
|
|
||||||
for course in context.class_info.courses:
|
context.courses = frappe.get_all(
|
||||||
|
"Class Course",
|
||||||
|
{"parent": class_name},
|
||||||
|
["name", "course", "title"],
|
||||||
|
order_by="creation desc",
|
||||||
|
)
|
||||||
|
|
||||||
|
for course in context.courses:
|
||||||
course.update(
|
course.update(
|
||||||
frappe.db.get_value(
|
frappe.db.get_value(
|
||||||
"LMS Course", course.course, ["name", "short_introduction", "image"], as_dict=1
|
"LMS Course", course.course, ["name", "short_introduction", "image"], as_dict=1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
context.students = frappe.get_all(
|
||||||
|
"Class Student",
|
||||||
|
{"parent": class_name},
|
||||||
|
["name", "student", "student_name", "username"],
|
||||||
|
order_by="creation desc",
|
||||||
|
)
|
||||||
|
|
||||||
context.is_moderator = has_course_moderator_role()
|
context.is_moderator = has_course_moderator_role()
|
||||||
context.is_evaluator = has_course_evaluator_role()
|
context.is_evaluator = has_course_evaluator_role()
|
||||||
context.is_student = is_student(class_name)
|
context.is_student = is_student(class_name)
|
||||||
|
|||||||
@@ -106,12 +106,12 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if show_price and class.paid_class %}
|
{% if show_price and class.paid_class %}
|
||||||
<div class="bold-heading">
|
<div class="bold-heading mb-2">
|
||||||
{{ frappe.utils.fmt_money(class.amount, 0, class.currency) }}
|
{{ frappe.utils.fmt_money(class.amount, 0, class.currency) }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="mt-auto mb-1">
|
<div class="mt-auto mb-2">
|
||||||
<svg class="icon icon-sm">
|
<svg class="icon icon-sm">
|
||||||
<use href="#icon-calendar"></use>
|
<use href="#icon-calendar"></use>
|
||||||
</svg>
|
</svg>
|
||||||
@@ -123,14 +123,14 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-1">
|
<div class="mb-2">
|
||||||
<svg class="icon icon-md">
|
<svg class="icon icon-md">
|
||||||
<use href="#icon-education"></use>
|
<use href="#icon-education"></use>
|
||||||
</svg>
|
</svg>
|
||||||
{{ course_count }} {{ _("Courses") }}
|
{{ course_count }} {{ _("Courses") }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-1">
|
<div class="mb-2">
|
||||||
<svg class="icon icon-md">
|
<svg class="icon icon-md">
|
||||||
<use href="#icon-users"></use>
|
<use href="#icon-users"></use>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
Reference in New Issue
Block a user