feat: capture gst information
This commit is contained in:
@@ -9,23 +9,10 @@
|
||||
"field_order": [
|
||||
"student_details_section",
|
||||
"student",
|
||||
"payment",
|
||||
"column_break_oduu",
|
||||
"student_name",
|
||||
"username",
|
||||
"payment_details_section",
|
||||
"column_break_zvlp",
|
||||
"amount",
|
||||
"currency",
|
||||
"column_break_clem",
|
||||
"order_id",
|
||||
"payment_id",
|
||||
"payment_received",
|
||||
"address_details_section",
|
||||
"address",
|
||||
"pan",
|
||||
"column_break_rqoj",
|
||||
"gstin",
|
||||
"gst_category"
|
||||
"username"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -51,43 +38,6 @@
|
||||
"label": "Username",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_zvlp",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "address",
|
||||
"fieldtype": "Link",
|
||||
"label": "Address",
|
||||
"options": "Address"
|
||||
},
|
||||
{
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Amount"
|
||||
},
|
||||
{
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "order_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Order ID"
|
||||
},
|
||||
{
|
||||
"fieldname": "payment_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Payment ID"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "payment_received",
|
||||
"fieldtype": "Check",
|
||||
"label": "Payment Received"
|
||||
},
|
||||
{
|
||||
"fieldname": "student_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -98,43 +48,16 @@
|
||||
"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"
|
||||
"fieldname": "payment",
|
||||
"fieldtype": "Link",
|
||||
"label": "Payment",
|
||||
"options": "LMS Payment"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2023-08-22 21:59:16.678547",
|
||||
"modified": "2023-08-24 17:48:53.045539",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "Class Student",
|
||||
|
||||
@@ -7,22 +7,15 @@
|
||||
"field_order": [
|
||||
"course",
|
||||
"member_type",
|
||||
"batch",
|
||||
"payment",
|
||||
"column_break_3",
|
||||
"member",
|
||||
"member_name",
|
||||
"member_username",
|
||||
"billing_information_section",
|
||||
"address",
|
||||
"amount",
|
||||
"currency",
|
||||
"column_break_rvzn",
|
||||
"order_id",
|
||||
"payment_id",
|
||||
"payment_received",
|
||||
"section_break_8",
|
||||
"cohort",
|
||||
"subgroup",
|
||||
"batch",
|
||||
"column_break_12",
|
||||
"current_lesson",
|
||||
"progress",
|
||||
@@ -122,52 +115,15 @@
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "billing_information_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Billing Information"
|
||||
},
|
||||
{
|
||||
"fieldname": "address",
|
||||
"fieldname": "payment",
|
||||
"fieldtype": "Link",
|
||||
"label": "Address",
|
||||
"options": "Address"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "payment_received",
|
||||
"fieldtype": "Check",
|
||||
"label": "Payment Received"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_rvzn",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "order_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Order ID"
|
||||
},
|
||||
{
|
||||
"fieldname": "payment_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Payment ID"
|
||||
},
|
||||
{
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Data",
|
||||
"label": "Amount",
|
||||
"options": "currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency"
|
||||
"label": "Payment",
|
||||
"options": "LMS Payment"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2023-08-17 13:52:49.450499",
|
||||
"modified": "2023-08-24 17:52:35.487141",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Batch Membership",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"seat_count",
|
||||
"section_break_6",
|
||||
"description",
|
||||
"prerequisite",
|
||||
"class_details",
|
||||
"students",
|
||||
"courses",
|
||||
"section_break_gsac",
|
||||
@@ -188,15 +188,15 @@
|
||||
"options": "Currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "prerequisite",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Prerequisite",
|
||||
"fieldname": "class_details",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Class Details",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2023-08-22 11:53:22.248596",
|
||||
"modified": "2023-08-23 17:35:42.750754",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Class",
|
||||
|
||||
@@ -191,7 +191,7 @@ def create_class(
|
||||
start_date,
|
||||
end_date,
|
||||
description=None,
|
||||
prerequisite=None,
|
||||
class_details=None,
|
||||
seat_count=0,
|
||||
start_time=None,
|
||||
end_time=None,
|
||||
@@ -204,17 +204,17 @@ def create_class(
|
||||
):
|
||||
frappe.only_for("Moderator")
|
||||
if name:
|
||||
class_details = frappe.get_doc("LMS Class", name)
|
||||
doc = frappe.get_doc("LMS Class", name)
|
||||
else:
|
||||
class_details = frappe.get_doc({"doctype": "LMS Class"})
|
||||
doc = frappe.get_doc({"doctype": "LMS Class"})
|
||||
|
||||
class_details.update(
|
||||
doc.update(
|
||||
{
|
||||
"title": title,
|
||||
"start_date": start_date,
|
||||
"end_date": end_date,
|
||||
"description": description,
|
||||
"prerequisite": prerequisite,
|
||||
"class_details": class_details,
|
||||
"seat_count": seat_count,
|
||||
"start_time": start_time,
|
||||
"end_time": end_time,
|
||||
@@ -225,8 +225,8 @@ def create_class(
|
||||
"currency": currency,
|
||||
}
|
||||
)
|
||||
class_details.save()
|
||||
return class_details
|
||||
doc.save()
|
||||
return doc
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
|
||||
0
lms/lms/doctype/lms_payment/__init__.py
Normal file
0
lms/lms/doctype/lms_payment/__init__.py
Normal file
8
lms/lms/doctype/lms_payment/lms_payment.js
Normal file
8
lms/lms/doctype/lms_payment/lms_payment.js
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2023, Frappe and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
// frappe.ui.form.on("LMS Payment", {
|
||||
// refresh(frm) {
|
||||
|
||||
// },
|
||||
// });
|
||||
139
lms/lms/doctype/lms_payment/lms_payment.json
Normal file
139
lms/lms/doctype/lms_payment/lms_payment.json
Normal file
@@ -0,0 +1,139 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_rename": 1,
|
||||
"autoname": "format:PAY-{#####}",
|
||||
"creation": "2023-08-24 17:46:52.065763",
|
||||
"default_view": "List",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"member",
|
||||
"column_break_rqkd",
|
||||
"billing_name",
|
||||
"payment_received",
|
||||
"payment_details_section",
|
||||
"amount",
|
||||
"currency",
|
||||
"column_break_yxpl",
|
||||
"order_id",
|
||||
"payment_id",
|
||||
"billing_details_section",
|
||||
"address",
|
||||
"column_break_monu",
|
||||
"gstin",
|
||||
"pan"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "order_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Order ID"
|
||||
},
|
||||
{
|
||||
"fieldname": "payment_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Payment ID"
|
||||
},
|
||||
{
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Amount"
|
||||
},
|
||||
{
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_rqkd",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "gstin",
|
||||
"fieldtype": "Data",
|
||||
"label": "GSTIN"
|
||||
},
|
||||
{
|
||||
"fieldname": "pan",
|
||||
"fieldtype": "Data",
|
||||
"label": "PAN"
|
||||
},
|
||||
{
|
||||
"fieldname": "address",
|
||||
"fieldtype": "Link",
|
||||
"label": "Address",
|
||||
"options": "Address"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "payment_received",
|
||||
"fieldtype": "Check",
|
||||
"label": "Payment Received"
|
||||
},
|
||||
{
|
||||
"fetch_from": "user.full_name",
|
||||
"fieldname": "billing_name",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Billing Name",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "payment_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Payment Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_yxpl",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "billing_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Billing Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_monu",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "member",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Member",
|
||||
"options": "User",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2023-08-24 22:08:12.294960",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Payment",
|
||||
"naming_rule": "Expression",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"show_title_field_in_link": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"title_field": "billing_name"
|
||||
}
|
||||
9
lms/lms/doctype/lms_payment/lms_payment.py
Normal file
9
lms/lms/doctype/lms_payment/lms_payment.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2023, Frappe and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class LMSPayment(Document):
|
||||
pass
|
||||
9
lms/lms/doctype/lms_payment/test_lms_payment.py
Normal file
9
lms/lms/doctype/lms_payment/test_lms_payment.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2023, Frappe and Contributors
|
||||
# See license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestLMSPayment(FrappeTestCase):
|
||||
pass
|
||||
155
lms/lms/utils.py
155
lms/lms/utils.py
@@ -835,24 +835,7 @@ def get_payment_options(doctype, docname, phone):
|
||||
frappe.throw(_("Invalid document provided."))
|
||||
|
||||
validate_phone_number(phone, True)
|
||||
if doctype == "LMS Course":
|
||||
details = frappe.db.get_value(
|
||||
"LMS Course",
|
||||
docname,
|
||||
["name", "title", "paid_course", "currency", "course_price as amount"],
|
||||
as_dict=True,
|
||||
)
|
||||
if not details.paid_course:
|
||||
frappe.throw(_("This course is free."))
|
||||
else:
|
||||
details = frappe.db.get_value(
|
||||
"LMS Class",
|
||||
docname,
|
||||
["name", "title", "paid_class", "currency", "amount"],
|
||||
as_dict=True,
|
||||
)
|
||||
if not details.paid_class:
|
||||
frappe.throw(_("To join this class, please contact the Administrator."))
|
||||
details = get_details(doctype, docname)
|
||||
|
||||
razorpay_key = frappe.db.get_single_value("LMS Settings", "razorpay_key")
|
||||
client = get_client()
|
||||
@@ -874,8 +857,30 @@ def get_payment_options(doctype, docname, phone):
|
||||
return options
|
||||
|
||||
|
||||
def get_details(doctype, docname):
|
||||
if doctype == "LMS Course":
|
||||
details = frappe.db.get_value(
|
||||
"LMS Course",
|
||||
docname,
|
||||
["name", "title", "paid_course", "currency", "course_price as amount"],
|
||||
as_dict=True,
|
||||
)
|
||||
if not details.paid_course:
|
||||
frappe.throw(_("This course is free."))
|
||||
else:
|
||||
details = frappe.db.get_value(
|
||||
"LMS Class",
|
||||
docname,
|
||||
["name", "title", "paid_class", "currency", "amount"],
|
||||
as_dict=True,
|
||||
)
|
||||
if not details.paid_class:
|
||||
frappe.throw(_("To join this class, please contact the Administrator."))
|
||||
|
||||
return details
|
||||
|
||||
|
||||
def save_address(address):
|
||||
address = json.loads(address)
|
||||
address.update(
|
||||
{
|
||||
"address_title": frappe.db.get_value("User", frappe.session.user, "full_name"),
|
||||
@@ -930,62 +935,76 @@ def verify_payment(response, doctype, docname, address, order_id):
|
||||
}
|
||||
)
|
||||
|
||||
payment = record_payment(address, response, client, doctype, docname)
|
||||
if doctype == "LMS Course":
|
||||
return create_membership(address, response, docname, client)
|
||||
return create_membership(docname, payment)
|
||||
else:
|
||||
return add_student_to_class(address, response, docname, client)
|
||||
return add_student_to_class(docname, payment)
|
||||
|
||||
|
||||
def create_membership(address, response, course, client):
|
||||
def record_payment(address, response, client, doctype, docname):
|
||||
address = frappe._dict(json.loads(address))
|
||||
address_name = save_address(address)
|
||||
|
||||
payment_details = get_payment_details(client, response, doctype, docname)
|
||||
payment_doc = frappe.new_doc("LMS Payment")
|
||||
payment_doc.update(
|
||||
{
|
||||
"member": frappe.session.user,
|
||||
"billing_name": address.billing_name,
|
||||
"address": address_name,
|
||||
"payment_received": 1,
|
||||
"order_id": response["razorpay_order_id"],
|
||||
"payment_id": response["razorpay_payment_id"],
|
||||
"amount": payment_details["amount"],
|
||||
"currency": payment_details["currency"],
|
||||
"gstin": address.gstin,
|
||||
"pan": address.pan,
|
||||
}
|
||||
)
|
||||
payment_doc.save(ignore_permissions=True)
|
||||
return payment_doc.name
|
||||
|
||||
|
||||
def get_payment_details(client, response, doctype, docname):
|
||||
try:
|
||||
address_name = save_address(address)
|
||||
payment = client.payment.fetch(response["razorpay_payment_id"])
|
||||
membership = frappe.new_doc("LMS Batch Membership")
|
||||
|
||||
membership.update(
|
||||
{
|
||||
"member": frappe.session.user,
|
||||
"course": course,
|
||||
"address": address_name,
|
||||
"payment_received": 1,
|
||||
"order_id": response["razorpay_order_id"],
|
||||
"payment_id": response["razorpay_payment_id"],
|
||||
"amount": payment["amount"] / 100,
|
||||
"currency": payment["currency"],
|
||||
}
|
||||
)
|
||||
membership.save(ignore_permissions=True)
|
||||
|
||||
return f"/courses/{course}/learn/1.1"
|
||||
except Exception as e:
|
||||
frappe.throw(
|
||||
_("Error during payment: {0}. Please contact the Administrator.").format(e)
|
||||
)
|
||||
frappe.log_error(e, "Error during payment fetch")
|
||||
|
||||
if payment:
|
||||
amount = payment["amount"] / 100
|
||||
currency = payment["currency"]
|
||||
else:
|
||||
amount_field = "course_price" if doctype == "LMS Course" else "amount"
|
||||
amount = frappe.db.get_value(doctype, docname, amount_field)
|
||||
currency = frappe.db.get_value(doctype, docname, "currency")
|
||||
|
||||
return {
|
||||
"amount": amount,
|
||||
"currency": currency,
|
||||
}
|
||||
|
||||
|
||||
def add_student_to_class(address, response, classname, client):
|
||||
try:
|
||||
address_name = save_address(address)
|
||||
payment = client.payment.fetch(response["razorpay_payment_id"])
|
||||
student = frappe.new_doc("Class Student")
|
||||
def create_membership(course, payment):
|
||||
membership = frappe.new_doc("LMS Batch Membership")
|
||||
membership.update(
|
||||
{"member": frappe.session.user, "course": course, "payment": payment}
|
||||
)
|
||||
membership.save(ignore_permissions=True)
|
||||
return f"/courses/{course}/learn/1.1"
|
||||
|
||||
student.update(
|
||||
{
|
||||
"student": frappe.session.user,
|
||||
"parent": classname,
|
||||
"parenttype": "LMS Class",
|
||||
"parentfield": "students",
|
||||
"address": address_name,
|
||||
"amount": payment["amount"] / 100,
|
||||
"currency": payment["currency"],
|
||||
"payment_received": 1,
|
||||
"order_id": response["razorpay_order_id"],
|
||||
"payment_id": response["razorpay_payment_id"],
|
||||
}
|
||||
)
|
||||
student.save(ignore_permissions=True)
|
||||
return f"/classes/{classname}"
|
||||
except Exception as e:
|
||||
frappe.throw(
|
||||
_("Error during payment: {0} Please contact the Administrator.").format(e)
|
||||
)
|
||||
|
||||
def add_student_to_class(classname, payment):
|
||||
student = frappe.new_doc("Class Student")
|
||||
student.update(
|
||||
{
|
||||
"student": frappe.session.user,
|
||||
"payment": payment,
|
||||
"parent": classname,
|
||||
"parenttype": "LMS Class",
|
||||
"parentfield": "students",
|
||||
}
|
||||
)
|
||||
student.save(ignore_permissions=True)
|
||||
return f"/classes/{classname}"
|
||||
|
||||
@@ -2188,10 +2188,6 @@ select {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.awesomplete ul li:last-child {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.students-parent {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, 150px);
|
||||
|
||||
@@ -321,10 +321,10 @@ const open_class_dialog = () => {
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
fieldtype: "Small Text",
|
||||
label: __("Prerequisite"),
|
||||
fieldname: "prerequisite",
|
||||
default: class_info && class_info.prerequisite,
|
||||
fieldtype: "Text Editor",
|
||||
label: __("Class Details"),
|
||||
fieldname: "class_details",
|
||||
default: class_info && class_info.class_details,
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -13,6 +13,12 @@ frappe.ready(() => {
|
||||
const setup_billing = () => {
|
||||
this.billing = new frappe.ui.FieldGroup({
|
||||
fields: [
|
||||
{
|
||||
fieldtype: "Data",
|
||||
label: __("Billing Name"),
|
||||
fieldname: "billing_name",
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
fieldtype: "Data",
|
||||
label: __("Address Line 1"),
|
||||
@@ -30,14 +36,14 @@ const setup_billing = () => {
|
||||
fieldname: "city",
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
fieldtype: "Column Break",
|
||||
},
|
||||
{
|
||||
fieldtype: "Data",
|
||||
label: __("State/Province"),
|
||||
fieldname: "state",
|
||||
},
|
||||
{
|
||||
fieldtype: "Column Break",
|
||||
},
|
||||
{
|
||||
fieldtype: "Link",
|
||||
label: __("Country"),
|
||||
@@ -58,17 +64,25 @@ const setup_billing = () => {
|
||||
fieldname: "phone",
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
fieldtype: "Section Break",
|
||||
label: __("GST Details"),
|
||||
fieldname: "gst_details",
|
||||
depends_on: "eval:doc.country === 'India'",
|
||||
},
|
||||
{
|
||||
fieldtype: "Data",
|
||||
fieldname: "gstin",
|
||||
label: __("GSTIN"),
|
||||
depends_on: (doc) => console.log(doc.country),
|
||||
fieldname: "gstin",
|
||||
},
|
||||
{
|
||||
fieldtype: "Column Break",
|
||||
fieldname: "gst_details_break",
|
||||
},
|
||||
{
|
||||
fieldtype: "Data",
|
||||
fieldname: "pan",
|
||||
label: __("PAN"),
|
||||
depends_on: (doc) => console.log(doc.country),
|
||||
},
|
||||
],
|
||||
body: $("#billing-form").get(0),
|
||||
|
||||
@@ -39,7 +39,7 @@ def get_context(context):
|
||||
"paid_class",
|
||||
"amount",
|
||||
"currency",
|
||||
"prerequisite",
|
||||
"class_details",
|
||||
],
|
||||
as_dict=True,
|
||||
)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<div class="container">
|
||||
{{ CourseHeaderOverlay(class_info, courses, students) }}
|
||||
<div class="pt-10">
|
||||
{{ Prerequisites(class_info) }}
|
||||
{{ ClassDetails(class_info) }}
|
||||
{{ CourseList(courses) }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -42,15 +42,6 @@
|
||||
|
||||
{% macro ClassHeaderDetails(class_info, courses, students) %}
|
||||
<div class="class-details" data-class="{{ class_info.name }}">
|
||||
<div class="flex align-center">
|
||||
<span>
|
||||
{{ courses | length }} {{ _("Courses") }}
|
||||
</span>
|
||||
<span class="px-2"> · </span>
|
||||
<span>
|
||||
{{ students | length }} {{ _("Students") }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="page-title">
|
||||
{{ class_info.title }}
|
||||
@@ -92,6 +83,19 @@
|
||||
<div class="course-overlay-card class-overlay">
|
||||
|
||||
<div class="course-overlay-content">
|
||||
|
||||
{% if class_info.seat_count %}
|
||||
{% if seats_left %}
|
||||
<div class="indicator-pill green pull-right">
|
||||
{{ _("Seats Available") }}: {{ seats_left }}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="indicator-pill red pull-right">
|
||||
{{ _("No seats left") }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if class_info.paid_class %}
|
||||
<div class="bold-heading">
|
||||
{{ frappe.utils.fmt_money(class_info.amount, 0, class_info.currency) }}
|
||||
@@ -105,13 +109,6 @@
|
||||
{{ courses | length }} {{ _("Courses") }}
|
||||
</div>
|
||||
|
||||
<div class="vertically-center mt-2">
|
||||
<svg class="icon icon-md mr-1">
|
||||
<use class="" href="#icon-users">
|
||||
</svg>
|
||||
{{ students | length }} {{ _("Students") }}
|
||||
</div>
|
||||
|
||||
<div class="mt-2">
|
||||
<svg class="icon icon-sm">
|
||||
<use href="#icon-calendar"></use>
|
||||
@@ -144,7 +141,8 @@
|
||||
{{ _("Checkout Class") }}
|
||||
</a>
|
||||
{% elif class_info.paid_class %}
|
||||
<a class="btn btn-primary wide-button" href="/billing/class/{{ class_info.name }}">
|
||||
<a class="btn btn-primary wide-button {% if class_info.seat_count and not seats_left %} hide {% endif %}"
|
||||
href="/billing/class/{{ class_info.name }}">
|
||||
{{ _("Register Now") }}
|
||||
</a>
|
||||
{% else %}
|
||||
@@ -165,13 +163,10 @@
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro Prerequisites(class_info) %}
|
||||
{% macro ClassDetails(class_info) %}
|
||||
<div class="course-description-section w-50">
|
||||
<div class="page-title">
|
||||
{{ _("Prerequisite Knowledge") }}
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
{{ class_info.prerequisite }}
|
||||
{{ class_info.class_details }}
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
@@ -14,7 +14,7 @@ def get_context(context):
|
||||
"name",
|
||||
"title",
|
||||
"description",
|
||||
"prerequisite",
|
||||
"class_details",
|
||||
"start_date",
|
||||
"end_date",
|
||||
"paid_class",
|
||||
@@ -22,6 +22,7 @@ def get_context(context):
|
||||
"currency",
|
||||
"start_time",
|
||||
"end_time",
|
||||
"seat_count",
|
||||
],
|
||||
as_dict=1,
|
||||
)
|
||||
@@ -40,12 +41,8 @@ def get_context(context):
|
||||
)
|
||||
)
|
||||
|
||||
context.students = frappe.get_all(
|
||||
"Class Student",
|
||||
{"parent": class_name},
|
||||
["name", "student", "student_name", "username"],
|
||||
order_by="creation desc",
|
||||
)
|
||||
context.student_count = frappe.db.count("Class Student", {"parent": class_name})
|
||||
context.seats_left = context.class_info.seat_count - context.student_count
|
||||
|
||||
context.is_moderator = has_course_moderator_role()
|
||||
context.is_evaluator = has_course_evaluator_role()
|
||||
|
||||
@@ -90,11 +90,21 @@
|
||||
{% macro ClassCards(classes, show_price=False) %}
|
||||
<div class="lms-card-parent">
|
||||
{% for class in classes %}
|
||||
{% set course_count = frappe.db.count("Class Course", {"parent": class.name}) %}
|
||||
{% set student_count = frappe.db.count("Class Student", {"parent": class.name}) %}
|
||||
|
||||
<div class="common-card-style column-card" style="min-height: 150px;">
|
||||
|
||||
{% if class.seat_count %}
|
||||
{% if class.seats_left > 0 %}
|
||||
<div class="indicator-pill green align-self-start mb-2">
|
||||
{{ _("Seats Available") }}: {{ class.seats_left }}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="indicator-pill red align-self-start mb-2">
|
||||
{{ _("No Seats Left") }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<div class="bold-heading">
|
||||
{{ class.title }}
|
||||
</div>
|
||||
@@ -127,15 +137,15 @@
|
||||
<svg class="icon icon-md">
|
||||
<use href="#icon-education"></use>
|
||||
</svg>
|
||||
{{ course_count }} {{ _("Courses") }}
|
||||
{{ class.course_count }} {{ _("Courses") }}
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<!-- <div class="mb-2">
|
||||
<svg class="icon icon-md">
|
||||
<use href="#icon-users"></use>
|
||||
</svg>
|
||||
{{ student_count }} {{ _("Students") }}
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
{% if is_student(class.name) %}
|
||||
<a class="stretched-link" href="/classes/{{ class.name }}"></a>
|
||||
|
||||
@@ -20,10 +20,17 @@ def get_context(context):
|
||||
"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:
|
||||
@@ -39,13 +46,31 @@ def get_context(context):
|
||||
)
|
||||
|
||||
for class_ in my_classes:
|
||||
my_classes_info.append(
|
||||
frappe.db.get_value(
|
||||
"LMS Class",
|
||||
class_,
|
||||
["name", "title", "start_date", "end_date", "paid_class", "seat_count"],
|
||||
as_dict=True,
|
||||
)
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user