diff --git a/lms/lms/doctype/class_student/class_student.json b/lms/lms/doctype/class_student/class_student.json index 819050fc..28a00a8d 100644 --- a/lms/lms/doctype/class_student/class_student.json +++ b/lms/lms/doctype/class_student/class_student.json @@ -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", diff --git a/lms/lms/doctype/lms_batch_membership/lms_batch_membership.json b/lms/lms/doctype/lms_batch_membership/lms_batch_membership.json index 10a8e93d..35ed4e2c 100644 --- a/lms/lms/doctype/lms_batch_membership/lms_batch_membership.json +++ b/lms/lms/doctype/lms_batch_membership/lms_batch_membership.json @@ -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", diff --git a/lms/lms/doctype/lms_class/lms_class.json b/lms/lms/doctype/lms_class/lms_class.json index b80cfa21..dec60488 100644 --- a/lms/lms/doctype/lms_class/lms_class.json +++ b/lms/lms/doctype/lms_class/lms_class.json @@ -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", diff --git a/lms/lms/doctype/lms_class/lms_class.py b/lms/lms/doctype/lms_class/lms_class.py index f7457ecd..77516171 100644 --- a/lms/lms/doctype/lms_class/lms_class.py +++ b/lms/lms/doctype/lms_class/lms_class.py @@ -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() diff --git a/lms/lms/doctype/lms_payment/__init__.py b/lms/lms/doctype/lms_payment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lms/lms/doctype/lms_payment/lms_payment.js b/lms/lms/doctype/lms_payment/lms_payment.js new file mode 100644 index 00000000..11d42cab --- /dev/null +++ b/lms/lms/doctype/lms_payment/lms_payment.js @@ -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) { + +// }, +// }); diff --git a/lms/lms/doctype/lms_payment/lms_payment.json b/lms/lms/doctype/lms_payment/lms_payment.json new file mode 100644 index 00000000..f89bc595 --- /dev/null +++ b/lms/lms/doctype/lms_payment/lms_payment.json @@ -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" +} \ No newline at end of file diff --git a/lms/lms/doctype/lms_payment/lms_payment.py b/lms/lms/doctype/lms_payment/lms_payment.py new file mode 100644 index 00000000..a250fd99 --- /dev/null +++ b/lms/lms/doctype/lms_payment/lms_payment.py @@ -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 diff --git a/lms/lms/doctype/lms_payment/test_lms_payment.py b/lms/lms/doctype/lms_payment/test_lms_payment.py new file mode 100644 index 00000000..3589140d --- /dev/null +++ b/lms/lms/doctype/lms_payment/test_lms_payment.py @@ -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 diff --git a/lms/lms/utils.py b/lms/lms/utils.py index 2385625b..baad5bfa 100644 --- a/lms/lms/utils.py +++ b/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}" diff --git a/lms/public/css/style.css b/lms/public/css/style.css index 35401e67..d140850e 100644 --- a/lms/public/css/style.css +++ b/lms/public/css/style.css @@ -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); diff --git a/lms/public/js/common_functions.js b/lms/public/js/common_functions.js index b70e26f7..8a1149b8 100644 --- a/lms/public/js/common_functions.js +++ b/lms/public/js/common_functions.js @@ -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, }, { diff --git a/lms/www/billing/billing.js b/lms/www/billing/billing.js index 9ff7480f..4f719057 100644 --- a/lms/www/billing/billing.js +++ b/lms/www/billing/billing.js @@ -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), diff --git a/lms/www/classes/class.py b/lms/www/classes/class.py index aea79520..553721db 100644 --- a/lms/www/classes/class.py +++ b/lms/www/classes/class.py @@ -39,7 +39,7 @@ def get_context(context): "paid_class", "amount", "currency", - "prerequisite", + "class_details", ], as_dict=True, ) diff --git a/lms/www/classes/class_details.html b/lms/www/classes/class_details.html index dff32a70..c59853b2 100644 --- a/lms/www/classes/class_details.html +++ b/lms/www/classes/class_details.html @@ -10,7 +10,7 @@