From 1babc5f367e5f114741dd29f063d68b4c308b113 Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Fri, 8 Apr 2022 08:05:10 +0530 Subject: [PATCH 001/106] feat: separated discount accounting settings for sales and purchase --- .../buying_settings/buying_settings.json | 10 ++- .../buying_settings/buying_settings.py | 62 +++++++++++++++++++ .../selling_settings/selling_settings.json | 12 +++- .../selling_settings/selling_settings.py | 58 +++++++++++++++++ 4 files changed, 139 insertions(+), 3 deletions(-) diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.json b/erpnext/buying/doctype/buying_settings/buying_settings.json index 50321baa2e..90e6975f64 100644 --- a/erpnext/buying/doctype/buying_settings/buying_settings.json +++ b/erpnext/buying/doctype/buying_settings/buying_settings.json @@ -20,6 +20,7 @@ "maintain_same_rate", "allow_multiple_items", "bill_for_rejected_quantity_in_purchase_invoice", + "enable_discount_accounting", "subcontract", "backflush_raw_materials_of_subcontract_based_on", "column_break_11", @@ -133,6 +134,13 @@ { "fieldname": "column_break_12", "fieldtype": "Column Break" + }, + { + "default": "0", + "description": "If enabled, additional ledger entries will be made for discounts in a separate Discount Account", + "fieldname": "enable_discount_accounting", + "fieldtype": "Check", + "label": "Enable Discount Accounting" } ], "icon": "fa fa-cog", @@ -140,7 +148,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2022-01-27 17:57:58.367048", + "modified": "2022-04-08 07:48:12.632498", "modified_by": "Administrator", "module": "Buying", "name": "Buying Settings", diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.py b/erpnext/buying/doctype/buying_settings/buying_settings.py index 5507254bbc..4d266e1264 100644 --- a/erpnext/buying/doctype/buying_settings/buying_settings.py +++ b/erpnext/buying/doctype/buying_settings/buying_settings.py @@ -6,9 +6,14 @@ import frappe from frappe.model.document import Document +from frappe.custom.doctype.property_setter.property_setter import make_property_setter +from frappe.utils import cint class BuyingSettings(Document): + def on_update(self): + self.toggle_discount_accounting_fields() + def validate(self): for key in ["supplier_group", "supp_master_name", "maintain_same_rate", "buying_price_list"]: frappe.db.set_default(key, self.get(key, "")) @@ -21,3 +26,60 @@ class BuyingSettings(Document): self.get("supp_master_name") == "Naming Series", hide_name_field=False, ) + + def toggle_discount_accounting_fields(self): + enable_discount_accounting = cint(self.enable_discount_accounting) + + make_property_setter( + "Purchase Invoice Item", + "discount_account", + "hidden", + not (enable_discount_accounting), + "Check", + validate_fields_for_doctype=False, + ) + if enable_discount_accounting: + make_property_setter( + "Purchase Invoice Item", + "discount_account", + "mandatory_depends_on", + "eval: doc.discount_amount", + "Code", + validate_fields_for_doctype=False, + ) + else: + make_property_setter( + "Purchase Invoice Item", + "discount_account", + "mandatory_depends_on", + "", + "Code", + validate_fields_for_doctype=False, + ) + + make_property_setter( + "Purchase Invoice", + "additional_discount_account", + "hidden", + not (enable_discount_accounting), + "Check", + validate_fields_for_doctype=False, + ) + if enable_discount_accounting: + make_property_setter( + "Purchase Invoice", + "additional_discount_account", + "mandatory_depends_on", + "eval: doc.discount_amount", + "Code", + validate_fields_for_doctype=False, + ) + else: + make_property_setter( + "Purchase Invoice", + "additional_discount_account", + "mandatory_depends_on", + "", + "Code", + validate_fields_for_doctype=False, + ) \ No newline at end of file diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.json b/erpnext/selling/doctype/selling_settings/selling_settings.json index 7c4a3f63dc..2c880ee029 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.json +++ b/erpnext/selling/doctype/selling_settings/selling_settings.json @@ -27,7 +27,8 @@ "column_break_5", "allow_multiple_items", "allow_against_multiple_purchase_orders", - "hide_tax_id" + "hide_tax_id", + "enable_discount_accounting" ], "fields": [ { @@ -164,6 +165,13 @@ "fieldname": "editable_bundle_item_rates", "fieldtype": "Check", "label": "Calculate Product Bundle Price based on Child Items' Rates" + }, + { + "default": "0", + "description": "If enabled, additional ledger entries will be made for discounts in a separate Discount Account", + "fieldname": "enable_discount_accounting", + "fieldtype": "Check", + "label": "Enable Discount Accounting" } ], "icon": "fa fa-cog", @@ -171,7 +179,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2022-02-04 15:41:59.939261", + "modified": "2022-04-08 07:48:48.074220", "modified_by": "Administrator", "module": "Selling", "name": "Selling Settings", diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.py b/erpnext/selling/doctype/selling_settings/selling_settings.py index 29e4712be3..c656c52c17 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.py +++ b/erpnext/selling/doctype/selling_settings/selling_settings.py @@ -14,6 +14,7 @@ class SellingSettings(Document): def on_update(self): self.toggle_hide_tax_id() self.toggle_editable_rate_for_bundle_items() + self.toggle_discount_accounting_fields() def validate(self): for key in [ @@ -58,3 +59,60 @@ class SellingSettings(Document): "Check", validate_fields_for_doctype=False, ) + + def toggle_discount_accounting_fields(self): + enable_discount_accounting = cint(self.enable_discount_accounting) + + make_property_setter( + "Sales Invoice Item", + "discount_account", + "hidden", + not (enable_discount_accounting), + "Check", + validate_fields_for_doctype=False, + ) + if enable_discount_accounting: + make_property_setter( + "Sales Invoice Item", + "discount_account", + "mandatory_depends_on", + "eval: doc.discount_amount", + "Code", + validate_fields_for_doctype=False, + ) + else: + make_property_setter( + "Sales Invoice Item", + "discount_account", + "mandatory_depends_on", + "", + "Code", + validate_fields_for_doctype=False, + ) + + make_property_setter( + "Sales Invoice", + "additional_discount_account", + "hidden", + not (enable_discount_accounting), + "Check", + validate_fields_for_doctype=False, + ) + if enable_discount_accounting: + make_property_setter( + "Sales Invoice", + "additional_discount_account", + "mandatory_depends_on", + "eval: doc.discount_amount", + "Code", + validate_fields_for_doctype=False, + ) + else: + make_property_setter( + "Sales Invoice", + "additional_discount_account", + "mandatory_depends_on", + "", + "Code", + validate_fields_for_doctype=False, + ) \ No newline at end of file From 0fcdf1b6137306dfadab0dc5f3389416d3898121 Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Fri, 8 Apr 2022 08:10:27 +0530 Subject: [PATCH 002/106] removed discount-accounting from account settings --- .../accounts_settings/accounts_settings.py | 69 ------------------- 1 file changed, 69 deletions(-) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py index 835498176c..3b125a2986 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py @@ -28,7 +28,6 @@ class AccountsSettings(Document): self.validate_stale_days() self.enable_payment_schedule_in_print() - self.toggle_discount_accounting_fields() self.validate_pending_reposts() def validate_stale_days(self): @@ -52,74 +51,6 @@ class AccountsSettings(Document): validate_fields_for_doctype=False, ) - def toggle_discount_accounting_fields(self): - enable_discount_accounting = cint(self.enable_discount_accounting) - - for doctype in ["Sales Invoice Item", "Purchase Invoice Item"]: - make_property_setter( - doctype, - "discount_account", - "hidden", - not (enable_discount_accounting), - "Check", - validate_fields_for_doctype=False, - ) - if enable_discount_accounting: - make_property_setter( - doctype, - "discount_account", - "mandatory_depends_on", - "eval: doc.discount_amount", - "Code", - validate_fields_for_doctype=False, - ) - else: - make_property_setter( - doctype, - "discount_account", - "mandatory_depends_on", - "", - "Code", - validate_fields_for_doctype=False, - ) - - for doctype in ["Sales Invoice", "Purchase Invoice"]: - make_property_setter( - doctype, - "additional_discount_account", - "hidden", - not (enable_discount_accounting), - "Check", - validate_fields_for_doctype=False, - ) - if enable_discount_accounting: - make_property_setter( - doctype, - "additional_discount_account", - "mandatory_depends_on", - "eval: doc.discount_amount", - "Code", - validate_fields_for_doctype=False, - ) - else: - make_property_setter( - doctype, - "additional_discount_account", - "mandatory_depends_on", - "", - "Code", - validate_fields_for_doctype=False, - ) - - make_property_setter( - "Item", - "default_discount_account", - "hidden", - not (enable_discount_accounting), - "Check", - validate_fields_for_doctype=False, - ) - def validate_pending_reposts(self): if self.acc_frozen_upto: check_pending_reposting(self.acc_frozen_upto) From b6ce49760132dac9b61d20fd05a68590004050ac Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Fri, 8 Apr 2022 15:08:21 +0530 Subject: [PATCH 003/106] fix: removed discount account field from account settings --- .../doctype/accounts_settings/accounts_settings.json | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index 9a35a247dd..417611fecd 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -18,7 +18,6 @@ "automatically_fetch_payment_terms", "column_break_17", "enable_common_party_accounting", - "enable_discount_accounting", "report_setting_section", "use_custom_cash_flow", "deferred_accounting_settings_section", @@ -272,13 +271,6 @@ "fieldtype": "Check", "label": "Create Ledger Entries for Change Amount" }, - { - "default": "0", - "description": "If enabled, additional ledger entries will be made for discounts in a separate Discount Account", - "fieldname": "enable_discount_accounting", - "fieldtype": "Check", - "label": "Enable Discount Accounting" - }, { "default": "0", "description": "Learn about Common Party", @@ -354,7 +346,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2022-02-04 12:32:36.805652", + "modified": "2022-04-08 14:45:06.796418", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", From 786887768ee5d7063915cdd30e3e222df22fa5de Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Fri, 8 Apr 2022 08:10:27 +0530 Subject: [PATCH 004/106] fix: removed discount-accounting code from account settings --- .../accounts_settings/accounts_settings.py | 69 ------------------- 1 file changed, 69 deletions(-) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py index 835498176c..3b125a2986 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py @@ -28,7 +28,6 @@ class AccountsSettings(Document): self.validate_stale_days() self.enable_payment_schedule_in_print() - self.toggle_discount_accounting_fields() self.validate_pending_reposts() def validate_stale_days(self): @@ -52,74 +51,6 @@ class AccountsSettings(Document): validate_fields_for_doctype=False, ) - def toggle_discount_accounting_fields(self): - enable_discount_accounting = cint(self.enable_discount_accounting) - - for doctype in ["Sales Invoice Item", "Purchase Invoice Item"]: - make_property_setter( - doctype, - "discount_account", - "hidden", - not (enable_discount_accounting), - "Check", - validate_fields_for_doctype=False, - ) - if enable_discount_accounting: - make_property_setter( - doctype, - "discount_account", - "mandatory_depends_on", - "eval: doc.discount_amount", - "Code", - validate_fields_for_doctype=False, - ) - else: - make_property_setter( - doctype, - "discount_account", - "mandatory_depends_on", - "", - "Code", - validate_fields_for_doctype=False, - ) - - for doctype in ["Sales Invoice", "Purchase Invoice"]: - make_property_setter( - doctype, - "additional_discount_account", - "hidden", - not (enable_discount_accounting), - "Check", - validate_fields_for_doctype=False, - ) - if enable_discount_accounting: - make_property_setter( - doctype, - "additional_discount_account", - "mandatory_depends_on", - "eval: doc.discount_amount", - "Code", - validate_fields_for_doctype=False, - ) - else: - make_property_setter( - doctype, - "additional_discount_account", - "mandatory_depends_on", - "", - "Code", - validate_fields_for_doctype=False, - ) - - make_property_setter( - "Item", - "default_discount_account", - "hidden", - not (enable_discount_accounting), - "Check", - validate_fields_for_doctype=False, - ) - def validate_pending_reposts(self): if self.acc_frozen_upto: check_pending_reposting(self.acc_frozen_upto) From 171c60ff37d6e1f95378a049f0fec66189aeac90 Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Fri, 8 Apr 2022 15:08:21 +0530 Subject: [PATCH 005/106] fix: removed discount account field from account settings --- .../doctype/accounts_settings/accounts_settings.json | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index 9a35a247dd..417611fecd 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -18,7 +18,6 @@ "automatically_fetch_payment_terms", "column_break_17", "enable_common_party_accounting", - "enable_discount_accounting", "report_setting_section", "use_custom_cash_flow", "deferred_accounting_settings_section", @@ -272,13 +271,6 @@ "fieldtype": "Check", "label": "Create Ledger Entries for Change Amount" }, - { - "default": "0", - "description": "If enabled, additional ledger entries will be made for discounts in a separate Discount Account", - "fieldname": "enable_discount_accounting", - "fieldtype": "Check", - "label": "Enable Discount Accounting" - }, { "default": "0", "description": "Learn about Common Party", @@ -354,7 +346,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2022-02-04 12:32:36.805652", + "modified": "2022-04-08 14:45:06.796418", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", From 35e875c11131465fe41be6a215c74cf81d47e67e Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Fri, 8 Apr 2022 17:27:53 +0530 Subject: [PATCH 006/106] fix(patch): enable discount account in buying and selling if exist in accounts settings --- .../v14_0/discount_accounting_separation.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 erpnext/patches/v14_0/discount_accounting_separation.py diff --git a/erpnext/patches/v14_0/discount_accounting_separation.py b/erpnext/patches/v14_0/discount_accounting_separation.py new file mode 100644 index 0000000000..bb236f783a --- /dev/null +++ b/erpnext/patches/v14_0/discount_accounting_separation.py @@ -0,0 +1,14 @@ +import frappe + +def execute(): + doc = frappe.get_doc("Accounts Settings") + discount_account = doc.enable_discount_accounting + if discount_account: + buying_settings = frappe.get_doc("Buying Settings") + selling_settings = frappe.get_doc("Selling Settings") + + buying_settings.enable_discount_accounting = 1 + selling_settings.enable_discount_accounting = 1 + + buying_settings.save() + selling_settings.save() \ No newline at end of file From 2173c8b11478e76f32807a6253b28456ba016239 Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Fri, 8 Apr 2022 17:29:08 +0530 Subject: [PATCH 007/106] fix(pathces): added to patches.txt --- erpnext/patches.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index a3bf78b532..24354c3842 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -364,3 +364,4 @@ erpnext.patches.v13_0.add_cost_center_in_loans erpnext.patches.v13_0.set_return_against_in_pos_invoice_references erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022 erpnext.patches.v13_0.update_expense_claim_status_for_paid_advances +erpnext.patches.v14_0.discount_accounting_separation \ No newline at end of file From ac7f1cbd87efe933f785a3476a478bb773bb7601 Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Fri, 8 Apr 2022 17:46:49 +0530 Subject: [PATCH 008/106] fix: minor fix --- erpnext/patches/v14_0/discount_accounting_separation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/patches/v14_0/discount_accounting_separation.py b/erpnext/patches/v14_0/discount_accounting_separation.py index bb236f783a..e7e4a2ebcf 100644 --- a/erpnext/patches/v14_0/discount_accounting_separation.py +++ b/erpnext/patches/v14_0/discount_accounting_separation.py @@ -4,8 +4,8 @@ def execute(): doc = frappe.get_doc("Accounts Settings") discount_account = doc.enable_discount_accounting if discount_account: - buying_settings = frappe.get_doc("Buying Settings") - selling_settings = frappe.get_doc("Selling Settings") + buying_settings = frappe.get_doc("Buying Settings", "Buying Settings") + selling_settings = frappe.get_doc("Selling Settings", "Selling Settings") buying_settings.enable_discount_accounting = 1 selling_settings.enable_discount_accounting = 1 From ac16f3b71fc403d2ad1f37f7ca54dc6236aa909c Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Fri, 8 Apr 2022 18:20:41 +0530 Subject: [PATCH 009/106] fix: lock timeout exceeded --- .../patches/v14_0/discount_accounting_separation.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/erpnext/patches/v14_0/discount_accounting_separation.py b/erpnext/patches/v14_0/discount_accounting_separation.py index e7e4a2ebcf..3d4907cca3 100644 --- a/erpnext/patches/v14_0/discount_accounting_separation.py +++ b/erpnext/patches/v14_0/discount_accounting_separation.py @@ -4,11 +4,5 @@ def execute(): doc = frappe.get_doc("Accounts Settings") discount_account = doc.enable_discount_accounting if discount_account: - buying_settings = frappe.get_doc("Buying Settings", "Buying Settings") - selling_settings = frappe.get_doc("Selling Settings", "Selling Settings") - - buying_settings.enable_discount_accounting = 1 - selling_settings.enable_discount_accounting = 1 - - buying_settings.save() - selling_settings.save() \ No newline at end of file + for doctype in ["Buying Settings", "Selling Settings"]: + doc = frappe.db.set_value(doctype, doctype, 'enable_discount_accounting', 1, update_modified=False) \ No newline at end of file From dc2944a0410811ce800107fbb3a531b5eb440498 Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Sat, 9 Apr 2022 03:55:25 +0530 Subject: [PATCH 010/106] fix[minor]: removed doc assignment --- erpnext/patches/v14_0/discount_accounting_separation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches/v14_0/discount_accounting_separation.py b/erpnext/patches/v14_0/discount_accounting_separation.py index 3d4907cca3..a814522a38 100644 --- a/erpnext/patches/v14_0/discount_accounting_separation.py +++ b/erpnext/patches/v14_0/discount_accounting_separation.py @@ -5,4 +5,4 @@ def execute(): discount_account = doc.enable_discount_accounting if discount_account: for doctype in ["Buying Settings", "Selling Settings"]: - doc = frappe.db.set_value(doctype, doctype, 'enable_discount_accounting', 1, update_modified=False) \ No newline at end of file + frappe.db.set_value(doctype, doctype, 'enable_discount_accounting', 1, update_modified=False) \ No newline at end of file From a7a574237502446885e3a2e2c255920e4045dcd7 Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Mon, 11 Apr 2022 14:28:36 +0530 Subject: [PATCH 011/106] fix: merge conflict(patch) --- erpnext/patches.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 24354c3842..46d6e93db5 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -364,4 +364,5 @@ erpnext.patches.v13_0.add_cost_center_in_loans erpnext.patches.v13_0.set_return_against_in_pos_invoice_references erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022 erpnext.patches.v13_0.update_expense_claim_status_for_paid_advances +erpnext.patches.v13_0.create_gst_custom_fields_in_quotation erpnext.patches.v14_0.discount_accounting_separation \ No newline at end of file From 0eff74c6500a229c5ff80f15a45fdf889add52e7 Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Thu, 14 Apr 2022 15:42:16 +0530 Subject: [PATCH 012/106] fix: tabspacing --- .../patches/v14_0/discount_accounting_separation.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/erpnext/patches/v14_0/discount_accounting_separation.py b/erpnext/patches/v14_0/discount_accounting_separation.py index a814522a38..fd498052d8 100644 --- a/erpnext/patches/v14_0/discount_accounting_separation.py +++ b/erpnext/patches/v14_0/discount_accounting_separation.py @@ -1,8 +1,9 @@ import frappe + def execute(): - doc = frappe.get_doc("Accounts Settings") - discount_account = doc.enable_discount_accounting - if discount_account: - for doctype in ["Buying Settings", "Selling Settings"]: - frappe.db.set_value(doctype, doctype, 'enable_discount_accounting', 1, update_modified=False) \ No newline at end of file + doc = frappe.get_doc("Accounts Settings") + discount_account = doc.enable_discount_accounting + if discount_account: + for doctype in ["Buying Settings", "Selling Settings"]: + frappe.db.set_value(doctype, doctype, "enable_discount_accounting", 1, update_modified=False) From 01fde15bd5a0c111eadd567323b15f04d10731cc Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Thu, 14 Apr 2022 15:48:55 +0530 Subject: [PATCH 013/106] fix: dependent codes updated --- .../accounts/doctype/purchase_invoice/purchase_invoice.py | 6 +++--- erpnext/accounts/doctype/sales_invoice/sales_invoice.py | 6 +++--- erpnext/controllers/accounts_controller.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index e6a46d0676..a222dd98e9 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -669,7 +669,7 @@ class PurchaseInvoice(BuyingController): exchange_rate_map, net_rate_map = get_purchase_document_details(self) enable_discount_accounting = cint( - frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting") + frappe.db.get_single_value("Buying Settings", "enable_discount_accounting") ) provisional_accounting_for_non_stock_items = cint( frappe.db.get_value( @@ -1157,7 +1157,7 @@ class PurchaseInvoice(BuyingController): # tax table gl entries valuation_tax = {} enable_discount_accounting = cint( - frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting") + frappe.db.get_single_value("Buying Settings", "enable_discount_accounting") ) for tax in self.get("taxes"): @@ -1250,7 +1250,7 @@ class PurchaseInvoice(BuyingController): def enable_discount_accounting(self): if not hasattr(self, "_enable_discount_accounting"): self._enable_discount_accounting = cint( - frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting") + frappe.db.get_single_value("Buying Settings", "enable_discount_accounting") ) return self._enable_discount_accounting diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 1efd3dca0d..dd85d99a8c 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -1051,7 +1051,7 @@ class SalesInvoice(SellingController): def make_tax_gl_entries(self, gl_entries): enable_discount_accounting = cint( - frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting") + frappe.db.get_single_value("Selling Settings", "enable_discount_accounting") ) for tax in self.get("taxes"): @@ -1097,7 +1097,7 @@ class SalesInvoice(SellingController): def make_item_gl_entries(self, gl_entries): # income account gl entries enable_discount_accounting = cint( - frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting") + frappe.db.get_single_value("Selling Settings", "enable_discount_accounting") ) for item in self.get("items"): @@ -1276,7 +1276,7 @@ class SalesInvoice(SellingController): def enable_discount_accounting(self): if not hasattr(self, "_enable_discount_accounting"): self._enable_discount_accounting = cint( - frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting") + frappe.db.get_single_value("Selling Settings", "enable_discount_accounting") ) return self._enable_discount_accounting diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 7cbd2bd6c7..5ebbb7a3f0 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1080,7 +1080,7 @@ class AccountsController(TransactionBase): def make_discount_gl_entries(self, gl_entries): enable_discount_accounting = cint( - frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting") + frappe.db.get_single_value("Selling Settings", "enable_discount_accounting") ) if enable_discount_accounting: From 4130493b589cea2e4bfb0fe98cc7fcca2e64f45f Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Thu, 14 Apr 2022 16:03:08 +0530 Subject: [PATCH 014/106] fix: Label typo --- erpnext/buying/doctype/buying_settings/buying_settings.json | 4 ++-- .../selling/doctype/selling_settings/selling_settings.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.json b/erpnext/buying/doctype/buying_settings/buying_settings.json index 90e6975f64..89a9448716 100644 --- a/erpnext/buying/doctype/buying_settings/buying_settings.json +++ b/erpnext/buying/doctype/buying_settings/buying_settings.json @@ -140,7 +140,7 @@ "description": "If enabled, additional ledger entries will be made for discounts in a separate Discount Account", "fieldname": "enable_discount_accounting", "fieldtype": "Check", - "label": "Enable Discount Accounting" + "label": "Enable Discount Accounting for Buying" } ], "icon": "fa fa-cog", @@ -148,7 +148,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2022-04-08 07:48:12.632498", + "modified": "2022-04-14 15:56:42.340223", "modified_by": "Administrator", "module": "Buying", "name": "Buying Settings", diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.json b/erpnext/selling/doctype/selling_settings/selling_settings.json index 2c880ee029..005e24cfbe 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.json +++ b/erpnext/selling/doctype/selling_settings/selling_settings.json @@ -171,7 +171,7 @@ "description": "If enabled, additional ledger entries will be made for discounts in a separate Discount Account", "fieldname": "enable_discount_accounting", "fieldtype": "Check", - "label": "Enable Discount Accounting" + "label": "Enable Discount Accounting for Selling" } ], "icon": "fa fa-cog", @@ -179,7 +179,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2022-04-08 07:48:48.074220", + "modified": "2022-04-14 16:01:29.405642", "modified_by": "Administrator", "module": "Selling", "name": "Selling Settings", From ebb7bc201b900df0f335b898494cc68b5a93366f Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Mon, 18 Apr 2022 14:53:45 +0530 Subject: [PATCH 015/106] fix: library import formatting --- erpnext/buying/doctype/buying_settings/buying_settings.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.py b/erpnext/buying/doctype/buying_settings/buying_settings.py index 4d266e1264..c52b59e4c0 100644 --- a/erpnext/buying/doctype/buying_settings/buying_settings.py +++ b/erpnext/buying/doctype/buying_settings/buying_settings.py @@ -5,8 +5,8 @@ import frappe -from frappe.model.document import Document from frappe.custom.doctype.property_setter.property_setter import make_property_setter +from frappe.model.document import Document from frappe.utils import cint @@ -26,7 +26,7 @@ class BuyingSettings(Document): self.get("supp_master_name") == "Naming Series", hide_name_field=False, ) - + def toggle_discount_accounting_fields(self): enable_discount_accounting = cint(self.enable_discount_accounting) @@ -82,4 +82,4 @@ class BuyingSettings(Document): "", "Code", validate_fields_for_doctype=False, - ) \ No newline at end of file + ) From bcfbb3e9c8d3cfc6818d21032bcf619eb33668aa Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Mon, 18 Apr 2022 15:04:47 +0530 Subject: [PATCH 016/106] fix: code formatting --- erpnext/selling/doctype/selling_settings/selling_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.py b/erpnext/selling/doctype/selling_settings/selling_settings.py index c656c52c17..6c09894251 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.py +++ b/erpnext/selling/doctype/selling_settings/selling_settings.py @@ -115,4 +115,4 @@ class SellingSettings(Document): "", "Code", validate_fields_for_doctype=False, - ) \ No newline at end of file + ) From 0ac11a5b305ecd6002bef94cefe04eba65c13f87 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 20 Apr 2022 12:18:11 +0530 Subject: [PATCH 017/106] fix: First preference to parent cost center rather than round off cost center --- erpnext/accounts/general_ledger.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index f52e517f73..4dbc4d6a72 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -355,7 +355,7 @@ def raise_debit_credit_not_equal_error(debit_credit_diff, voucher_type, voucher_ def make_round_off_gle(gl_map, debit_credit_diff, precision): round_off_account, round_off_cost_center = get_round_off_account_and_cost_center( - gl_map[0].company + gl_map[0].company, gl_map[0].voucher_type, gl_map[0].voucher_no ) round_off_account_exists = False round_off_gle = frappe._dict() @@ -396,10 +396,17 @@ def make_round_off_gle(gl_map, debit_credit_diff, precision): gl_map.append(round_off_gle) -def get_round_off_account_and_cost_center(company): +def get_round_off_account_and_cost_center(company, voucher_type, voucher_no): round_off_account, round_off_cost_center = frappe.get_cached_value( "Company", company, ["round_off_account", "round_off_cost_center"] ) or [None, None] + + # Give first preference to parent cost center for round off GLE + if frappe.db.has_column(voucher_type, "cost_center"): + parent_cost_center = frappe.db.get_value(voucher_type, voucher_no, "cost_center") + if parent_cost_center: + round_off_cost_center = parent_cost_center + if not round_off_account: frappe.throw(_("Please mention Round Off Account in Company")) From f058755ad362d55d45906c4db4a7bbe440adf6e4 Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Wed, 20 Apr 2022 13:24:15 +0530 Subject: [PATCH 018/106] fix: test cases updated --- .../purchase_invoice/test_purchase_invoice.py | 6 +++--- .../doctype/sales_invoice/test_sales_invoice.py | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 59bd637e41..a12f06bc96 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -1589,9 +1589,9 @@ def unlink_payment_on_cancel_of_invoice(enable=1): def enable_discount_accounting(enable=1): - accounts_settings = frappe.get_doc("Accounts Settings") - accounts_settings.enable_discount_accounting = enable - accounts_settings.save() + buying_settings = frappe.get_doc("Buying Settings") + buying_settings.enable_discount_accounting = enable + buying_settings.save() def make_purchase_invoice(**args): diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index caa70d00ef..eaab94108d 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -2685,9 +2685,6 @@ class TestSalesInvoice(unittest.TestCase): ) def test_sales_invoice_with_discount_accounting_enabled(self): - from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import ( - enable_discount_accounting, - ) enable_discount_accounting() @@ -2708,9 +2705,6 @@ class TestSalesInvoice(unittest.TestCase): enable_discount_accounting(enable=0) def test_additional_discount_for_sales_invoice_with_discount_accounting_enabled(self): - from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import ( - enable_discount_accounting, - ) enable_discount_accounting() additional_discount_account = create_account( @@ -3181,6 +3175,12 @@ class TestSalesInvoice(unittest.TestCase): ) +def enable_discount_accounting(enable=1): + selling_settings = frappe.get_doc("Selling Settings") + selling_settings.enable_discount_accounting = enable + selling_settings.save() + + def get_sales_invoice_for_e_invoice(): si = make_sales_invoice_for_ewaybill() si.naming_series = "INV-2020-.#####" From f3fa6ac4c20a87ed55c54ca738b9bedcbc777da3 Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Wed, 20 Apr 2022 16:01:12 +0530 Subject: [PATCH 019/106] fix: account setting seperation gl discount account creation --- erpnext/controllers/accounts_controller.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 8558cea0f0..78645e0d4f 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1079,9 +1079,14 @@ class AccountsController(TransactionBase): return amount, base_amount def make_discount_gl_entries(self, gl_entries): - enable_discount_accounting = cint( - frappe.db.get_single_value("Selling Settings", "enable_discount_accounting") - ) + if self.doctype == "Purchase Invoice": + enable_discount_accounting = cint( + frappe.db.get_single_value("Buying Settings", "enable_discount_accounting") + ) + elif self.doctype == "Sales Invoice": + enable_discount_accounting = cint( + frappe.db.get_single_value("Selling Settings", "enable_discount_accounting") + ) if enable_discount_accounting: if self.doctype == "Purchase Invoice": From 1e143e7479d78a6dd53eeef8a161a1cb6c4e50f1 Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Wed, 20 Apr 2022 16:06:55 +0530 Subject: [PATCH 020/106] fix: use @change_settings to enable_discount_account --- .../purchase_invoice/test_purchase_invoice.py | 13 ++++--------- .../doctype/sales_invoice/test_sales_invoice.py | 14 +++----------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index a12f06bc96..30d26acf3a 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -5,6 +5,7 @@ import unittest import frappe +from frappe.tests.utils import change_settings from frappe.utils import add_days, cint, flt, getdate, nowdate, today import erpnext @@ -336,8 +337,8 @@ class TestPurchaseInvoice(unittest.TestCase): self.assertEqual(discrepancy_caused_by_exchange_rate_diff, amount) + @change_settings("Buying Settings", {"enable_discount_accounting": 1}) def test_purchase_invoice_with_discount_accounting_enabled(self): - enable_discount_accounting() discount_account = create_account( account_name="Discount Account", @@ -353,10 +354,10 @@ class TestPurchaseInvoice(unittest.TestCase): ] check_gl_entries(self, pi.name, expected_gle, nowdate()) - enable_discount_accounting(enable=0) + @change_settings("Buying Settings", {"enable_discount_accounting": 1}) def test_additional_discount_for_purchase_invoice_with_discount_accounting_enabled(self): - enable_discount_accounting() + additional_discount_account = create_account( account_name="Discount Account", parent_account="Indirect Expenses - _TC", @@ -1588,12 +1589,6 @@ def unlink_payment_on_cancel_of_invoice(enable=1): accounts_settings.save() -def enable_discount_accounting(enable=1): - buying_settings = frappe.get_doc("Buying Settings") - buying_settings.enable_discount_accounting = enable - buying_settings.save() - - def make_purchase_invoice(**args): pi = frappe.new_doc("Purchase Invoice") args = frappe._dict(args) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index eaab94108d..98a5755f71 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -7,6 +7,7 @@ import unittest import frappe from frappe.model.dynamic_links import get_dynamic_link_map from frappe.model.naming import make_autoname +from frappe.tests.utils import change_settings from frappe.utils import add_days, flt, getdate, nowdate import erpnext @@ -2684,10 +2685,9 @@ class TestSalesInvoice(unittest.TestCase): sales_invoice.items[0].item_tax_template, "_Test Account Excise Duty @ 10 - _TC" ) + @change_settings("Selling Settings", {"enable_discount_accounting": 1}) def test_sales_invoice_with_discount_accounting_enabled(self): - enable_discount_accounting() - discount_account = create_account( account_name="Discount Account", parent_account="Indirect Expenses - _TC", @@ -2702,11 +2702,10 @@ class TestSalesInvoice(unittest.TestCase): ] check_gl_entries(self, si.name, expected_gle, add_days(nowdate(), -1)) - enable_discount_accounting(enable=0) + @change_settings("Selling Settings", {"enable_discount_accounting": 1}) def test_additional_discount_for_sales_invoice_with_discount_accounting_enabled(self): - enable_discount_accounting() additional_discount_account = create_account( account_name="Discount Account", parent_account="Indirect Expenses - _TC", @@ -2737,7 +2736,6 @@ class TestSalesInvoice(unittest.TestCase): ] check_gl_entries(self, si.name, expected_gle, add_days(nowdate(), -1)) - enable_discount_accounting(enable=0) def test_asset_depreciation_on_sale_with_pro_rata(self): """ @@ -3175,12 +3173,6 @@ class TestSalesInvoice(unittest.TestCase): ) -def enable_discount_accounting(enable=1): - selling_settings = frappe.get_doc("Selling Settings") - selling_settings.enable_discount_accounting = enable - selling_settings.save() - - def get_sales_invoice_for_e_invoice(): si = make_sales_invoice_for_ewaybill() si.naming_series = "INV-2020-.#####" From 13092bcc2dbb312ef5367ca74f6bfe90e72950b2 Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Wed, 20 Apr 2022 16:46:29 +0530 Subject: [PATCH 021/106] fix: enable discount roll_back --- .../doctype/purchase_invoice/test_purchase_invoice.py | 8 ++++++++ .../accounts/doctype/sales_invoice/test_sales_invoice.py | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 30d26acf3a..e894252f5d 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -354,6 +354,7 @@ class TestPurchaseInvoice(unittest.TestCase): ] check_gl_entries(self, pi.name, expected_gle, nowdate()) + enable_discount_accounting(enable=0) @change_settings("Buying Settings", {"enable_discount_accounting": 1}) def test_additional_discount_for_purchase_invoice_with_discount_accounting_enabled(self): @@ -389,6 +390,7 @@ class TestPurchaseInvoice(unittest.TestCase): ] check_gl_entries(self, pi.name, expected_gle, nowdate()) + enable_discount_accounting(enable=0) def test_purchase_invoice_change_naming_series(self): pi = frappe.copy_doc(test_records[1]) @@ -1530,6 +1532,12 @@ class TestPurchaseInvoice(unittest.TestCase): company.save() +def enable_discount_accounting(enable=1): + buying_settings = frappe.get_doc("Buying Settings") + buying_settings.enable_discount_accounting = enable + buying_settings.save() + + def check_gl_entries(doc, voucher_no, expected_gle, posting_date): gl_entries = frappe.db.sql( """select account, debit, credit, posting_date diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 98a5755f71..e4df20f6b7 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -2702,6 +2702,7 @@ class TestSalesInvoice(unittest.TestCase): ] check_gl_entries(self, si.name, expected_gle, add_days(nowdate(), -1)) + enable_discount_accounting(enable=0) @change_settings("Selling Settings", {"enable_discount_accounting": 1}) def test_additional_discount_for_sales_invoice_with_discount_accounting_enabled(self): @@ -2736,6 +2737,7 @@ class TestSalesInvoice(unittest.TestCase): ] check_gl_entries(self, si.name, expected_gle, add_days(nowdate(), -1)) + enable_discount_accounting(enable=0) def test_asset_depreciation_on_sale_with_pro_rata(self): """ @@ -3173,6 +3175,12 @@ class TestSalesInvoice(unittest.TestCase): ) +def enable_discount_accounting(enable=1): + selling_settings = frappe.get_doc("Selling Settings") + selling_settings.enable_discount_accounting = enable + selling_settings.save() + + def get_sales_invoice_for_e_invoice(): si = make_sales_invoice_for_ewaybill() si.naming_series = "INV-2020-.#####" From c3e27b5556bc2ffe1c4bd6ab0b3731b8017af04c Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 20 Apr 2022 19:07:53 +0530 Subject: [PATCH 022/106] fix: Loan doctypes in bank reconciliation --- .../doctype/bank_clearance/bank_clearance.py | 63 ++++++++++++++++++- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py index 96779d75be..ed5a699463 100644 --- a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py +++ b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py @@ -5,7 +5,10 @@ import frappe from frappe import _, msgprint from frappe.model.document import Document -from frappe.utils import flt, fmt_money, getdate, nowdate +from frappe.query_builder.custom import ConstantColumn +from frappe.utils import flt, fmt_money, getdate + +import erpnext form_grid_templates = {"journal_entries": "templates/form_grid/bank_reconciliation_grid.html"} @@ -76,6 +79,52 @@ class BankClearance(Document): as_dict=1, ) + loan_disbursement = frappe.qb.DocType("Loan Disbursement") + + loan_disbursements = ( + frappe.qb.from_(loan_disbursement) + .select( + ConstantColumn("Loan Disbursement").as_("payment_document"), + loan_disbursement.name.as_("payment_entry"), + loan_disbursement.disbursed_amount.as_("credit"), + ConstantColumn(0).as_("debit"), + loan_disbursement.reference_number.as_("cheque_number"), + loan_disbursement.reference_date.as_("cheque_date"), + loan_disbursement.disbursement_date.as_("posting_date"), + loan_disbursement.applicant.as_("against_account"), + ) + .where(loan_disbursement.docstatus == 1) + .where(loan_disbursement.disbursement_date >= self.from_date) + .where(loan_disbursement.disbursement_date <= self.to_date) + .where(loan_disbursement.clearance_date.isnull()) + .where(loan_disbursement.disbursement_account.isin([self.bank_account, self.account])) + .orderby(loan_disbursement.disbursement_date) + .orderby(loan_disbursement.name, frappe.qb.desc) + ).run(as_dict=1) + + loan_repayment = frappe.qb.DocType("Loan Repayment") + + loan_repayments = ( + frappe.qb.from_(loan_repayment) + .select( + ConstantColumn("Loan Repayment").as_("doctype"), + loan_repayment.name.as_("payment_entry"), + loan_repayment.amount_paid.as_("debit"), + ConstantColumn(0).as_("credit"), + loan_repayment.reference_number.as_("cheque_number"), + loan_repayment.reference_date.as_("cheque_date"), + loan_repayment.applicant.as_("against_account"), + loan_repayment.posting_date, + ) + .where(loan_repayment.docstatus == 1) + .where(loan_repayment.clearance_date.isnull()) + .where(loan_repayment.posting_date >= self.from_date) + .where(loan_repayment.posting_date <= self.to_date) + .where(loan_repayment.payment_account.isin([self.bank_account, self.account])) + .orderby(loan_repayment.posting_date) + .orderby(loan_repayment.name, frappe.qb.desc) + ).run(as_dict=1) + pos_sales_invoices, pos_purchase_invoices = [], [] if self.include_pos_transactions: pos_sales_invoices = frappe.db.sql( @@ -114,18 +163,26 @@ class BankClearance(Document): entries = sorted( list(payment_entries) - + list(journal_entries + list(pos_sales_invoices) + list(pos_purchase_invoices)), - key=lambda k: k["posting_date"] or getdate(nowdate()), + + list(journal_entries) + + list(pos_sales_invoices) + + list(pos_purchase_invoices) + + list(loan_disbursements) + + list(loan_repayments), + key=lambda k: getdate(k["posting_date"]), ) self.set("payment_entries", []) self.total_amount = 0.0 + default_currency = erpnext.get_default_currency() for d in entries: row = self.append("payment_entries", {}) amount = flt(d.get("debit", 0)) - flt(d.get("credit", 0)) + if not d.get("account_currency"): + d.account_currency = default_currency + formatted_amount = fmt_money(abs(amount), 2, d.account_currency) d.amount = formatted_amount + " " + (_("Dr") if amount > 0 else _("Cr")) From 3d0e68acaa82aa0e1a6ab50e835f192297bd7bd2 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 20 Apr 2022 19:49:53 +0530 Subject: [PATCH 023/106] fix: select doctype as payment_document --- erpnext/accounts/doctype/bank_clearance/bank_clearance.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py index ed5a699463..0f617b5dda 100644 --- a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py +++ b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py @@ -107,7 +107,7 @@ class BankClearance(Document): loan_repayments = ( frappe.qb.from_(loan_repayment) .select( - ConstantColumn("Loan Repayment").as_("doctype"), + ConstantColumn("Loan Repayment").as_("payment_document"), loan_repayment.name.as_("payment_entry"), loan_repayment.amount_paid.as_("debit"), ConstantColumn(0).as_("credit"), @@ -185,6 +185,7 @@ class BankClearance(Document): formatted_amount = fmt_money(abs(amount), 2, d.account_currency) d.amount = formatted_amount + " " + (_("Dr") if amount > 0 else _("Cr")) + d.posting_date = getdate(d.posting_date) d.pop("credit") d.pop("debit") From 2c78cc2014496ed7f1b358d19b66cacecf8967ec Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Thu, 21 Apr 2022 02:40:59 +0530 Subject: [PATCH 024/106] fix: removed manual rollback - enable discount account --- .../accounts/doctype/purchase_invoice/test_purchase_invoice.py | 2 -- erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index e894252f5d..42455bf431 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -354,7 +354,6 @@ class TestPurchaseInvoice(unittest.TestCase): ] check_gl_entries(self, pi.name, expected_gle, nowdate()) - enable_discount_accounting(enable=0) @change_settings("Buying Settings", {"enable_discount_accounting": 1}) def test_additional_discount_for_purchase_invoice_with_discount_accounting_enabled(self): @@ -390,7 +389,6 @@ class TestPurchaseInvoice(unittest.TestCase): ] check_gl_entries(self, pi.name, expected_gle, nowdate()) - enable_discount_accounting(enable=0) def test_purchase_invoice_change_naming_series(self): pi = frappe.copy_doc(test_records[1]) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index e4df20f6b7..3c52c6ed9a 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -2702,7 +2702,6 @@ class TestSalesInvoice(unittest.TestCase): ] check_gl_entries(self, si.name, expected_gle, add_days(nowdate(), -1)) - enable_discount_accounting(enable=0) @change_settings("Selling Settings", {"enable_discount_accounting": 1}) def test_additional_discount_for_sales_invoice_with_discount_accounting_enabled(self): @@ -2737,7 +2736,6 @@ class TestSalesInvoice(unittest.TestCase): ] check_gl_entries(self, si.name, expected_gle, add_days(nowdate(), -1)) - enable_discount_accounting(enable=0) def test_asset_depreciation_on_sale_with_pro_rata(self): """ From 02e17dbded5cd954563090e659bebd409a808559 Mon Sep 17 00:00:00 2001 From: rahib-hassan Date: Thu, 21 Apr 2022 02:42:42 +0530 Subject: [PATCH 025/106] fix: removed manual enable-discount-account method --- .../accounts/doctype/sales_invoice/test_sales_invoice.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 3c52c6ed9a..98a5755f71 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -3173,12 +3173,6 @@ class TestSalesInvoice(unittest.TestCase): ) -def enable_discount_accounting(enable=1): - selling_settings = frappe.get_doc("Selling Settings") - selling_settings.enable_discount_accounting = enable - selling_settings.save() - - def get_sales_invoice_for_e_invoice(): si = make_sales_invoice_for_ewaybill() si.naming_series = "INV-2020-.#####" From c42547d40f5b23dd0c0a045005c49677863215fd Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 21 Apr 2022 13:26:44 +0530 Subject: [PATCH 026/106] fix: Use parent cost center for Sales and Purchase Invoice --- erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py | 4 +++- erpnext/accounts/doctype/sales_invoice/sales_invoice.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index a5f9e24e15..e37900b02e 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -1369,7 +1369,9 @@ class PurchaseInvoice(BuyingController): if ( not self.is_internal_transfer() and self.rounding_adjustment and self.base_rounding_adjustment ): - round_off_account, round_off_cost_center = get_round_off_account_and_cost_center(self.company) + round_off_account, round_off_cost_center = get_round_off_account_and_cost_center( + self.company, "Purchase Invoice", self.name + ) gl_entries.append( self.get_gl_dict( diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 1efd3dca0d..5b7f1ce8fd 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -1466,7 +1466,9 @@ class SalesInvoice(SellingController): and self.base_rounding_adjustment and not self.is_internal_transfer() ): - round_off_account, round_off_cost_center = get_round_off_account_and_cost_center(self.company) + round_off_account, round_off_cost_center = get_round_off_account_and_cost_center( + self.company, "Sales Invoice", self.name + ) gl_entries.append( self.get_gl_dict( From 8a8476bb5c9e487a80d0631b685a4a596caa297e Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 21 Apr 2022 18:53:18 +0530 Subject: [PATCH 027/106] test: Add test coverage for bank clearance --- .../bank_clearance/test_bank_clearance.py | 121 +++++++++++++++++- 1 file changed, 119 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py index 706fbbe245..fbc44ee312 100644 --- a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py +++ b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py @@ -1,9 +1,126 @@ # Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors # See license.txt -# import frappe import unittest +import frappe +from frappe.utils import add_months, getdate + +from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry +from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice +from erpnext.loan_management.doctype.loan.test_loan import ( + create_loan, + create_loan_accounts, + create_loan_type, + create_repayment_entry, + make_loan_disbursement_entry, +) + class TestBankClearance(unittest.TestCase): - pass + @classmethod + def setUpClass(cls): + make_bank_account() + create_loan_accounts() + create_loan_masters() + add_transactions() + + @classmethod + def tearDownClass(cls): + payment_entry = frappe.get_doc( + "Payment Entry", {"party_name": "_Test Supplier", "paid_from": "_Test Bank Clearance - _TC"} + ) + payment_entry.cancel() + payment_entry.delete() + + loan = frappe.get_doc("Loan", {"applicant": "_Test Customer"}) + + ld_doc = frappe.get_doc("Loan Disbursement", {"against_loan": loan.name}) + ld_doc.cancel() + ld_doc.delete() + + lr_doc = frappe.get_doc("Loan Repayment", {"against_loan": loan.name}) + lr_doc.cancel() + lr_doc.delete() + + lia = frappe.get_doc("Loan Interest Accrual", {"loan": loan.name}) + lia.delete() + + plia = frappe.get_doc("Process Loan Interest Accrual", {"loan": loan.name}) + plia.cancel() + plia.delete() + + loan.load_from_db() + loan.cancel() + loan.flags.ignore_links = True + loan.delete() + + # Basic test case to test if bank clearance tool doesn't break + # Detailed test can be added later + def test_bank_clearance(self): + bank_clearance = frappe.get_doc("Bank Clearance") + bank_clearance.account = "_Test Bank Clearance - _TC" + bank_clearance.from_date = add_months(getdate(), -1) + bank_clearance.to_date = getdate() + bank_clearance.get_payment_entries() + self.assertEqual(len(bank_clearance.payment_entries), 3) + + +def make_bank_account(): + if not frappe.db.get_value("Account", "_Test Bank Clearance - _TC"): + frappe.get_doc( + { + "doctype": "Account", + "account_type": "Bank", + "account_name": "_Test Bank Clearance", + "company": "_Test Company", + "parent_account": "Bank Accounts - _TC", + } + ).insert() + + +def create_loan_masters(): + create_loan_type( + "Clearance Loan", + 2000000, + 13.5, + 25, + 0, + 5, + "Cash", + "_Test Bank Clearance - _TC", + "_Test Bank Clearance - _TC", + "Loan Account - _TC", + "Interest Income Account - _TC", + "Penalty Income Account - _TC", + ) + + +def add_transactions(): + make_payment_entry() + make_loan() + + +def make_loan(): + loan = create_loan( + "_Test Customer", + "Clearance Loan", + 280000, + "Repay Over Number of Periods", + 20, + applicant_type="Customer", + ) + loan.submit() + make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=getdate()) + repayment_entry = create_repayment_entry(loan.name, "_Test Customer", getdate(), loan.loan_amount) + repayment_entry.save() + repayment_entry.submit() + + +def make_payment_entry(): + pi = make_purchase_invoice(supplier="_Test Supplier", qty=1, rate=690) + pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank Clearance - _TC") + pe.reference_no = "Conrad Oct 18" + pe.reference_date = "2018-10-24" + pe.insert() + pe.submit() From 9bb132fdd3d98a149427be3341e268d818e3bfa1 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 22 Apr 2022 13:39:43 +0530 Subject: [PATCH 028/106] fix: Do not validate while creating accounting dimension --- .../doctype/accounting_dimension/accounting_dimension.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py index 445378300b..3f1998a3b3 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py @@ -99,7 +99,7 @@ def make_dimension_in_accounting_doctypes(doc, doclist=None): if doctype == "Budget": add_dimension_to_budget_doctype(df.copy(), doc) else: - create_custom_field(doctype, df) + create_custom_field(doctype, df, ignore_validate=True) count += 1 @@ -115,7 +115,7 @@ def add_dimension_to_budget_doctype(df, doc): } ) - create_custom_field("Budget", df) + create_custom_field("Budget", df, ignore_validate=True) property_setter = frappe.db.exists("Property Setter", "Budget-budget_against-options") From 0eacc99ab705af446a0464f09ac92af760f5d9cf Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sat, 23 Apr 2022 12:08:30 +0530 Subject: [PATCH 029/106] test: Fixes in test case --- .../bank_clearance/test_bank_clearance.py | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py index fbc44ee312..c09aa1c013 100644 --- a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py +++ b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py @@ -30,25 +30,33 @@ class TestBankClearance(unittest.TestCase): payment_entry = frappe.get_doc( "Payment Entry", {"party_name": "_Test Supplier", "paid_from": "_Test Bank Clearance - _TC"} ) - payment_entry.cancel() - payment_entry.delete() + + if payment_entry.docstatus == 1: + payment_entry.cancel() + payment_entry.delete() loan = frappe.get_doc("Loan", {"applicant": "_Test Customer"}) ld_doc = frappe.get_doc("Loan Disbursement", {"against_loan": loan.name}) - ld_doc.cancel() - ld_doc.delete() + + if ld_doc.docstatus == 1: + ld_doc.cancel() + ld_doc.delete() lr_doc = frappe.get_doc("Loan Repayment", {"against_loan": loan.name}) - lr_doc.cancel() - lr_doc.delete() + + if lr_doc.docstatus == 1: + lr_doc.cancel() + lr_doc.delete() lia = frappe.get_doc("Loan Interest Accrual", {"loan": loan.name}) lia.delete() plia = frappe.get_doc("Process Loan Interest Accrual", {"loan": loan.name}) - plia.cancel() - plia.delete() + + if plia.docstatus == 1: + plia.cancel() + plia.delete() loan.load_from_db() loan.cancel() From d4d83f4bb6f34353347f4b613bfe7c9554343425 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sat, 23 Apr 2022 12:33:35 +0530 Subject: [PATCH 030/106] test: Fixes in test case --- .../accounts/doctype/bank_clearance/test_bank_clearance.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py index c09aa1c013..18645c7517 100644 --- a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py +++ b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py @@ -27,6 +27,8 @@ class TestBankClearance(unittest.TestCase): @classmethod def tearDownClass(cls): + frappe.db.set_single_value("Accounts Settings", "delete_linked_ledger_entries", 1) + payment_entry = frappe.get_doc( "Payment Entry", {"party_name": "_Test Supplier", "paid_from": "_Test Bank Clearance - _TC"} ) @@ -63,6 +65,8 @@ class TestBankClearance(unittest.TestCase): loan.flags.ignore_links = True loan.delete() + frappe.db.set_single_value("Accounts Settings", "delete_linked_ledger_entries", 0) + # Basic test case to test if bank clearance tool doesn't break # Detailed test can be added later def test_bank_clearance(self): From 015812b0b8216d0d66e005700691dfa1ace74bf7 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sat, 23 Apr 2022 21:40:08 +0530 Subject: [PATCH 031/106] fix: Add accounting dimensions for round off GL Entry --- erpnext/accounts/general_ledger.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index 4dbc4d6a72..2d36835869 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -392,10 +392,22 @@ def make_round_off_gle(gl_map, debit_credit_diff, precision): } ) + update_accounting_dimensions(round_off_gle) + if not round_off_account_exists: gl_map.append(round_off_gle) +def update_accounting_dimensions(round_off_gle): + dimensions = get_accounting_dimensions() + dimension_values = frappe.db.get_value( + round_off_gle["voucher_type"], round_off_gle["voucher_no"], dimensions + ) + + for dimension in dimensions: + round_off_gle[dimension] = dimension_values.get(dimension) + + def get_round_off_account_and_cost_center(company, voucher_type, voucher_no): round_off_account, round_off_cost_center = frappe.get_cached_value( "Company", company, ["round_off_account", "round_off_cost_center"] From c312cd3725680cff91aa9e41da5a40fa91af7784 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 24 Apr 2022 18:11:32 +0530 Subject: [PATCH 032/106] fix: Check if accounting dimension exists --- erpnext/accounts/general_ledger.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index 2d36835869..56f84c2392 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -400,12 +400,20 @@ def make_round_off_gle(gl_map, debit_credit_diff, precision): def update_accounting_dimensions(round_off_gle): dimensions = get_accounting_dimensions() - dimension_values = frappe.db.get_value( - round_off_gle["voucher_type"], round_off_gle["voucher_no"], dimensions - ) + meta = frappe.get_meta(round_off_gle["voucher_type"]) + has_all_dimensions = True for dimension in dimensions: - round_off_gle[dimension] = dimension_values.get(dimension) + if not meta.has_field(dimension): + has_all_dimensions = False + + if dimensions and has_all_dimensions: + dimension_values = frappe.db.get_value( + round_off_gle["voucher_type"], round_off_gle["voucher_no"], dimensions + ) + + for dimension in dimensions: + round_off_gle[dimension] = dimension_values.get(dimension) def get_round_off_account_and_cost_center(company, voucher_type, voucher_no): @@ -413,8 +421,10 @@ def get_round_off_account_and_cost_center(company, voucher_type, voucher_no): "Company", company, ["round_off_account", "round_off_cost_center"] ) or [None, None] + meta = frappe.get_meta(voucher_type) + # Give first preference to parent cost center for round off GLE - if frappe.db.has_column(voucher_type, "cost_center"): + if meta.has_field("cost_center"): parent_cost_center = frappe.db.get_value(voucher_type, voucher_no, "cost_center") if parent_cost_center: round_off_cost_center = parent_cost_center From c515abc392a8ae6b230ff39e32aae6a8ca4a6dfe Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 24 Apr 2022 19:20:29 +0530 Subject: [PATCH 033/106] test: Remove teardown method --- .../bank_clearance/test_bank_clearance.py | 42 ------------------- 1 file changed, 42 deletions(-) diff --git a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py index 18645c7517..c1e55f6f72 100644 --- a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py +++ b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py @@ -25,48 +25,6 @@ class TestBankClearance(unittest.TestCase): create_loan_masters() add_transactions() - @classmethod - def tearDownClass(cls): - frappe.db.set_single_value("Accounts Settings", "delete_linked_ledger_entries", 1) - - payment_entry = frappe.get_doc( - "Payment Entry", {"party_name": "_Test Supplier", "paid_from": "_Test Bank Clearance - _TC"} - ) - - if payment_entry.docstatus == 1: - payment_entry.cancel() - payment_entry.delete() - - loan = frappe.get_doc("Loan", {"applicant": "_Test Customer"}) - - ld_doc = frappe.get_doc("Loan Disbursement", {"against_loan": loan.name}) - - if ld_doc.docstatus == 1: - ld_doc.cancel() - ld_doc.delete() - - lr_doc = frappe.get_doc("Loan Repayment", {"against_loan": loan.name}) - - if lr_doc.docstatus == 1: - lr_doc.cancel() - lr_doc.delete() - - lia = frappe.get_doc("Loan Interest Accrual", {"loan": loan.name}) - lia.delete() - - plia = frappe.get_doc("Process Loan Interest Accrual", {"loan": loan.name}) - - if plia.docstatus == 1: - plia.cancel() - plia.delete() - - loan.load_from_db() - loan.cancel() - loan.flags.ignore_links = True - loan.delete() - - frappe.db.set_single_value("Accounts Settings", "delete_linked_ledger_entries", 0) - # Basic test case to test if bank clearance tool doesn't break # Detailed test can be added later def test_bank_clearance(self): From d6a43a39aef6915276e9d433f0d2d085c045ab27 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 25 Apr 2022 11:46:01 +0530 Subject: [PATCH 034/106] test: tie breaking in SLEs (#30796) [skip ci] --- .../test_stock_ledger_entry.py | 59 ++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py index b4fac82935..5850ec7be6 100644 --- a/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py +++ b/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py @@ -2,12 +2,12 @@ # See license.txt import json -from datetime import timedelta from uuid import uuid4 import frappe from frappe.core.page.permission_manager.permission_manager import reset from frappe.custom.doctype.property_setter.property_setter import make_property_setter +from frappe.query_builder.functions import CombineDatetime from frappe.tests.utils import FrappeTestCase from frappe.utils import add_days, today from frappe.utils.data import add_to_date @@ -1126,6 +1126,63 @@ class TestStockLedgerEntry(FrappeTestCase): # original amount self.assertEqual(50, _get_stock_credit(final_consumption)) + def test_tie_breaking(self): + frappe.flags.dont_execute_stock_reposts = True + self.addCleanup(frappe.flags.pop, "dont_execute_stock_reposts") + + item = make_item().name + warehouse = "_Test Warehouse - _TC" + + posting_date = "2022-01-01" + posting_time = "00:00:01" + sle = frappe.qb.DocType("Stock Ledger Entry") + + def ordered_qty_after_transaction(): + return ( + frappe.qb.from_(sle) + .select("qty_after_transaction") + .where((sle.item_code == item) & (sle.warehouse == warehouse) & (sle.is_cancelled == 0)) + .orderby(CombineDatetime(sle.posting_date, sle.posting_time)) + .orderby(sle.creation) + ).run(pluck=True) + + first = make_stock_entry( + item_code=item, + to_warehouse=warehouse, + qty=10, + posting_time=posting_time, + posting_date=posting_date, + do_not_submit=True, + ) + second = make_stock_entry( + item_code=item, + to_warehouse=warehouse, + qty=1, + posting_date=posting_date, + posting_time=posting_time, + do_not_submit=True, + ) + + first.submit() + second.submit() + + self.assertEqual([10, 11], ordered_qty_after_transaction()) + + first.cancel() + self.assertEqual([1], ordered_qty_after_transaction()) + + backdated = make_stock_entry( + item_code=item, + to_warehouse=warehouse, + qty=1, + posting_date="2021-01-01", + posting_time=posting_time, + ) + self.assertEqual([1, 2], ordered_qty_after_transaction()) + + backdated.cancel() + self.assertEqual([1], ordered_qty_after_transaction()) + def create_repack_entry(**args): args = frappe._dict(args) From 02aaa6546ce4766aed84908bca79747cd77b0250 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 25 Apr 2022 12:42:06 +0530 Subject: [PATCH 035/106] chore: Remove dead code --- .../doctype/purchase_invoice/test_purchase_invoice.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 42455bf431..30d26acf3a 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -1530,12 +1530,6 @@ class TestPurchaseInvoice(unittest.TestCase): company.save() -def enable_discount_accounting(enable=1): - buying_settings = frappe.get_doc("Buying Settings") - buying_settings.enable_discount_accounting = enable - buying_settings.save() - - def check_gl_entries(doc, voucher_no, expected_gle, posting_date): gl_entries = frappe.db.sql( """select account, debit, credit, posting_date From 8e6c7a6bf7b1b934ae239a77e8767c8d8e9c375b Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Mon, 25 Apr 2022 14:02:46 +0530 Subject: [PATCH 036/106] fix(india): cess value not considered while validating e-invoice totals --- erpnext/regional/india/e_invoice/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py index f317569312..5518e1cb35 100644 --- a/erpnext/regional/india/e_invoice/utils.py +++ b/erpnext/regional/india/e_invoice/utils.py @@ -552,6 +552,7 @@ def validate_totals(einvoice): + flt(value_details["CgstVal"]) + flt(value_details["SgstVal"]) + flt(value_details["IgstVal"]) + + flt(value_details["CesVal"]) + flt(value_details["OthChrg"]) + flt(value_details["RndOffAmt"]) - flt(value_details["Discount"]) From 3fa1c634790095bf7eabc135ed717e124efa4ff0 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 25 Apr 2022 16:29:26 +0530 Subject: [PATCH 037/106] test: Unit test for round off entry dimensions --- .../sales_invoice/test_sales_invoice.py | 23 +++++++++++++++++++ erpnext/accounts/general_ledger.py | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index caa70d00ef..b22ec44f8a 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -1977,6 +1977,13 @@ class TestSalesInvoice(unittest.TestCase): self.assertEqual(expected_values[gle.account][2], gle.credit) def test_rounding_adjustment_3(self): + from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import ( + create_dimension, + disable_dimension, + ) + + create_dimension() + si = create_sales_invoice(do_not_save=True) si.items = [] for d in [(1122, 2), (1122.01, 1), (1122.01, 1)]: @@ -2004,6 +2011,10 @@ class TestSalesInvoice(unittest.TestCase): "included_in_print_rate": 1, }, ) + + si.cost_center = "_Test Cost Center 2 - _TC" + si.location = "Block 1" + si.save() si.submit() self.assertEqual(si.net_total, 4007.16) @@ -2039,6 +2050,18 @@ class TestSalesInvoice(unittest.TestCase): self.assertEqual(debit_credit_diff, 0) + round_off_gle = frappe.db.get_value( + "GL Entry", + {"voucher_type": "Sales Invoice", "voucher_no": si.name, "account": "Round Off - _TC"}, + ["cost_center", "location"], + as_dict=1, + ) + + self.assertEqual(round_off_gle.cost_center, "_Test Cost Center 2 - _TC") + self.assertEqual(round_off_gle.location, "Block 1") + + disable_dimension() + def test_sales_invoice_with_shipping_rule(self): from erpnext.accounts.doctype.shipping_rule.test_shipping_rule import create_shipping_rule diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index 56f84c2392..89034ebb8c 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -409,7 +409,7 @@ def update_accounting_dimensions(round_off_gle): if dimensions and has_all_dimensions: dimension_values = frappe.db.get_value( - round_off_gle["voucher_type"], round_off_gle["voucher_no"], dimensions + round_off_gle["voucher_type"], round_off_gle["voucher_no"], dimensions, as_dict=1 ) for dimension in dimensions: From d3582ea399bb77d21bc1a2e1d902a3b3035628b6 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 25 Apr 2022 18:18:39 +0530 Subject: [PATCH 038/106] fix: Allow multi-currency opening invoices --- .../opening_invoice_creation_tool.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py index 9d4d76b8f6..174b7d7f46 100644 --- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py +++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py @@ -154,6 +154,7 @@ class OpeningInvoiceCreationTool(Document): "income_account" if row.party_type == "Customer" else "expense_account" ) default_uom = frappe.db.get_single_value("Stock Settings", "stock_uom") or _("Nos") + default_currency = frappe.db.get_value(row.party_type, row.party, "default_currency") rate = flt(row.outstanding_amount) / flt(row.qty) item_dict = frappe._dict( @@ -166,6 +167,7 @@ class OpeningInvoiceCreationTool(Document): "description": row.item_name or "Opening Invoice Item", income_expense_account_field: row.temporary_opening_account, "cost_center": cost_center, + "currency": default_currency, } ) From e1c168766198d44dc7e28746bcad9f4c266c3a39 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Thu, 21 Apr 2022 20:01:48 +0530 Subject: [PATCH 039/106] refactor: use db agnostic `CombineDatetime` --- erpnext/stock/stock_ledger.py | 10 ++++------ erpnext/stock/utils.py | 6 +++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index a781479cf6..7e5c231d9c 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -8,9 +8,8 @@ from typing import Optional, Set, Tuple import frappe from frappe import _ from frappe.model.meta import get_field_precision -from frappe.query_builder.functions import Sum +from frappe.query_builder.functions import CombineDatetime, Sum from frappe.utils import cint, cstr, flt, get_link_to_form, getdate, now, nowdate -from pypika import CustomFunction import erpnext from erpnext.stock.doctype.bin.bin import update_qty as update_bin_qty @@ -1158,16 +1157,15 @@ def get_batch_incoming_rate( item_code, warehouse, batch_no, posting_date, posting_time, creation=None ): - Timestamp = CustomFunction("timestamp", ["date", "time"]) - sle = frappe.qb.DocType("Stock Ledger Entry") - timestamp_condition = Timestamp(sle.posting_date, sle.posting_time) < Timestamp( + timestamp_condition = CombineDatetime(sle.posting_date, sle.posting_time) < CombineDatetime( posting_date, posting_time ) if creation: timestamp_condition |= ( - Timestamp(sle.posting_date, sle.posting_time) == Timestamp(posting_date, posting_time) + CombineDatetime(sle.posting_date, sle.posting_time) + == CombineDatetime(posting_date, posting_time) ) & (sle.creation < creation) batch_details = ( diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py index d40218e143..2120304097 100644 --- a/erpnext/stock/utils.py +++ b/erpnext/stock/utils.py @@ -7,6 +7,7 @@ from typing import Dict, Optional import frappe from frappe import _ +from frappe.query_builder.functions import CombineDatetime from frappe.utils import cstr, flt, get_link_to_form, nowdate, nowtime import erpnext @@ -143,12 +144,10 @@ def get_stock_balance( def get_serial_nos_data_after_transactions(args): - from pypika import CustomFunction serial_nos = set() args = frappe._dict(args) sle = frappe.qb.DocType("Stock Ledger Entry") - Timestamp = CustomFunction("timestamp", ["date", "time"]) stock_ledger_entries = ( frappe.qb.from_(sle) @@ -157,7 +156,8 @@ def get_serial_nos_data_after_transactions(args): (sle.item_code == args.item_code) & (sle.warehouse == args.warehouse) & ( - Timestamp(sle.posting_date, sle.posting_time) < Timestamp(args.posting_date, args.posting_time) + CombineDatetime(sle.posting_date, sle.posting_time) + < CombineDatetime(args.posting_date, args.posting_time) ) & (sle.is_cancelled == 0) ) From cdac2b8c63e5856498e5c4cbcc871a1178f7cb80 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Thu, 21 Apr 2022 20:43:07 +0530 Subject: [PATCH 040/106] fix: ignore duplicate fixtures --- erpnext/regional/india/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index 446faaa708..062c2ef5c5 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -1219,7 +1219,7 @@ def make_fixtures(company=None): try: doc = frappe.get_doc(d) doc.flags.ignore_permissions = True - doc.insert() + doc.insert(ignore_if_duplicate=True) except frappe.NameError: frappe.clear_messages() except frappe.DuplicateEntryError: From ce75fe0ec405c68f1c5dd7b4a5d1bbde1af70705 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Fri, 22 Apr 2022 11:44:30 +0530 Subject: [PATCH 041/106] fix: out of range date value --- erpnext/stock/doctype/stock_entry/stock_entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index c4aa8a4711..27a6eaf08b 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -1167,7 +1167,7 @@ class StockEntry(StockController): from `tabItem` i LEFT JOIN `tabItem Default` id ON i.name=id.parent and id.company=%s where i.name=%s and i.disabled=0 - and (i.end_of_life is null or i.end_of_life='0000-00-00' or i.end_of_life > %s)""", + and (i.end_of_life is null or i.end_of_life<'1900-01-01' or i.end_of_life > %s)""", (self.company, args.get("item_code"), nowdate()), as_dict=1, ) From 0fdfc1e76e7aa89268e89a67c968b7acb6d980ec Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Sun, 24 Apr 2022 19:19:22 +0530 Subject: [PATCH 042/106] fix: only query fields that exist --- erpnext/crm/doctype/opportunity/opportunity.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py index 96c730c668..19b4d68e1c 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.py +++ b/erpnext/crm/doctype/opportunity/opportunity.py @@ -54,11 +54,11 @@ class Opportunity(TransactionBase): self.calculate_totals() def map_fields(self): - for field in self.meta.fields: - if not self.get(field.fieldname): + for field in self.meta.get_valid_columns(): + if not self.get(field) and frappe.db.field_exists(self.opportunity_from, field): try: - value = frappe.db.get_value(self.opportunity_from, self.party_name, field.fieldname) - frappe.db.set(self, field.fieldname, value) + value = frappe.db.get_value(self.opportunity_from, self.party_name, field) + frappe.db.set(self, field, value) except Exception: continue From 7d2587c0a9b2ab30ab45bbc9c2af40b1f2ade1fb Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Sun, 24 Apr 2022 19:26:15 +0530 Subject: [PATCH 043/106] fix: nullish check and table name --- erpnext/manufacturing/doctype/bom/bom.py | 2 +- erpnext/stock/doctype/item_price/item_price.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index fefb2e59f0..220ce1dbd8 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -753,7 +753,7 @@ class BOM(WebsiteGenerator): bom_item.include_item_in_manufacturing, bom_item.sourced_by_supplier, bom_item.stock_qty / ifnull(bom.quantity, 1) AS qty_consumed_per_unit - FROM `tabBOM Explosion Item` bom_item, tabBOM bom + FROM `tabBOM Explosion Item` bom_item, `tabBOM` bom WHERE bom_item.parent = bom.name AND bom.name = %s diff --git a/erpnext/stock/doctype/item_price/item_price.py b/erpnext/stock/doctype/item_price/item_price.py index 562f7b9e12..ab797cd039 100644 --- a/erpnext/stock/doctype/item_price/item_price.py +++ b/erpnext/stock/doctype/item_price/item_price.py @@ -64,7 +64,7 @@ class ItemPrice(Document): if self.get(field): conditions += " and {0} = %({0})s ".format(field) else: - conditions += "and (isnull({0}) or {0} = '')".format(field) + conditions += "and ({0} is null or {0} = '')".format(field) price_list_rate = frappe.db.sql( """ From 7e555d3d8c47bc7f304905a3d52b02e9da6b0283 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Sun, 24 Apr 2022 19:47:07 +0530 Subject: [PATCH 044/106] fix: item price query for postgres postgres doesn't like bad type comparisons and doesn't have `isnull` funciton --- .../stock/doctype/item_price/item_price.py | 64 +++++++++++++------ 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/erpnext/stock/doctype/item_price/item_price.py b/erpnext/stock/doctype/item_price/item_price.py index ab797cd039..bcd31ada83 100644 --- a/erpnext/stock/doctype/item_price/item_price.py +++ b/erpnext/stock/doctype/item_price/item_price.py @@ -5,6 +5,8 @@ import frappe from frappe import _ from frappe.model.document import Document +from frappe.query_builder import Criterion +from frappe.query_builder.functions import Cast_ from frappe.utils import getdate @@ -48,35 +50,57 @@ class ItemPrice(Document): ) def check_duplicates(self): - conditions = ( - """where item_code = %(item_code)s and price_list = %(price_list)s and name != %(name)s""" - ) - for field in [ + item_price = frappe.qb.DocType("Item Price") + + query = ( + frappe.qb.from_(item_price) + .select(item_price.price_list_rate) + .where( + (item_price.item_code == self.item_code) + & (item_price.price_list == self.price_list) + & (item_price.name != self.name) + ) + ) + data_fields = ( "uom", "valid_from", "valid_upto", - "packing_unit", "customer", "supplier", "batch_no", - ]: - if self.get(field): - conditions += " and {0} = %({0})s ".format(field) - else: - conditions += "and ({0} is null or {0} = '')".format(field) - - price_list_rate = frappe.db.sql( - """ - select price_list_rate - from `tabItem Price` - {conditions} - """.format( - conditions=conditions - ), - self.as_dict(), ) + number_fields = ["packing_unit"] + + for field in data_fields: + if self.get(field): + query = query.where(item_price[field] == self.get(field)) + else: + query = query.where( + Criterion.any( + [ + item_price[field].isnull(), + Cast_(item_price[field], "varchar") == "", + ] + ) + ) + + for field in number_fields: + if self.get(field): + query = query.where(item_price[field] == self.get(field)) + else: + query = query.where( + Criterion.any( + [ + item_price[field].isnull(), + item_price[field] == 0, + ] + ) + ) + + price_list_rate = query.run(as_dict=True) + if price_list_rate: frappe.throw( _( From a90e7e32a42362f5a03ad1467c7a1e5757fe95fe Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Sun, 24 Apr 2022 20:05:36 +0530 Subject: [PATCH 045/106] fix: proper quoting in sql queries --- erpnext/accounts/party.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index b0b3049d48..ac1dfec7a5 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -881,11 +881,11 @@ def get_default_contact(doctype, name): """ SELECT dl.parent, c.is_primary_contact, c.is_billing_contact FROM `tabDynamic Link` dl - INNER JOIN tabContact c ON c.name = dl.parent + INNER JOIN `tabContact` c ON c.name = dl.parent WHERE dl.link_doctype=%s AND dl.link_name=%s AND - dl.parenttype = "Contact" + dl.parenttype = 'Contact' ORDER BY is_primary_contact DESC, is_billing_contact DESC """, (doctype, name), From 052171f51c17c77459c05423a87ca935dd0ab555 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Sun, 24 Apr 2022 20:14:01 +0530 Subject: [PATCH 046/106] fix: date condition in tax rule --- erpnext/accounts/doctype/tax_rule/tax_rule.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/tax_rule/tax_rule.py b/erpnext/accounts/doctype/tax_rule/tax_rule.py index 27b78e9fab..5bfca96bb1 100644 --- a/erpnext/accounts/doctype/tax_rule/tax_rule.py +++ b/erpnext/accounts/doctype/tax_rule/tax_rule.py @@ -163,10 +163,15 @@ def get_party_details(party, party_type, args=None): def get_tax_template(posting_date, args): """Get matching tax rule""" args = frappe._dict(args) + from_date = to_date = posting_date + if not posting_date: + from_date = "1900-01-01" + to_date = "4000-01-01" + conditions = [ """(from_date is null or from_date <= '{0}') - and (to_date is null or to_date >= '{0}')""".format( - posting_date + and (to_date is null or to_date >= '{1}')""".format( + from_date, to_date ) ] From 88e257ff6d89ba03e3b273be33fec62714751b69 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Sun, 24 Apr 2022 20:17:17 +0530 Subject: [PATCH 047/106] fix: column name in party query --- erpnext/accounts/party.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index ac1dfec7a5..db741d97e1 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -831,9 +831,9 @@ def get_party_shipping_address(doctype, name): "where " "dl.link_doctype=%s " "and dl.link_name=%s " - 'and dl.parenttype="Address" ' + "and dl.parenttype='Address' " "and ifnull(ta.disabled, 0) = 0 and" - '(ta.address_type="Shipping" or ta.is_shipping_address=1) ' + "(ta.address_type='Shipping' or ta.is_shipping_address=1) " "order by ta.is_shipping_address desc, ta.address_type desc limit 1", (doctype, name), ) From b0ead459a01e281ff0ddb5cbe5ff22a5628a95a2 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 26 Apr 2022 13:30:13 +0530 Subject: [PATCH 048/106] feat: add payment terms status rpr to Selling homepage --- .../selling/workspace/selling/selling.json | 362 ++++++++++++------ 1 file changed, 252 insertions(+), 110 deletions(-) diff --git a/erpnext/selling/workspace/selling/selling.json b/erpnext/selling/workspace/selling/selling.json index a700ad89a3..45e160d143 100644 --- a/erpnext/selling/workspace/selling/selling.json +++ b/erpnext/selling/workspace/selling/selling.json @@ -5,7 +5,7 @@ "label": "Sales Order Trends" } ], - "content": "[{\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Selling\",\"col\":12}},{\"type\":\"chart\",\"data\":{\"chart_name\":\"Sales Order Trends\",\"col\":12}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"Quick Access\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Item\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Order\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Analytics\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Order Analysis\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"Reports & Masters\",\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Selling\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Items and Pricing\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Key Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Other Reports\",\"col\":4}}]", + "content": "[{\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Selling\",\"col\":12}},{\"type\":\"chart\",\"data\":{\"chart_name\":\"Sales Order Trends\",\"col\":12}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"Quick Access\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Item\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Order\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Analytics\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Order Analysis\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"Reports & Masters\",\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Selling\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Items and Pricing\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Key Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Other Reports\",\"col\":4}}]", "creation": "2020-01-28 11:49:12.092882", "docstatus": 0, "doctype": "Workspace", @@ -314,118 +314,11 @@ "onboard": 0, "type": "Link" }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Key Reports", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 1, - "label": "Sales Analytics", - "link_count": 0, - "link_to": "Sales Analytics", - "link_type": "Report", - "onboard": 1, - "type": "Link" - }, - { - "dependencies": "Sales Order", - "hidden": 0, - "is_query_report": 1, - "label": "Sales Order Analysis", - "link_count": 0, - "link_to": "Sales Order Analysis", - "link_type": "Report", - "onboard": 1, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Sales Funnel", - "link_count": 0, - "link_to": "sales-funnel", - "link_type": "Page", - "onboard": 1, - "type": "Link" - }, - { - "dependencies": "Sales Order", - "hidden": 0, - "is_query_report": 1, - "label": "Sales Order Trends", - "link_count": 0, - "link_to": "Sales Order Trends", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Quotation", - "hidden": 0, - "is_query_report": 1, - "label": "Quotation Trends", - "link_count": 0, - "link_to": "Quotation Trends", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Customer", - "hidden": 0, - "is_query_report": 1, - "label": "Customer Acquisition and Loyalty", - "link_count": 0, - "link_to": "Customer Acquisition and Loyalty", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Sales Order", - "hidden": 0, - "is_query_report": 1, - "label": "Inactive Customers", - "link_count": 0, - "link_to": "Inactive Customers", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Sales Order", - "hidden": 0, - "is_query_report": 1, - "label": "Sales Person-wise Transaction Summary", - "link_count": 0, - "link_to": "Sales Person-wise Transaction Summary", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Item", - "hidden": 0, - "is_query_report": 1, - "label": "Item-wise Sales History", - "link_count": 0, - "link_to": "Item-wise Sales History", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, { "hidden": 0, "is_query_report": 0, "label": "Other Reports", - "link_count": 0, + "link_count": 12, "onboard": 0, "type": "Card Break" }, @@ -560,9 +453,258 @@ "link_type": "Report", "onboard": 0, "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Key Reports", + "link_count": 22, + "onboard": 0, + "type": "Card Break" + }, + { + "dependencies": "", + "hidden": 0, + "is_query_report": 1, + "label": "Sales Analytics", + "link_count": 0, + "link_to": "Sales Analytics", + "link_type": "Report", + "onboard": 1, + "type": "Link" + }, + { + "dependencies": "Sales Order", + "hidden": 0, + "is_query_report": 1, + "label": "Sales Order Analysis", + "link_count": 0, + "link_to": "Sales Order Analysis", + "link_type": "Report", + "onboard": 1, + "type": "Link" + }, + { + "dependencies": "", + "hidden": 0, + "is_query_report": 0, + "label": "Sales Funnel", + "link_count": 0, + "link_to": "sales-funnel", + "link_type": "Page", + "onboard": 1, + "type": "Link" + }, + { + "dependencies": "Sales Order", + "hidden": 0, + "is_query_report": 1, + "label": "Sales Order Trends", + "link_count": 0, + "link_to": "Sales Order Trends", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Quotation", + "hidden": 0, + "is_query_report": 1, + "label": "Quotation Trends", + "link_count": 0, + "link_to": "Quotation Trends", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Customer", + "hidden": 0, + "is_query_report": 1, + "label": "Customer Acquisition and Loyalty", + "link_count": 0, + "link_to": "Customer Acquisition and Loyalty", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Sales Order", + "hidden": 0, + "is_query_report": 1, + "label": "Inactive Customers", + "link_count": 0, + "link_to": "Inactive Customers", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Sales Order", + "hidden": 0, + "is_query_report": 1, + "label": "Sales Person-wise Transaction Summary", + "link_count": 0, + "link_to": "Sales Person-wise Transaction Summary", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Item", + "hidden": 0, + "is_query_report": 1, + "label": "Item-wise Sales History", + "link_count": 0, + "link_to": "Item-wise Sales History", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Lead", + "hidden": 0, + "is_query_report": 1, + "label": "Lead Details", + "link_count": 0, + "link_to": "Lead Details", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Address", + "hidden": 0, + "is_query_report": 1, + "label": "Customer Addresses And Contacts", + "link_count": 0, + "link_to": "Address And Contacts", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Item", + "hidden": 0, + "is_query_report": 1, + "label": "Available Stock for Packing Items", + "link_count": 0, + "link_to": "Available Stock for Packing Items", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Sales Order", + "hidden": 0, + "is_query_report": 1, + "label": "Pending SO Items For Purchase Request", + "link_count": 0, + "link_to": "Pending SO Items For Purchase Request", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Delivery Note", + "hidden": 0, + "is_query_report": 1, + "label": "Delivery Note Trends", + "link_count": 0, + "link_to": "Delivery Note Trends", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Sales Invoice", + "hidden": 0, + "is_query_report": 1, + "label": "Sales Invoice Trends", + "link_count": 0, + "link_to": "Sales Invoice Trends", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Customer", + "hidden": 0, + "is_query_report": 1, + "label": "Customer Credit Balance", + "link_count": 0, + "link_to": "Customer Credit Balance", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Customer", + "hidden": 0, + "is_query_report": 1, + "label": "Customers Without Any Sales Transactions", + "link_count": 0, + "link_to": "Customers Without Any Sales Transactions", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Customer", + "hidden": 0, + "is_query_report": 1, + "label": "Sales Partners Commission", + "link_count": 0, + "link_to": "Sales Partners Commission", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Sales Order", + "hidden": 0, + "is_query_report": 1, + "label": "Territory Target Variance Based On Item Group", + "link_count": 0, + "link_to": "Territory Target Variance Based On Item Group", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Sales Order", + "hidden": 0, + "is_query_report": 1, + "label": "Sales Person Target Variance Based On Item Group", + "link_count": 0, + "link_to": "Sales Person Target Variance Based On Item Group", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Sales Order", + "hidden": 0, + "is_query_report": 1, + "label": "Sales Partner Target Variance Based On Item Group", + "link_count": 0, + "link_to": "Sales Partner Target Variance based on Item Group", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Payment Terms Status for Sales Order", + "link_count": 0, + "link_to": "Payment Terms Status for Sales Order", + "link_type": "Report", + "onboard": 0, + "type": "Link" } ], - "modified": "2022-01-13 17:43:02.778627", + "modified": "2022-04-26 13:29:55.087240", "modified_by": "Administrator", "module": "Selling", "name": "Selling", From 82a0635c6620837c1871ce6f6597ac35dd45c5c3 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 26 Apr 2022 14:01:13 +0530 Subject: [PATCH 049/106] fix: Consistent accounting dimensions across Sales and Purchase docs --- .../purchase_order/purchase_order.json | 30 +++++++++++++- erpnext/hooks.py | 3 ++ erpnext/patches.txt | 1 + .../create_accounting_dimensions_in_orders.py | 39 +++++++++++++++++++ .../doctype/sales_order/sales_order.json | 23 ++++++++++- .../doctype/delivery_note/delivery_note.json | 24 +++++++++++- .../purchase_receipt/purchase_receipt.json | 23 ++++++++++- 7 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 erpnext/patches/v13_0/create_accounting_dimensions_in_orders.py diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index 9a1f9d1995..b365a836cd 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -23,6 +23,10 @@ "order_confirmation_no", "order_confirmation_date", "amended_from", + "accounting_dimensions_section", + "cost_center", + "dimension_col_break", + "project", "drop_ship", "customer", "customer_name", @@ -1137,16 +1141,39 @@ "fieldtype": "Link", "label": "Tax Withholding Category", "options": "Tax Withholding Category" + }, + { + "collapsible": 1, + "fieldname": "accounting_dimensions_section", + "fieldtype": "Section Break", + "label": "Accounting Dimensions " + }, + { + "fieldname": "cost_center", + "fieldtype": "Link", + "label": "Cost Center", + "options": "Cost Center" + }, + { + "fieldname": "dimension_col_break", + "fieldtype": "Column Break" + }, + { + "fieldname": "project", + "fieldtype": "Link", + "label": "Project", + "options": "Project" } ], "icon": "fa fa-file-text", "idx": 105, "is_submittable": 1, "links": [], - "modified": "2021-09-28 13:10:47.955401", + "modified": "2022-04-26 12:16:38.694276", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", + "naming_rule": "By \"Naming Series\" field", "owner": "Administrator", "permissions": [ { @@ -1193,6 +1220,7 @@ "show_name_in_global_search": 1, "sort_field": "modified", "sort_order": "DESC", + "states": [], "timeline_field": "supplier", "title_field": "supplier_name", "track_changes": 1 diff --git a/erpnext/hooks.py b/erpnext/hooks.py index fe0a89a276..d8b5380c0f 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -551,6 +551,9 @@ accounting_dimension_doctypes = [ "Subscription Plan", "POS Invoice", "POS Invoice Item", + "Purchase Order", + "Purchase Receipt", + "Sales Order", ] regional_overrides = { diff --git a/erpnext/patches.txt b/erpnext/patches.txt index d163ca52f5..474383dd52 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -366,3 +366,4 @@ erpnext.patches.v13_0.update_expense_claim_status_for_paid_advances erpnext.patches.v13_0.create_gst_custom_fields_in_quotation erpnext.patches.v13_0.copy_custom_field_filters_to_website_item erpnext.patches.v14_0.delete_employee_transfer_property_doctype +erpnext.patches.v13_0.create_accounting_dimensions_in_orders \ No newline at end of file diff --git a/erpnext/patches/v13_0/create_accounting_dimensions_in_orders.py b/erpnext/patches/v13_0/create_accounting_dimensions_in_orders.py new file mode 100644 index 0000000000..8a3f1d0a58 --- /dev/null +++ b/erpnext/patches/v13_0/create_accounting_dimensions_in_orders.py @@ -0,0 +1,39 @@ +import frappe +from frappe.custom.doctype.custom_field.custom_field import create_custom_field + + +def execute(): + accounting_dimensions = frappe.db.get_all( + "Accounting Dimension", fields=["fieldname", "label", "document_type", "disabled"] + ) + + if not accounting_dimensions: + return + + count = 1 + for d in accounting_dimensions: + + if count % 2 == 0: + insert_after_field = "dimension_col_break" + else: + insert_after_field = "accounting_dimensions_section" + + for doctype in ["Purchase Order", "Purchase Receipt", "Sales Order"]: + + field = frappe.db.get_value("Custom Field", {"dt": doctype, "fieldname": d.fieldname}) + + if field: + continue + + df = { + "fieldname": d.fieldname, + "label": d.label, + "fieldtype": "Link", + "options": d.document_type, + "insert_after": insert_after_field, + } + + create_custom_field(doctype, df, ignore_validate=False) + frappe.clear_cache(doctype=doctype) + + count += 1 diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index fe2f14e19a..149ad89376 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -25,6 +25,10 @@ "po_no", "po_date", "tax_id", + "accounting_dimensions_section", + "cost_center", + "dimension_col_break", + "project", "contact_info", "customer_address", "address_display", @@ -113,7 +117,6 @@ "is_internal_customer", "represents_company", "inter_company_order_reference", - "project", "party_account_currency", "column_break_77", "source", @@ -1521,13 +1524,29 @@ "fieldtype": "Percent", "label": "% Picked", "read_only": 1 + }, + { + "collapsible": 1, + "fieldname": "accounting_dimensions_section", + "fieldtype": "Section Break", + "label": "Accounting Dimensions" + }, + { + "fieldname": "cost_center", + "fieldtype": "Link", + "label": "Cost Center", + "options": "Cost Center" + }, + { + "fieldname": "dimension_col_break", + "fieldtype": "Column Break" } ], "icon": "fa fa-file-text", "idx": 105, "is_submittable": 1, "links": [], - "modified": "2022-03-15 21:38:31.437586", + "modified": "2022-04-26 14:38:18.350207", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order", diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json index 7ebc4eed75..e3222bc885 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.json +++ b/erpnext/stock/doctype/delivery_note/delivery_note.json @@ -23,6 +23,10 @@ "is_return", "issue_credit_note", "return_against", + "accounting_dimensions_section", + "cost_center", + "dimension_col_break", + "project", "customer_po_details", "po_no", "column_break_17", @@ -115,7 +119,6 @@ "driver_name", "lr_date", "more_info", - "project", "campaign", "source", "column_break5", @@ -1309,13 +1312,29 @@ "fieldtype": "Currency", "label": "Amount Eligible for Commission", "read_only": 1 + }, + { + "collapsible": 1, + "fieldname": "accounting_dimensions_section", + "fieldtype": "Section Break", + "label": "Accounting Dimensions" + }, + { + "fieldname": "cost_center", + "fieldtype": "Link", + "label": "Cost Center", + "options": "Cost Center" + }, + { + "fieldname": "dimension_col_break", + "fieldtype": "Column Break" } ], "icon": "fa fa-truck", "idx": 146, "is_submittable": 1, "links": [], - "modified": "2022-03-10 14:29:13.428984", + "modified": "2022-04-26 14:48:08.781837", "modified_by": "Administrator", "module": "Stock", "name": "Delivery Note", @@ -1380,6 +1399,7 @@ "show_name_in_global_search": 1, "sort_field": "modified", "sort_order": "DESC", + "states": [], "timeline_field": "customer", "title_field": "title", "track_changes": 1, diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json index 19c490d37f..983b62a09a 100755 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json @@ -24,6 +24,10 @@ "apply_putaway_rule", "is_return", "return_against", + "accounting_dimensions_section", + "cost_center", + "dimension_col_break", + "project", "section_addresses", "supplier_address", "contact_person", @@ -107,7 +111,6 @@ "bill_no", "bill_date", "more_info", - "project", "status", "amended_from", "range", @@ -1143,13 +1146,29 @@ "label": "Represents Company", "options": "Company", "read_only": 1 + }, + { + "collapsible": 1, + "fieldname": "accounting_dimensions_section", + "fieldtype": "Section Break", + "label": "Accounting Dimensions" + }, + { + "fieldname": "cost_center", + "fieldtype": "Link", + "label": "Cost Center", + "options": "Cost Center" + }, + { + "fieldname": "dimension_col_break", + "fieldtype": "Column Break" } ], "icon": "fa fa-truck", "idx": 261, "is_submittable": 1, "links": [], - "modified": "2022-04-10 22:50:37.761362", + "modified": "2022-04-26 13:41:32.625197", "modified_by": "Administrator", "module": "Stock", "name": "Purchase Receipt", From 03a6103fe58b35ab18ea669d6cc4e82ff1534200 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 26 Apr 2022 14:28:33 +0530 Subject: [PATCH 050/106] fix(pos): search field doesn't reset on checkout --- .../page/point_of_sale/pos_controller.js | 4 +-- .../page/point_of_sale/pos_item_selector.js | 36 +++++++++++++++++-- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js index 65e0cbb7a5..7a6838680f 100644 --- a/erpnext/selling/page/point_of_sale/pos_controller.js +++ b/erpnext/selling/page/point_of_sale/pos_controller.js @@ -343,9 +343,9 @@ erpnext.PointOfSale.Controller = class { toggle_other_sections: (show) => { if (show) { this.item_details.$component.is(':visible') ? this.item_details.$component.css('display', 'none') : ''; - this.item_selector.$component.css('display', 'none'); + this.item_selector.toggle_component(false); } else { - this.item_selector.$component.css('display', 'flex'); + this.item_selector.toggle_component(true); } }, diff --git a/erpnext/selling/page/point_of_sale/pos_item_selector.js b/erpnext/selling/page/point_of_sale/pos_item_selector.js index b62b27bc4b..7a90fb044f 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_selector.js +++ b/erpnext/selling/page/point_of_sale/pos_item_selector.js @@ -179,6 +179,25 @@ erpnext.PointOfSale.ItemSelector = class { }); this.search_field.toggle_label(false); this.item_group_field.toggle_label(false); + + this.attach_clear_btn(); + } + + attach_clear_btn() { + this.search_field.$wrapper.find('.control-input').append( + ` + + ${frappe.utils.icon('close', 'sm')} + + ` + ); + + this.$clear_search_btn = this.search_field.$wrapper.find('.link-btn'); + + this.$clear_search_btn.on('click', 'a', () => { + this.set_search_value(''); + this.search_field.set_focus(); + }); } set_search_value(value) { @@ -252,6 +271,16 @@ erpnext.PointOfSale.ItemSelector = class { const search_term = e.target.value; this.filter_items({ search_term }); }, 300); + + this.$clear_search_btn.toggle( + Boolean(this.search_field.$input.val()) + ); + }); + + this.search_field.$input.on('focus', () => { + this.$clear_search_btn.toggle( + Boolean(this.search_field.$input.val()) + ); }); } @@ -284,7 +313,7 @@ erpnext.PointOfSale.ItemSelector = class { if (this.items.length == 1) { this.$items_container.find(".item-wrapper").click(); frappe.utils.play_sound("submit"); - $(this.search_field.$input[0]).val("").trigger("input"); + this.set_search_value(''); } else if (this.items.length == 0 && this.barcode_scanned) { // only show alert of barcode is scanned and enter is pressed frappe.show_alert({ @@ -293,7 +322,7 @@ erpnext.PointOfSale.ItemSelector = class { }); frappe.utils.play_sound("error"); this.barcode_scanned = false; - $(this.search_field.$input[0]).val("").trigger("input"); + this.set_search_value(''); } }); } @@ -350,6 +379,7 @@ erpnext.PointOfSale.ItemSelector = class { } toggle_component(show) { - show ? this.$component.css('display', 'flex') : this.$component.css('display', 'none'); + this.set_search_value(''); + this.$component.css('display', show ? 'flex': 'none'); } }; From b1ac5ff9d27eb54f7c5d1ae2e2ccaaa44bffdcc5 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 26 Apr 2022 14:41:36 +0530 Subject: [PATCH 051/106] fix(pos): number pad translations --- erpnext/selling/page/point_of_sale/pos_item_cart.js | 8 ++++---- erpnext/selling/page/point_of_sale/pos_number_pad.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js index 4a99f068cd..eacf480ef8 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_cart.js +++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js @@ -130,10 +130,10 @@ erpnext.PointOfSale.ItemCart = class { }, cols: 5, keys: [ - [ 1, 2, 3, __('Quantity') ], - [ 4, 5, 6, __('Discount') ], - [ 7, 8, 9, __('Rate') ], - [ '.', 0, __('Delete'), __('Remove') ] + [ 1, 2, 3, 'Quantity' ], + [ 4, 5, 6, 'Discount' ], + [ 7, 8, 9, 'Rate' ], + [ '.', 0, 'Delete', 'Remove' ] ], css_classes: [ [ '', '', '', 'col-span-2' ], diff --git a/erpnext/selling/page/point_of_sale/pos_number_pad.js b/erpnext/selling/page/point_of_sale/pos_number_pad.js index 95293d1dd5..f27b0d55ef 100644 --- a/erpnext/selling/page/point_of_sale/pos_number_pad.js +++ b/erpnext/selling/page/point_of_sale/pos_number_pad.js @@ -25,7 +25,7 @@ erpnext.PointOfSale.NumberPad = class { const fieldname = fieldnames && fieldnames[number] ? fieldnames[number] : typeof number === 'string' ? frappe.scrub(number) : number; - return a2 + `
${number}
`; + return a2 + `
${__(number)}
`; }, ''); }, ''); } From 1cc8c79807ce5f864b0d3af1126272223ac3f5e1 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Tue, 26 Apr 2022 17:43:08 +0530 Subject: [PATCH 052/106] test: fix flaky carry forwarded leave expiry test (#30810) --- erpnext/hr/doctype/leave_allocation/test_leave_allocation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/hr/doctype/leave_allocation/test_leave_allocation.py b/erpnext/hr/doctype/leave_allocation/test_leave_allocation.py index dde52d7ad8..a1d39d4423 100644 --- a/erpnext/hr/doctype/leave_allocation/test_leave_allocation.py +++ b/erpnext/hr/doctype/leave_allocation/test_leave_allocation.py @@ -18,6 +18,7 @@ class TestLeaveAllocation(FrappeTestCase): def setUp(self): frappe.db.delete("Leave Period") frappe.db.delete("Leave Allocation") + frappe.db.delete("Leave Ledger Entry") emp_id = make_employee("test_emp_leave_allocation@salary.com", company="_Test Company") self.employee = frappe.get_doc("Employee", emp_id) From 44331f4f1ffb722f1ca2450156c86e16d127697e Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 26 Apr 2022 17:23:56 +0530 Subject: [PATCH 053/106] chore: Warn users about multiple warehouse accounts - Get distinct accounts that warehouse value has been booked against - If same account as the one being set, ignore - If not same account or multiple accounts: warn user that it makes it harder to track mismatches --- erpnext/stock/doctype/warehouse/warehouse.py | 50 ++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py index 3b18a9ac26..3c2d6b8d4c 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.py +++ b/erpnext/stock/doctype/warehouse/warehouse.py @@ -36,6 +36,9 @@ class Warehouse(NestedSet): self.set_onload("account", account) load_address_and_contact(self) + def validate(self): + self.warn_about_multiple_warehouse_account() + def on_update(self): self.update_nsm_model() @@ -70,6 +73,53 @@ class Warehouse(NestedSet): self.update_nsm_model() self.unlink_from_items() + def warn_about_multiple_warehouse_account(self): + "If Warehouse value is split across multiple accounts, warn." + + def get_accounts_where_value_is_booked(name): + sle = frappe.qb.DocType("Stock Ledger Entry") + gle = frappe.qb.DocType("GL Entry") + ac = frappe.qb.DocType("Account") + + return ( + frappe.qb.from_(sle) + .join(gle) + .on(sle.voucher_no == gle.voucher_no) + .join(ac) + .on(ac.name == gle.account) + .select(gle.account) + .distinct() + .where((sle.warehouse == name) & (ac.root_type == "Asset")) + .orderby(sle.creation) + .run(as_dict=True) + ) + + if self.is_new(): + return + + old_wh_account = frappe.db.get_value("Warehouse", self.name, "account") + + # WH account is being changed or set get all accounts against which wh value is booked + if self.account != old_wh_account: + accounts = get_accounts_where_value_is_booked(self.name) + accounts = [d.account for d in accounts] + + if not accounts or (len(accounts) == 1 and self.account in accounts): + # if same singular account has stock value booked ignore + return + + warning = _("Warehouse's Stock Value has already been booked in the following accounts:") + account_str = "
" + ", ".join(frappe.bold(ac) for ac in accounts) + reason = "

" + _( + "Booking stock value across multiple accounts will make it harder to track stock and account value." + ) + + frappe.msgprint( + warning + account_str + reason, + title=_("Multiple Warehouse Accounts"), + indicator="orange", + ) + def check_if_sle_exists(self): return frappe.db.exists("Stock Ledger Entry", {"warehouse": self.name}) From e2a163d4e9ca0e26c0bef8de83b4265db083518c Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 26 Apr 2022 17:50:51 +0530 Subject: [PATCH 054/106] fix: Use `account_type == 'Stock'` to filter stock accounts --- erpnext/stock/doctype/warehouse/warehouse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py index 3c2d6b8d4c..df16643d46 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.py +++ b/erpnext/stock/doctype/warehouse/warehouse.py @@ -89,7 +89,7 @@ class Warehouse(NestedSet): .on(ac.name == gle.account) .select(gle.account) .distinct() - .where((sle.warehouse == name) & (ac.root_type == "Asset")) + .where((sle.warehouse == name) & (ac.account_type == "Stock")) .orderby(sle.creation) .run(as_dict=True) ) From 24a7acaabc23226031af9e2155c3f56f4b09fa25 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Tue, 26 Apr 2022 19:22:26 +0530 Subject: [PATCH 055/106] chore: incorrect translations --- erpnext/translations/ru.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/translations/ru.csv b/erpnext/translations/ru.csv index 6703da6063..073820e9b9 100644 --- a/erpnext/translations/ru.csv +++ b/erpnext/translations/ru.csv @@ -3034,7 +3034,7 @@ To Date,До, To Date cannot be before From Date,На сегодняшний день не может быть раньше от даты, To Date cannot be less than From Date,"Дата не может быть меньше, чем с даты", To Date must be greater than From Date,"До даты должно быть больше, чем с даты", -To Date should be within the Fiscal Year. Assuming To Date = {0},Дата должна быть в пределах финансового года. Предположим, до даты = {0}, +"To Date should be within the Fiscal Year. Assuming To Date = {0}","Дата должна быть в пределах финансового года. Предположим, до даты = {0}", To Datetime,Для DateTime, To Deliver,Для доставки, To Deliver and Bill,Для доставки и оплаты, @@ -6917,7 +6917,7 @@ Time after the end of shift during which check-out is considered for attendance. Working Hours Threshold for Half Day,Порог рабочего времени на полдня, Working hours below which Half Day is marked. (Zero to disable),"Рабочее время, ниже которого отмечается полдня. (Ноль отключить)", Working Hours Threshold for Absent,Порог рабочего времени для отсутствующих, -Working hours below which Absent is marked. (Zero to disable),Порог рабочего времени, ниже которого устанавливается отметка «Отсутствует». (Ноль для отключения),", +"Working hours below which Absent is marked. (Zero to disable)","Порог рабочего времени, ниже которого устанавливается отметка «Отсутствует». (Ноль для отключения)", Process Attendance After,Посещаемость процесса после, Attendance will be marked automatically only after this date.,Посещаемость будет отмечена автоматически только после этой даты., Last Sync of Checkin,Последняя синхронизация регистрации, From 67bb29026f6a897bfda0dcccb4a0a2c0d3adeb7f Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 26 Apr 2022 20:15:15 +0530 Subject: [PATCH 056/106] fix: Ignore custom field validation while setup --- erpnext/regional/united_arab_emirates/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/regional/united_arab_emirates/setup.py b/erpnext/regional/united_arab_emirates/setup.py index cc647f8519..c77fdcc142 100644 --- a/erpnext/regional/united_arab_emirates/setup.py +++ b/erpnext/regional/united_arab_emirates/setup.py @@ -244,7 +244,7 @@ def make_custom_fields(): "Supplier Quotation Item": invoice_item_fields, } - create_custom_fields(custom_fields) + create_custom_fields(custom_fields, ignore_validate=True) def add_print_formats(): From 5c3f9019cc4dda9e0c58a7bf9a824e64db995a21 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Thu, 21 Apr 2022 17:18:19 +0530 Subject: [PATCH 057/106] refactor: misc pick list refactors - make tracking fields read only and no-copy :facepalm: - collapse print settings section, most users configure it once and forget about it, not need to show this. - call pick list grouping function directly - use get_descendants_of instead of obscure db function --- erpnext/selling/doctype/sales_order/sales_order.json | 3 ++- .../selling/doctype/sales_order_item/sales_order_item.json | 6 ++++-- erpnext/stock/doctype/pick_list/pick_list.json | 4 +++- erpnext/stock/doctype/pick_list/pick_list.py | 6 +++--- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index fe2f14e19a..1d0432bddb 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -1520,6 +1520,7 @@ "fieldname": "per_picked", "fieldtype": "Percent", "label": "% Picked", + "no_copy": 1, "read_only": 1 } ], @@ -1527,7 +1528,7 @@ "idx": 105, "is_submittable": 1, "links": [], - "modified": "2022-03-15 21:38:31.437586", + "modified": "2022-04-21 08:16:48.316074", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order", diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.json b/erpnext/selling/doctype/sales_order_item/sales_order_item.json index 195e96486b..8a6a0bae54 100644 --- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json +++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json @@ -803,13 +803,15 @@ { "fieldname": "picked_qty", "fieldtype": "Float", - "label": "Picked Qty" + "label": "Picked Qty", + "no_copy": 1, + "read_only": 1 } ], "idx": 1, "istable": 1, "links": [], - "modified": "2022-03-15 20:17:33.984799", + "modified": "2022-04-21 08:15:14.010319", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order Item", diff --git a/erpnext/stock/doctype/pick_list/pick_list.json b/erpnext/stock/doctype/pick_list/pick_list.json index c604c711ef..e984c082d4 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.json +++ b/erpnext/stock/doctype/pick_list/pick_list.json @@ -114,6 +114,7 @@ "set_only_once": 1 }, { + "collapsible": 1, "fieldname": "print_settings_section", "fieldtype": "Section Break", "label": "Print Settings" @@ -129,7 +130,7 @@ ], "is_submittable": 1, "links": [], - "modified": "2021-10-05 15:08:40.369957", + "modified": "2022-04-21 07:56:40.646473", "modified_by": "Administrator", "module": "Stock", "name": "Pick List", @@ -199,5 +200,6 @@ ], "sort_field": "modified", "sort_order": "DESC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 33d7745c62..72524f036e 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -11,6 +11,7 @@ from frappe import _ from frappe.model.document import Document from frappe.model.mapper import map_child_doc from frappe.utils import cint, floor, flt, today +from frappe.utils.nestedset import get_descendants_of from erpnext.selling.doctype.sales_order.sales_order import ( make_delivery_note as create_delivery_note_from_sales_order, @@ -109,7 +110,7 @@ class PickList(Document): from_warehouses = None if self.parent_warehouse: - from_warehouses = frappe.db.get_descendants("Warehouse", self.parent_warehouse) + from_warehouses = get_descendants_of("Warehouse", self.parent_warehouse) # Create replica before resetting, to handle empty table on update after submit. locations_replica = self.get("locations") @@ -190,8 +191,7 @@ class PickList(Document): frappe.throw(_("Qty of Finished Goods Item should be greater than 0.")) def before_print(self, settings=None): - if self.get("group_same_items"): - self.group_similar_items() + self.group_similar_items() def group_similar_items(self): group_item_qty = defaultdict(float) From 7d5682020ad59853ebec83431219671a3648d4b9 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Wed, 20 Apr 2022 18:57:33 +0530 Subject: [PATCH 058/106] test: bundles in picklist --- .../stock/doctype/pick_list/test_pick_list.py | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/doctype/pick_list/test_pick_list.py b/erpnext/stock/doctype/pick_list/test_pick_list.py index 27b06d2dd9..1ba46f7414 100644 --- a/erpnext/stock/doctype/pick_list/test_pick_list.py +++ b/erpnext/stock/doctype/pick_list/test_pick_list.py @@ -3,11 +3,10 @@ import frappe from frappe import _dict - -test_dependencies = ["Item", "Sales Invoice", "Stock Entry", "Batch"] - from frappe.tests.utils import FrappeTestCase +from erpnext.selling.doctype.sales_order.sales_order import create_pick_list +from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order from erpnext.stock.doctype.item.test_item import create_item, make_item from erpnext.stock.doctype.pick_list.pick_list import create_delivery_note from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt @@ -15,6 +14,8 @@ from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import ( EmptyStockReconciliationItemsError, ) +test_dependencies = ["Item", "Sales Invoice", "Stock Entry", "Batch"] + class TestPickList(FrappeTestCase): def test_pick_list_picks_warehouse_for_each_item(self): @@ -579,6 +580,19 @@ class TestPickList(FrappeTestCase): if dn_item.item_code == "_Test Item 2": self.assertEqual(dn_item.qty, 2) + def test_picklist_with_bundles(self): + # from test_records.json + bundle = "_Test Product Bundle Item" + bundle_items = {"_Test Item": 5, "_Test Item Home Desktop 100": 2} + + so = make_sales_order(item_code=bundle, qty=1) + + pl = create_pick_list(so.name) + pl.save() + self.assertEqual(len(pl.locations), 2) + for item in pl.locations: + self.assertEqual(item.stock_qty, bundle_items[item.item_code]) + # def test_pick_list_skips_items_in_expired_batch(self): # pass From 36c5e8a14fd9cebac5c5f22cf062ca3a47a416f0 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Thu, 21 Apr 2022 12:33:38 +0530 Subject: [PATCH 059/106] feat: Pick list from SO with Product Bundle --- .../doctype/sales_order/sales_order.py | 31 +++++++++++++++++-- .../doctype/packed_item/packed_item.json | 9 +++++- .../stock/doctype/packed_item/packed_item.py | 6 +++- .../stock/doctype/pick_list/test_pick_list.py | 8 +++-- .../pick_list_item/pick_list_item.json | 13 +++++++- 5 files changed, 59 insertions(+), 8 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index d3b4286be5..1d172ad0bf 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -1232,10 +1232,27 @@ def make_inter_company_purchase_order(source_name, target_doc=None): @frappe.whitelist() def create_pick_list(source_name, target_doc=None): - def update_item_quantity(source, target, source_parent): + from erpnext.stock.doctype.packed_item.packed_item import is_product_bundle + + def update_item_quantity(source, target, source_parent) -> None: target.qty = flt(source.qty) - flt(source.delivered_qty) target.stock_qty = (flt(source.qty) - flt(source.delivered_qty)) * flt(source.conversion_factor) + def update_packed_item_qty(source, target, source_parent) -> None: + qty = flt(source.qty) + for item in source_parent.items: + if source.parent_detail_docname == item.name: + pending_percent = (item.qty - item.delivered_qty) / item.qty + target.qty = target.stock_qty = qty * pending_percent + return + + def should_pick_order_item(item) -> bool: + return ( + abs(item.delivered_qty) < abs(item.qty) + and item.delivered_by_supplier != 1 + and not is_product_bundle(item.item_code) + ) + doc = get_mapped_doc( "Sales Order", source_name, @@ -1245,8 +1262,16 @@ def create_pick_list(source_name, target_doc=None): "doctype": "Pick List Item", "field_map": {"parent": "sales_order", "name": "sales_order_item"}, "postprocess": update_item_quantity, - "condition": lambda doc: abs(doc.delivered_qty) < abs(doc.qty) - and doc.delivered_by_supplier != 1, + "condition": should_pick_order_item, + }, + "Packed Item": { + "doctype": "Pick List Item", + "field_map": { + "parent": "sales_order", + "name": "sales_order_item", + "parent_detail_docname": "product_bundle_item", + }, + "postprocess": update_packed_item_qty, }, }, target_doc, diff --git a/erpnext/stock/doctype/packed_item/packed_item.json b/erpnext/stock/doctype/packed_item/packed_item.json index e94c34d7ad..4e67c84a0b 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.json +++ b/erpnext/stock/doctype/packed_item/packed_item.json @@ -29,6 +29,7 @@ "ordered_qty", "column_break_16", "incoming_rate", + "picked_qty", "page_break", "prevdoc_doctype", "parent_detail_docname" @@ -234,13 +235,19 @@ "label": "Ordered Qty", "no_copy": 1, "read_only": 1 + }, + { + "depends_on": "picked_qty", + "fieldname": "picked_qty", + "fieldtype": "Float", + "label": "Picked Qty" } ], "idx": 1, "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2022-03-10 15:42:00.265915", + "modified": "2022-04-21 08:05:29.785362", "modified_by": "Administrator", "module": "Stock", "name": "Packed Item", diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py index 026dd4e122..4d05d7a345 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.py +++ b/erpnext/stock/doctype/packed_item/packed_item.py @@ -32,7 +32,7 @@ def make_packing_list(doc): reset = reset_packing_list(doc) for item_row in doc.get("items"): - if frappe.db.exists("Product Bundle", {"new_item_code": item_row.item_code}): + if is_product_bundle(item_row.item_code): for bundle_item in get_product_bundle_items(item_row.item_code): pi_row = add_packed_item_row( doc=doc, @@ -54,6 +54,10 @@ def make_packing_list(doc): set_product_bundle_rate_amount(doc, parent_items_price) # set price in bundle item +def is_product_bundle(item_code: str) -> bool: + return bool(frappe.db.exists("Product Bundle", {"new_item_code": item_code})) + + def get_indexed_packed_items_table(doc): """ Create dict from stale packed items table like: diff --git a/erpnext/stock/doctype/pick_list/test_pick_list.py b/erpnext/stock/doctype/pick_list/test_pick_list.py index 1ba46f7414..d1a9472f1f 100644 --- a/erpnext/stock/doctype/pick_list/test_pick_list.py +++ b/erpnext/stock/doctype/pick_list/test_pick_list.py @@ -10,6 +10,7 @@ from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_orde from erpnext.stock.doctype.item.test_item import create_item, make_item from erpnext.stock.doctype.pick_list.pick_list import create_delivery_note from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt +from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import ( EmptyStockReconciliationItemsError, ) @@ -582,16 +583,19 @@ class TestPickList(FrappeTestCase): def test_picklist_with_bundles(self): # from test_records.json + warehouse = "_Test Warehouse - _TC" bundle = "_Test Product Bundle Item" bundle_items = {"_Test Item": 5, "_Test Item Home Desktop 100": 2} + for item in bundle_items: + make_stock_entry(item=item, to_warehouse=warehouse, qty=10, rate=10) - so = make_sales_order(item_code=bundle, qty=1) + so = make_sales_order(item_code=bundle, qty=3) pl = create_pick_list(so.name) pl.save() self.assertEqual(len(pl.locations), 2) for item in pl.locations: - self.assertEqual(item.stock_qty, bundle_items[item.item_code]) + self.assertEqual(item.stock_qty, bundle_items[item.item_code] * 3) # def test_pick_list_skips_items_in_expired_batch(self): # pass diff --git a/erpnext/stock/doctype/pick_list_item/pick_list_item.json b/erpnext/stock/doctype/pick_list_item/pick_list_item.json index 805286ddcc..a96ebfcdee 100644 --- a/erpnext/stock/doctype/pick_list_item/pick_list_item.json +++ b/erpnext/stock/doctype/pick_list_item/pick_list_item.json @@ -27,6 +27,7 @@ "column_break_15", "sales_order", "sales_order_item", + "product_bundle_item", "material_request", "material_request_item" ], @@ -146,6 +147,7 @@ { "fieldname": "sales_order_item", "fieldtype": "Data", + "hidden": 1, "label": "Sales Order Item", "read_only": 1 }, @@ -177,11 +179,19 @@ "fieldtype": "Data", "label": "Item Group", "read_only": 1 + }, + { + "description": "product bundle item row's name in sales order. Also indicates that picked item is to be used for a product bundle", + "fieldname": "product_bundle_item", + "fieldtype": "Data", + "hidden": 1, + "label": "Product Bundle Item", + "read_only": 1 } ], "istable": 1, "links": [], - "modified": "2021-09-28 12:02:16.923056", + "modified": "2022-04-22 05:27:38.497997", "modified_by": "Administrator", "module": "Stock", "name": "Pick List Item", @@ -190,5 +200,6 @@ "quick_entry": 1, "sort_field": "modified", "sort_order": "DESC", + "states": [], "track_changes": 1 } \ No newline at end of file From e64cc66df74dd1015b3b015adfacc4f665806f7c Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Fri, 22 Apr 2022 15:22:36 +0530 Subject: [PATCH 060/106] refactor: sales order status update - rename badly named variables - support updated packed items --- erpnext/stock/doctype/pick_list/pick_list.py | 27 ++++++++++---------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 72524f036e..01448be600 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -46,7 +46,7 @@ class PickList(Document): if item.sales_order_item: # update the picked_qty in SO Item - self.update_so(item.sales_order_item, item.picked_qty, item.item_code) + self.update_sales_order_item(item, item.picked_qty, item.item_code) if not frappe.get_cached_value("Item", item.item_code, "has_serial_no"): continue @@ -70,14 +70,13 @@ class PickList(Document): # update picked_qty in SO Item on cancel of PL for item in self.get("locations"): if item.sales_order_item: - self.update_so(item.sales_order_item, -1 * item.picked_qty, item.item_code) + self.update_sales_order_item(item, -1 * item.picked_qty, item.item_code) + + def update_sales_order_item(self, item, picked_qty, item_code): + item_table = "Sales Order Item" if not item.product_bundle_item else "Packed Item" - def update_so(self, so_item, picked_qty, item_code): - so_doc = frappe.get_doc( - "Sales Order", frappe.db.get_value("Sales Order Item", so_item, "parent") - ) already_picked, actual_qty = frappe.db.get_value( - "Sales Order Item", so_item, ["picked_qty", "qty"] + item_table, item.sales_order_item, ["picked_qty", "qty"] ) if self.docstatus == 1: @@ -87,20 +86,22 @@ class PickList(Document): frappe.throw( _( "You are picking more than required quantity for {}. Check if there is any other pick list created for {}" - ).format(item_code, so_doc.name) + ).format(item_code, item.sales_order) ) - frappe.db.set_value("Sales Order Item", so_item, "picked_qty", already_picked + picked_qty) + frappe.db.set_value(item_table, item.sales_order_item, "picked_qty", already_picked + picked_qty) + # TODO: only do this once after all items + sales_order = frappe.get_doc("Sales Order", item.sales_order) total_picked_qty = 0 total_so_qty = 0 - for item in so_doc.get("items"): - total_picked_qty += flt(item.picked_qty) - total_so_qty += flt(item.stock_qty) + for so_item in sales_order.get("items"): + total_picked_qty += flt(so_item.picked_qty) + total_so_qty += flt(so_item.stock_qty) total_picked_qty = total_picked_qty + picked_qty per_picked = total_picked_qty / total_so_qty * 100 - so_doc.db_set("per_picked", flt(per_picked), update_modified=False) + sales_order.db_set("per_picked", flt(per_picked), update_modified=False) @frappe.whitelist() def set_item_locations(self, save=False): From c3fc0a4f55789ee273c7acbc0fb711def4af3190 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Fri, 22 Apr 2022 15:31:41 +0530 Subject: [PATCH 061/106] perf: single update per Sales Order. For each SO item the sales order picking status was being updated, this isn't required and wasteful. --- .../doctype/sales_order/sales_order.py | 10 +++++++ erpnext/stock/doctype/pick_list/pick_list.py | 29 +++++++++++-------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 1d172ad0bf..a35e16f2c2 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -385,6 +385,16 @@ class SalesOrder(SellingController): if tot_qty != 0: self.db_set("per_delivered", flt(delivered_qty / tot_qty) * 100, update_modified=False) + def update_picking_status(self): + total_picked_qty = 0.0 + total_qty = 0.0 + for so_item in self.items: + total_picked_qty += flt(so_item.picked_qty) + total_qty += flt(so_item.stock_qty) + per_picked = total_picked_qty / total_qty * 100 + + self.db_set("per_picked", flt(per_picked), update_modified=False) + def set_indicator(self): """Set indicator for portal""" if self.per_billed < 100 and self.per_delivered < 100: diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 01448be600..3191f15782 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -5,6 +5,7 @@ import json from collections import OrderedDict, defaultdict from itertools import groupby from operator import itemgetter +from typing import Set import frappe from frappe import _ @@ -39,6 +40,8 @@ class PickList(Document): ) def before_submit(self): + + update_sales_orders = set() for item in self.locations: # if the user has not entered any picked qty, set it to stock_qty, before submit if item.picked_qty == 0: @@ -47,6 +50,7 @@ class PickList(Document): if item.sales_order_item: # update the picked_qty in SO Item self.update_sales_order_item(item, item.picked_qty, item.item_code) + update_sales_orders.add(item.sales_order) if not frappe.get_cached_value("Item", item.item_code, "has_serial_no"): continue @@ -66,11 +70,18 @@ class PickList(Document): title=_("Quantity Mismatch"), ) + self.update_sales_order_picking_status(update_sales_orders) + def before_cancel(self): - # update picked_qty in SO Item on cancel of PL + """Deduct picked qty on cancelling pick list""" + updated_sales_orders = set() + for item in self.get("locations"): if item.sales_order_item: self.update_sales_order_item(item, -1 * item.picked_qty, item.item_code) + updated_sales_orders.add(item.sales_order) + + self.update_sales_order_picking_status(updated_sales_orders) def update_sales_order_item(self, item, picked_qty, item_code): item_table = "Sales Order Item" if not item.product_bundle_item else "Packed Item" @@ -91,17 +102,11 @@ class PickList(Document): frappe.db.set_value(item_table, item.sales_order_item, "picked_qty", already_picked + picked_qty) - # TODO: only do this once after all items - sales_order = frappe.get_doc("Sales Order", item.sales_order) - total_picked_qty = 0 - total_so_qty = 0 - for so_item in sales_order.get("items"): - total_picked_qty += flt(so_item.picked_qty) - total_so_qty += flt(so_item.stock_qty) - total_picked_qty = total_picked_qty + picked_qty - per_picked = total_picked_qty / total_so_qty * 100 - - sales_order.db_set("per_picked", flt(per_picked), update_modified=False) + @staticmethod + def update_sales_order_picking_status(sales_orders: Set[str]) -> None: + for sales_order in sales_orders: + if sales_order: + frappe.get_doc("Sales Order", sales_order).update_picking_status() @frappe.whitelist() def set_item_locations(self, save=False): From 60bc26fdbe9540cbb40a01732d469f3579314be2 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 25 Apr 2022 13:42:42 +0530 Subject: [PATCH 062/106] feat: back-update min picked qty for a bundle --- erpnext/stock/doctype/pick_list/pick_list.py | 55 +++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 3191f15782..7564e8fd15 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -5,7 +5,7 @@ import json from collections import OrderedDict, defaultdict from itertools import groupby from operator import itemgetter -from typing import Set +from typing import Dict, List, Set import frappe from frappe import _ @@ -40,7 +40,6 @@ class PickList(Document): ) def before_submit(self): - update_sales_orders = set() for item in self.locations: # if the user has not entered any picked qty, set it to stock_qty, before submit @@ -70,6 +69,7 @@ class PickList(Document): title=_("Quantity Mismatch"), ) + self.update_bundle_picked_qty() self.update_sales_order_picking_status(update_sales_orders) def before_cancel(self): @@ -81,6 +81,7 @@ class PickList(Document): self.update_sales_order_item(item, -1 * item.picked_qty, item.item_code) updated_sales_orders.add(item.sales_order) + self.update_bundle_picked_qty() self.update_sales_order_picking_status(updated_sales_orders) def update_sales_order_item(self, item, picked_qty, item_code): @@ -223,6 +224,56 @@ class PickList(Document): for idx, item in enumerate(self.locations, start=1): item.idx = idx + def update_bundle_picked_qty(self): + """Ensure that picked quantity is sufficient for fulfilling a whole number of.""" + + product_bundles = self._get_product_bundles() + product_bundle_qty_map = self._get_product_bundle_qty_map(product_bundles.values()) + + for so_row, item_code in product_bundles.items(): + picked_qty = self._compute_picked_qty_for_bundle(so_row, product_bundle_qty_map[item_code]) + item_table = "Sales Order Item" + already_picked = frappe.db.get_value(item_table, so_row, "picked_qty") + frappe.db.set_value( + item_table, + so_row, + "picked_qty", + already_picked + (picked_qty * (1 if self.docstatus == 1 else -1)), + ) + + def _get_product_bundles(self) -> Dict[str, str]: + # Dict[so_item_row: item_code] + product_bundles = {} + for item in self.locations: + if not item.product_bundle_item: + continue + bundle_item_code = frappe.db.get_value( + "Sales Order Item", item.product_bundle_item, "item_code" + ) + product_bundles[item.product_bundle_item] = bundle_item_code + return product_bundles + + def _get_product_bundle_qty_map(self, bundles: List[str]) -> Dict[str, Dict[str, float]]: + # bundle_item_code: Dict[component, qty] + product_bundle_qty_map = {} + for bundle_item_code in bundles: + bundle = frappe.get_last_doc("Product Bundle", {"new_item_code": bundle_item_code}) + product_bundle_qty_map[bundle_item_code] = {item.item_code: item.qty for item in bundle.items} + return product_bundle_qty_map + + def _compute_picked_qty_for_bundle(self, bundle_row, bundle_items) -> float: + """Compute how many full bundles can be created from picked items.""" + possible_bundles = [] + for item in self.locations: + if item.product_bundle_item != bundle_row: + continue + + if qty_in_bundle := bundle_items.get(item.item_code): + possible_bundles.append(item.picked_qty / qty_in_bundle) + else: + possible_bundles.append(0) + return min(possible_bundles) + def validate_item_locations(pick_list): if not pick_list.locations: From 3ddad6891ae6184e7bdcd12abb1cfa3f6993344d Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 25 Apr 2022 14:22:29 +0530 Subject: [PATCH 063/106] refactor: simplify needlessly complicated code --- erpnext/stock/doctype/pick_list/pick_list.py | 56 ++++++++++---------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 7564e8fd15..3703e85502 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -549,21 +549,21 @@ def create_dn_wo_so(pick_list): def create_dn_with_so(sales_dict, pick_list): delivery_note = None + item_table_mapper = { + "doctype": "Delivery Note Item", + "field_map": { + "rate": "rate", + "name": "so_detail", + "parent": "against_sales_order", + }, + "condition": lambda doc: abs(doc.delivered_qty) < abs(doc.qty) + and doc.delivered_by_supplier != 1, + } + for customer in sales_dict: for so in sales_dict[customer]: delivery_note = None delivery_note = create_delivery_note_from_sales_order(so, delivery_note, skip_item_mapping=True) - - item_table_mapper = { - "doctype": "Delivery Note Item", - "field_map": { - "rate": "rate", - "name": "so_detail", - "parent": "against_sales_order", - }, - "condition": lambda doc: abs(doc.delivered_qty) < abs(doc.qty) - and doc.delivered_by_supplier != 1, - } break if delivery_note: # map all items of all sales orders of that customer @@ -577,28 +577,26 @@ def create_dn_with_so(sales_dict, pick_list): def map_pl_locations(pick_list, item_mapper, delivery_note, sales_order=None): for location in pick_list.locations: - if location.sales_order == sales_order: - if location.sales_order_item: - sales_order_item = frappe.get_cached_doc( - "Sales Order Item", {"name": location.sales_order_item} - ) - else: - sales_order_item = None + if location.sales_order != sales_order: + continue - source_doc, table_mapper = ( - [sales_order_item, item_mapper] if sales_order_item else [location, item_mapper] - ) + if location.sales_order_item: + sales_order_item = frappe.get_doc("Sales Order Item", location.sales_order_item) + else: + sales_order_item = None - dn_item = map_child_doc(source_doc, delivery_note, table_mapper) + source_doc = sales_order_item or location - if dn_item: - dn_item.pick_list_item = location.name - dn_item.warehouse = location.warehouse - dn_item.qty = flt(location.picked_qty) / (flt(location.conversion_factor) or 1) - dn_item.batch_no = location.batch_no - dn_item.serial_no = location.serial_no + dn_item = map_child_doc(source_doc, delivery_note, item_mapper) - update_delivery_note_item(source_doc, dn_item, delivery_note) + if dn_item: + dn_item.pick_list_item = location.name + dn_item.warehouse = location.warehouse + dn_item.qty = flt(location.picked_qty) / (flt(location.conversion_factor) or 1) + dn_item.batch_no = location.batch_no + dn_item.serial_no = location.serial_no + + update_delivery_note_item(source_doc, dn_item, delivery_note) set_delivery_note_missing_values(delivery_note) delivery_note.pick_list = pick_list.name From 277b51b40482447639d2c0b9d5440e758ea0b76f Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 25 Apr 2022 15:02:08 +0530 Subject: [PATCH 064/106] refactor: groupby using keys instead of int index --- erpnext/stock/doctype/pick_list/pick_list.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 3703e85502..a94745677f 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -4,7 +4,6 @@ import json from collections import OrderedDict, defaultdict from itertools import groupby -from operator import itemgetter from typing import Dict, List, Set import frappe @@ -507,11 +506,13 @@ def create_delivery_note(source_name, target_doc=None): for location in pick_list.locations: if location.sales_order: sales_orders.append( - [frappe.db.get_value("Sales Order", location.sales_order, "customer"), location.sales_order] + frappe.db.get_value( + "Sales Order", location.sales_order, ["customer", "name as sales_order"], as_dict=True + ) ) - # Group sales orders by customer - for key, keydata in groupby(sales_orders, key=itemgetter(0)): - sales_dict[key] = set([d[1] for d in keydata]) + + for customer, rows in groupby(sales_orders, key=lambda so: so["customer"]): + sales_dict[customer] = {row.sales_order for row in rows} if sales_dict: delivery_note = create_dn_with_so(sales_dict, pick_list) From f574121741800425e9eb8b34a78e26d8ed1d877a Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 25 Apr 2022 15:05:10 +0530 Subject: [PATCH 065/106] refactor: simpler check for non-SO items --- erpnext/stock/doctype/pick_list/pick_list.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index a94745677f..9daf4f11c4 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -517,13 +517,7 @@ def create_delivery_note(source_name, target_doc=None): if sales_dict: delivery_note = create_dn_with_so(sales_dict, pick_list) - is_item_wo_so = 0 - for location in pick_list.locations: - if not location.sales_order: - is_item_wo_so = 1 - break - if is_item_wo_so == 1: - # Create a DN for items without sales orders as well + if not all(item.sales_order for item in pick_list.locations): delivery_note = create_dn_wo_so(pick_list) frappe.msgprint(_("Delivery Note(s) created for the Pick List")) From 23cb0d684d5e10fd12688b55caddc0911ff4e927 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 25 Apr 2022 17:06:26 +0530 Subject: [PATCH 066/106] feat: create DN from pick list with bundle items --- erpnext/stock/doctype/pick_list/pick_list.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 9daf4f11c4..46c858878a 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -572,7 +572,7 @@ def create_dn_with_so(sales_dict, pick_list): def map_pl_locations(pick_list, item_mapper, delivery_note, sales_order=None): for location in pick_list.locations: - if location.sales_order != sales_order: + if location.sales_order != sales_order or location.product_bundle_item: continue if location.sales_order_item: @@ -592,6 +592,8 @@ def map_pl_locations(pick_list, item_mapper, delivery_note, sales_order=None): dn_item.serial_no = location.serial_no update_delivery_note_item(source_doc, dn_item, delivery_note) + + add_product_bundles_to_delivery_note(pick_list, delivery_note, item_mapper) set_delivery_note_missing_values(delivery_note) delivery_note.pick_list = pick_list.name @@ -599,6 +601,22 @@ def map_pl_locations(pick_list, item_mapper, delivery_note, sales_order=None): delivery_note.customer = frappe.get_value("Sales Order", sales_order, "customer") +def add_product_bundles_to_delivery_note( + pick_list: "PickList", delivery_note, item_mapper +) -> None: + product_bundles = pick_list._get_product_bundles() + product_bundle_qty_map = pick_list._get_product_bundle_qty_map(product_bundles.values()) + + for so_row, item_code in product_bundles.items(): + sales_order_item = frappe.get_doc("Sales Order Item", so_row) + dn_bundle_item = map_child_doc(sales_order_item, delivery_note, item_mapper) + # TODO: post process packed items and update stock details + dn_bundle_item.qty = pick_list._compute_picked_qty_for_bundle( + so_row, product_bundle_qty_map[item_code] + ) + update_delivery_note_item(sales_order_item, dn_bundle_item, delivery_note) + + @frappe.whitelist() def create_stock_entry(pick_list): pick_list = frappe.get_doc(json.loads(pick_list)) From 25485edfd966301966a8ccc366da1fa0fd38db1f Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 25 Apr 2022 17:12:37 +0530 Subject: [PATCH 067/106] refactor: remove unnecssary vars also remove misleading docstring --- erpnext/stock/doctype/pick_list/pick_list.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 46c858878a..60f5e34efb 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -224,8 +224,6 @@ class PickList(Document): item.idx = idx def update_bundle_picked_qty(self): - """Ensure that picked quantity is sufficient for fulfilling a whole number of.""" - product_bundles = self._get_product_bundles() product_bundle_qty_map = self._get_product_bundle_qty_map(product_bundles.values()) @@ -246,10 +244,11 @@ class PickList(Document): for item in self.locations: if not item.product_bundle_item: continue - bundle_item_code = frappe.db.get_value( - "Sales Order Item", item.product_bundle_item, "item_code" + product_bundles[item.product_bundle_item] = frappe.db.get_value( + "Sales Order Item", + item.product_bundle_item, + "item_code", ) - product_bundles[item.product_bundle_item] = bundle_item_code return product_bundles def _get_product_bundle_qty_map(self, bundles: List[str]) -> Dict[str, Dict[str, float]]: From 41aa4b352407190c4f2ed6bc223cb4510555206c Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 25 Apr 2022 17:16:44 +0530 Subject: [PATCH 068/106] fix: round off bundle qty This is to accomodate bundles that might allow floating point qty. --- erpnext/stock/doctype/pick_list/pick_list.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 60f5e34efb..aa015755fe 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -261,6 +261,8 @@ class PickList(Document): def _compute_picked_qty_for_bundle(self, bundle_row, bundle_items) -> float: """Compute how many full bundles can be created from picked items.""" + precision = frappe.get_precision("Stock Ledger Entry", "qty_after_transaction") + possible_bundles = [] for item in self.locations: if item.product_bundle_item != bundle_row: @@ -270,7 +272,7 @@ class PickList(Document): possible_bundles.append(item.picked_qty / qty_in_bundle) else: possible_bundles.append(0) - return min(possible_bundles) + return flt(min(possible_bundles), precision or 6) def validate_item_locations(pick_list): From 1ac275ce61d0e113aac43a8b5ad81ba7c53b8f65 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 25 Apr 2022 17:32:48 +0530 Subject: [PATCH 069/106] feat: transfer picklist stock info to packing list --- erpnext/stock/doctype/pick_list/pick_list.py | 34 +++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index aa015755fe..94e9e53423 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -565,7 +565,10 @@ def create_dn_with_so(sales_dict, pick_list): # map all items of all sales orders of that customer for so in sales_dict[customer]: map_pl_locations(pick_list, item_table_mapper, delivery_note, so) - delivery_note.insert(ignore_mandatory=True) + delivery_note.flags.ignore_mandatory = True + delivery_note.insert() + update_packed_item_details(pick_list, delivery_note) + delivery_note.save() return delivery_note @@ -605,6 +608,10 @@ def map_pl_locations(pick_list, item_mapper, delivery_note, sales_order=None): def add_product_bundles_to_delivery_note( pick_list: "PickList", delivery_note, item_mapper ) -> None: + """Add product bundles found in pick list to delivery note. + + When mapping pick list items, the bundle item itself isn't part of the + locations. Dynamically fetch and add parent bundle item into DN.""" product_bundles = pick_list._get_product_bundles() product_bundle_qty_map = pick_list._get_product_bundle_qty_map(product_bundles.values()) @@ -618,6 +625,31 @@ def add_product_bundles_to_delivery_note( update_delivery_note_item(sales_order_item, dn_bundle_item, delivery_note) +def update_packed_item_details(pick_list: "PickList", delivery_note) -> None: + """Update stock details on packed items table of delivery note.""" + + def _find_so_row(packed_item): + for item in delivery_note.items: + if packed_item.parent_detail_docname == item.name: + return item.so_detail + + def _find_pick_list_location(bundle_row, packed_item): + if not bundle_row: + return + for loc in pick_list.locations: + if loc.product_bundle_item == bundle_row and loc.item_code == packed_item.item_code: + return loc + + for packed_item in delivery_note.packed_items: + so_row = _find_so_row(packed_item) + location = _find_pick_list_location(so_row, packed_item) + if not location: + continue + packed_item.warehouse = location.warehouse + packed_item.batch_no = location.batch_no + packed_item.serial_no = location.serial_no + + @frappe.whitelist() def create_stock_entry(pick_list): pick_list = frappe.get_doc(json.loads(pick_list)) From ee54ece8fd7dd70d154e3483d372f43681fbc514 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 25 Apr 2022 19:24:33 +0530 Subject: [PATCH 070/106] test: product bundle fixture --- .../doctype/packed_item/test_packed_item.py | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/erpnext/stock/doctype/packed_item/test_packed_item.py b/erpnext/stock/doctype/packed_item/test_packed_item.py index fe1b0d9f79..c928b57d58 100644 --- a/erpnext/stock/doctype/packed_item/test_packed_item.py +++ b/erpnext/stock/doctype/packed_item/test_packed_item.py @@ -1,10 +1,12 @@ # Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors # License: GNU General Public License v3. See license.txt +from typing import List, Optional, Tuple + +import frappe from frappe.tests.utils import FrappeTestCase, change_settings from frappe.utils import add_to_date, nowdate -from erpnext.selling.doctype.product_bundle.test_product_bundle import make_product_bundle from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order from erpnext.stock.doctype.item.test_item import make_item @@ -12,6 +14,25 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import get_gl_ from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry +def create_product_bundle(quantities: Optional[List[int]] = None) -> Tuple[str, List[str]]: + """Get a new product_bundle for use in tests""" + if not quantities: + quantities = [2, 2] + + bundle = make_item(properties={"is_stock_item": 0}).name + + bundle_doc = frappe.get_doc({"doctype": "Product Bundle", "new_item_code": bundle}) + + components = [] + for qty in quantities: + compoenent = make_item().name + components.append(compoenent) + bundle_doc.append("items", {"item_code": compoenent, "qty": qty}) + + bundle_doc.insert() + return bundle, components + + class TestPackedItem(FrappeTestCase): "Test impact on Packed Items table in various scenarios." @@ -19,22 +40,11 @@ class TestPackedItem(FrappeTestCase): def setUpClass(cls) -> None: super().setUpClass() cls.warehouse = "_Test Warehouse - _TC" - cls.bundle = "_Test Product Bundle X" - cls.bundle_items = ["_Test Bundle Item 1", "_Test Bundle Item 2"] - cls.bundle2 = "_Test Product Bundle Y" - cls.bundle2_items = ["_Test Bundle Item 3", "_Test Bundle Item 4"] - - make_item(cls.bundle, {"is_stock_item": 0}) - make_item(cls.bundle2, {"is_stock_item": 0}) - for item in cls.bundle_items + cls.bundle2_items: - make_item(item, {"is_stock_item": 1}) - - make_item("_Test Normal Stock Item", {"is_stock_item": 1}) - - make_product_bundle(cls.bundle, cls.bundle_items, qty=2) - make_product_bundle(cls.bundle2, cls.bundle2_items, qty=2) + cls.bundle, cls.bundle_items = create_product_bundle() + cls.bundle2, cls.bundle2_items = create_product_bundle() + cls.normal_item = make_item().name for item in cls.bundle_items + cls.bundle2_items: make_stock_entry(item_code=item, to_warehouse=cls.warehouse, qty=100, rate=100) @@ -58,7 +68,7 @@ class TestPackedItem(FrappeTestCase): self.assertEqual(so.packed_items[1].qty, 4) # change item code to non bundle item - so.items[0].item_code = "_Test Normal Stock Item" + so.items[0].item_code = self.normal_item so.save() self.assertEqual(len(so.packed_items), 0) From 9e60acdf56d15334f55a71c80f3c2e580dc46024 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 25 Apr 2022 19:30:42 +0530 Subject: [PATCH 071/106] test: test bundle - picklist behaviour --- .../doctype/packed_item/test_packed_item.py | 18 ++++-- erpnext/stock/doctype/pick_list/pick_list.py | 1 - .../stock/doctype/pick_list/test_pick_list.py | 61 +++++++++++++++---- 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/erpnext/stock/doctype/packed_item/test_packed_item.py b/erpnext/stock/doctype/packed_item/test_packed_item.py index c928b57d58..ad7fd9a697 100644 --- a/erpnext/stock/doctype/packed_item/test_packed_item.py +++ b/erpnext/stock/doctype/packed_item/test_packed_item.py @@ -14,8 +14,13 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import get_gl_ from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry -def create_product_bundle(quantities: Optional[List[int]] = None) -> Tuple[str, List[str]]: - """Get a new product_bundle for use in tests""" +def create_product_bundle( + quantities: Optional[List[int]] = None, warehouse: Optional[str] = None +) -> Tuple[str, List[str]]: + """Get a new product_bundle for use in tests. + + Create 10x required stock if warehouse is specified. + """ if not quantities: quantities = [2, 2] @@ -28,8 +33,11 @@ def create_product_bundle(quantities: Optional[List[int]] = None) -> Tuple[str, compoenent = make_item().name components.append(compoenent) bundle_doc.append("items", {"item_code": compoenent, "qty": qty}) + if warehouse: + make_stock_entry(item=compoenent, to_warehouse=warehouse, qty=10 * qty, rate=100) bundle_doc.insert() + return bundle, components @@ -41,12 +49,10 @@ class TestPackedItem(FrappeTestCase): super().setUpClass() cls.warehouse = "_Test Warehouse - _TC" - cls.bundle, cls.bundle_items = create_product_bundle() - cls.bundle2, cls.bundle2_items = create_product_bundle() + cls.bundle, cls.bundle_items = create_product_bundle(warehouse=cls.warehouse) + cls.bundle2, cls.bundle2_items = create_product_bundle(warehouse=cls.warehouse) cls.normal_item = make_item().name - for item in cls.bundle_items + cls.bundle2_items: - make_stock_entry(item_code=item, to_warehouse=cls.warehouse, qty=100, rate=100) def test_adding_bundle_item(self): "Test impact on packed items if bundle item row is added." diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 94e9e53423..53584f5079 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -618,7 +618,6 @@ def add_product_bundles_to_delivery_note( for so_row, item_code in product_bundles.items(): sales_order_item = frappe.get_doc("Sales Order Item", so_row) dn_bundle_item = map_child_doc(sales_order_item, delivery_note, item_mapper) - # TODO: post process packed items and update stock details dn_bundle_item.qty = pick_list._compute_picked_qty_for_bundle( so_row, product_bundle_qty_map[item_code] ) diff --git a/erpnext/stock/doctype/pick_list/test_pick_list.py b/erpnext/stock/doctype/pick_list/test_pick_list.py index d1a9472f1f..8ce05f15f7 100644 --- a/erpnext/stock/doctype/pick_list/test_pick_list.py +++ b/erpnext/stock/doctype/pick_list/test_pick_list.py @@ -8,6 +8,7 @@ from frappe.tests.utils import FrappeTestCase from erpnext.selling.doctype.sales_order.sales_order import create_pick_list from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order from erpnext.stock.doctype.item.test_item import create_item, make_item +from erpnext.stock.doctype.packed_item.test_packed_item import create_product_bundle from erpnext.stock.doctype.pick_list.pick_list import create_delivery_note from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry @@ -584,12 +585,12 @@ class TestPickList(FrappeTestCase): def test_picklist_with_bundles(self): # from test_records.json warehouse = "_Test Warehouse - _TC" - bundle = "_Test Product Bundle Item" - bundle_items = {"_Test Item": 5, "_Test Item Home Desktop 100": 2} - for item in bundle_items: - make_stock_entry(item=item, to_warehouse=warehouse, qty=10, rate=10) - so = make_sales_order(item_code=bundle, qty=3) + quantities = [5, 2] + bundle, components = create_product_bundle(quantities, warehouse=warehouse) + bundle_items = dict(zip(components, quantities)) + + so = make_sales_order(item_code=bundle, qty=3, rate=42) pl = create_pick_list(so.name) pl.save() @@ -597,14 +598,48 @@ class TestPickList(FrappeTestCase): for item in pl.locations: self.assertEqual(item.stock_qty, bundle_items[item.item_code] * 3) - # def test_pick_list_skips_items_in_expired_batch(self): - # pass + # check picking status on sales order + pl.submit() + so.reload() + self.assertEqual(so.per_picked, 100) - # def test_pick_list_from_sales_order(self): - # pass + # deliver + dn = create_delivery_note(pl.name).submit() + self.assertEqual(dn.items[0].rate, 42) + self.assertEqual(dn.packed_items[0].warehouse, warehouse) + so.reload() + self.assertEqual(so.per_delivered, 100) - # def test_pick_list_from_work_order(self): - # pass + def test_picklist_with_partial_bundles(self): + # from test_records.json + warehouse = "_Test Warehouse - _TC" - # def test_pick_list_from_material_request(self): - # pass + quantities = [5, 2] + bundle, components = create_product_bundle(quantities, warehouse=warehouse) + + so = make_sales_order(item_code=bundle, qty=4, rate=42) + + pl = create_pick_list(so.name) + for loc in pl.locations: + loc.picked_qty = loc.qty / 2 + + pl.save().submit() + so.reload() + self.assertEqual(so.per_picked, 50) + + # deliver half qty + dn = create_delivery_note(pl.name).submit() + self.assertEqual(dn.items[0].rate, 42) + so.reload() + self.assertEqual(so.per_delivered, 50) + + pl = create_pick_list(so.name) + pl.save().submit() + so.reload() + self.assertEqual(so.per_picked, 100) + + # deliver remaining + dn = create_delivery_note(pl.name).submit() + self.assertEqual(dn.items[0].rate, 42) + so.reload() + self.assertEqual(so.per_delivered, 100) From 85e8dd9a4960980e1ce681d942016f68081493e0 Mon Sep 17 00:00:00 2001 From: gavin Date: Wed, 27 Apr 2022 12:41:16 +0530 Subject: [PATCH 072/106] chore: Add "Try on PWD" button (#30817) --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c26660c5a2..e59c744712 100644 --- a/README.md +++ b/README.md @@ -41,12 +41,17 @@ ERPNext is built on the [Frappe Framework](https://github.com/frappe/frappe), a --- -
+ +> Login for the PWD site: (username: Administrator, password: admin) + ### Containerized Installation Use docker to deploy ERPNext in production or for development of [Frappe](https://github.com/frappe/frappe) apps. See https://github.com/frappe/frappe_docker for more details. From 8207697e43a8baa3353c0c984e8e99b14fcb5b55 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Wed, 27 Apr 2022 12:15:26 +0530 Subject: [PATCH 073/106] fix: compare against stock qty while validating Other changes: - only allow whole number of bundles to get picked --- .../sales_order_item/sales_order_item.json | 4 ++-- erpnext/stock/doctype/pick_list/pick_list.py | 9 ++++++--- .../stock/doctype/pick_list/test_pick_list.py | 17 ++++++++++++++++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.json b/erpnext/selling/doctype/sales_order_item/sales_order_item.json index 8a6a0bae54..3797856db2 100644 --- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json +++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json @@ -803,7 +803,7 @@ { "fieldname": "picked_qty", "fieldtype": "Float", - "label": "Picked Qty", + "label": "Picked Qty (in Stock UOM)", "no_copy": 1, "read_only": 1 } @@ -811,7 +811,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2022-04-21 08:15:14.010319", + "modified": "2022-04-27 03:15:34.366563", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order Item", diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 53584f5079..70d2f23070 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -85,9 +85,12 @@ class PickList(Document): def update_sales_order_item(self, item, picked_qty, item_code): item_table = "Sales Order Item" if not item.product_bundle_item else "Packed Item" + stock_qty_field = "stock_qty" if not item.product_bundle_item else "qty" already_picked, actual_qty = frappe.db.get_value( - item_table, item.sales_order_item, ["picked_qty", "qty"] + item_table, + item.sales_order_item, + ["picked_qty", stock_qty_field], ) if self.docstatus == 1: @@ -259,7 +262,7 @@ class PickList(Document): product_bundle_qty_map[bundle_item_code] = {item.item_code: item.qty for item in bundle.items} return product_bundle_qty_map - def _compute_picked_qty_for_bundle(self, bundle_row, bundle_items) -> float: + def _compute_picked_qty_for_bundle(self, bundle_row, bundle_items) -> int: """Compute how many full bundles can be created from picked items.""" precision = frappe.get_precision("Stock Ledger Entry", "qty_after_transaction") @@ -272,7 +275,7 @@ class PickList(Document): possible_bundles.append(item.picked_qty / qty_in_bundle) else: possible_bundles.append(0) - return flt(min(possible_bundles), precision or 6) + return int(flt(min(possible_bundles), precision or 6)) def validate_item_locations(pick_list): diff --git a/erpnext/stock/doctype/pick_list/test_pick_list.py b/erpnext/stock/doctype/pick_list/test_pick_list.py index 8ce05f15f7..f552299806 100644 --- a/erpnext/stock/doctype/pick_list/test_pick_list.py +++ b/erpnext/stock/doctype/pick_list/test_pick_list.py @@ -582,8 +582,23 @@ class TestPickList(FrappeTestCase): if dn_item.item_code == "_Test Item 2": self.assertEqual(dn_item.qty, 2) + def test_picklist_with_multi_uom(self): + warehouse = "_Test Warehouse - _TC" + item = make_item(properties={"uoms": [dict(uom="Box", conversion_factor=24)]}).name + make_stock_entry(item=item, to_warehouse=warehouse, qty=1000) + + so = make_sales_order(item_code=item, qty=10, rate=42, uom="Box") + pl = create_pick_list(so.name) + # pick half the qty + for loc in pl.locations: + loc.picked_qty = loc.stock_qty / 2 + pl.save() + pl.submit() + + so.reload() + self.assertEqual(so.per_picked, 50) + def test_picklist_with_bundles(self): - # from test_records.json warehouse = "_Test Warehouse - _TC" quantities = [5, 2] From 47e1a0104c83824a315a666c9a21956265c2b7d2 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Wed, 27 Apr 2022 13:31:23 +0530 Subject: [PATCH 074/106] fix: dont map picked qty and consider pick qty for new PL Co-Authored-By: marination --- erpnext/selling/doctype/sales_order/sales_order.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index a35e16f2c2..b463213f50 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -1245,14 +1245,18 @@ def create_pick_list(source_name, target_doc=None): from erpnext.stock.doctype.packed_item.packed_item import is_product_bundle def update_item_quantity(source, target, source_parent) -> None: - target.qty = flt(source.qty) - flt(source.delivered_qty) - target.stock_qty = (flt(source.qty) - flt(source.delivered_qty)) * flt(source.conversion_factor) + picked_qty = flt(source.picked_qty) / (flt(source.conversion_factor) or 1) + qty_to_be_picked = flt(source.qty) - max(picked_qty, flt(source.delivered_qty)) + + target.qty = qty_to_be_picked + target.stock_qty = qty_to_be_picked * flt(source.conversion_factor) def update_packed_item_qty(source, target, source_parent) -> None: qty = flt(source.qty) for item in source_parent.items: if source.parent_detail_docname == item.name: - pending_percent = (item.qty - item.delivered_qty) / item.qty + picked_qty = flt(item.picked_qty) / (flt(item.conversion_factor) or 1) + pending_percent = (item.qty - max(picked_qty, item.delivered_qty)) / item.qty target.qty = target.stock_qty = qty * pending_percent return @@ -1281,6 +1285,7 @@ def create_pick_list(source_name, target_doc=None): "name": "sales_order_item", "parent_detail_docname": "product_bundle_item", }, + "field_no_map": ["picked_qty"], "postprocess": update_packed_item_qty, }, }, From 3ae9fa98c4de9a1c016f6bcddd0b8ce5f1cbb5c5 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Wed, 27 Apr 2022 14:33:26 +0530 Subject: [PATCH 075/106] ci: failfast when merge conflict exists (#30823) [skip ci] --- .github/helper/install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/helper/install.sh b/.github/helper/install.sh index 859146bbcd..69749c93af 100644 --- a/.github/helper/install.sh +++ b/.github/helper/install.sh @@ -2,6 +2,13 @@ set -e +# Check for merge conflicts before proceeding +python -m compileall -f "${GITHUB_WORKSPACE}" +if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}" + then echo "Found merge conflicts" + exit 1 +fi + cd ~ || exit sudo apt-get install redis-server libcups2-dev From 9a8e3ef2356ac080d8922d5072a4e8a58c5eb676 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Wed, 27 Apr 2022 14:41:50 +0530 Subject: [PATCH 076/106] fix(UX): only show pick list when picking is pending [skip ci] --- erpnext/selling/doctype/sales_order/sales_order.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index 0b48f70eab..26c9996dba 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -152,7 +152,9 @@ erpnext.selling.SalesOrderController = class SalesOrderController extends erpnex } } - this.frm.add_custom_button(__('Pick List'), () => this.create_pick_list(), __('Create')); + if (flt(doc.per_picked, 6) < 100 && flt(doc.per_delivered, 6) < 100) { + this.frm.add_custom_button(__('Pick List'), () => this.create_pick_list(), __('Create')); + } const order_is_a_sale = ["Sales", "Shopping Cart"].indexOf(doc.order_type) !== -1; const order_is_maintenance = ["Maintenance"].indexOf(doc.order_type) !== -1; From ebd5f0b1bb4a2792bb768b720b800ca5d8724085 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Wed, 27 Apr 2022 14:53:20 +0530 Subject: [PATCH 077/106] chore: make picked qty read only --- erpnext/stock/doctype/packed_item/packed_item.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/doctype/packed_item/packed_item.json b/erpnext/stock/doctype/packed_item/packed_item.json index 4e67c84a0b..cb8eb30cb3 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.json +++ b/erpnext/stock/doctype/packed_item/packed_item.json @@ -237,17 +237,18 @@ "read_only": 1 }, { - "depends_on": "picked_qty", "fieldname": "picked_qty", "fieldtype": "Float", - "label": "Picked Qty" + "label": "Picked Qty", + "no_copy": 1, + "read_only": 1 } ], "idx": 1, "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2022-04-21 08:05:29.785362", + "modified": "2022-04-27 05:23:08.683245", "modified_by": "Administrator", "module": "Stock", "name": "Packed Item", From 0a07cd8f68f50c358dd9726feab830b34a35d2c9 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Wed, 27 Apr 2022 15:47:28 +0530 Subject: [PATCH 078/106] chore: "refactor" readme (#30825) [skip ci] --- README.md | 69 ++++++++++----------------------------------- TRADEMARK_POLICY.md | 36 +++++++++++++++++++++++ 2 files changed, 51 insertions(+), 54 deletions(-) create mode 100644 TRADEMARK_POLICY.md diff --git a/README.md b/README.md index e59c744712..f8f5f80b34 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@
- + + +

ERPNext

ERP made simple

@@ -32,14 +34,9 @@ ERPNext as a monolith includes the following areas for managing businesses: 1. [Customize ERPNext](https://erpnext.com/docs/user/manual/en/customize-erpnext) 1. [And More](https://erpnext.com/docs/user/manual/en/) -ERPNext requires MariaDB. - ERPNext is built on the [Frappe Framework](https://github.com/frappe/frappe), a full-stack web app framework built with Python & JavaScript. -- [User Guide](https://erpnext.com/docs/user) -- [Discussion Forum](https://discuss.erpnext.com/) - ---- +## Installation
@@ -56,21 +53,20 @@ ERPNext is built on the [Frappe Framework](https://github.com/frappe/frappe), a Use docker to deploy ERPNext in production or for development of [Frappe](https://github.com/frappe/frappe) apps. See https://github.com/frappe/frappe_docker for more details. -### Full Install +### Manual Install The Easy Way: our install script for bench will install all dependencies (e.g. MariaDB). See https://github.com/frappe/bench for more details. New passwords will be created for the ERPNext "Administrator" user, the MariaDB root user, and the frappe user (the script displays the passwords and saves them to ~/frappe_passwords.txt). ---- -## License +## Learning and community -GNU/General Public License (see [license.txt](license.txt)) +1. [Frappe School](https://frappe.school) - Learn Frappe Framework and ERPNext from the various courses by the maintainers or from the community. +2. [Official documentation](https://docs.erpnext.com/) - Extensive documentation for ERPNext. +3. [Discussion Forum](https://discuss.erpnext.com/) - Engage with community of ERPNext users and service providers. +4. [Telegram Group](https://t.me/erpnexthelp) - Get instant help from huge community of users. -The ERPNext code is licensed as GNU General Public License (v3) and the Documentation is licensed as Creative Commons (CC-BY-SA-3.0) and the copyright is owned by Frappe Technologies Pvt Ltd (Frappe) and Contributors. - ---- ## Contributing @@ -78,49 +74,14 @@ The ERPNext code is licensed as GNU General Public License (v3) and the Document 1. [Report Security Vulnerabilities](https://erpnext.com/security) 1. [Pull Request Requirements](https://github.com/frappe/erpnext/wiki/Contribution-Guidelines) 1. [Translations](https://translate.erpnext.com) -1. [Chart of Accounts](https://charts.erpnext.com) ---- -## Learning +## License -1. [Frappe School](https://frappe.school) - Learn Frappe Framework and ERPNext from the various courses by the maintainers or from the community. +GNU/General Public License (see [license.txt](license.txt)) ---- +The ERPNext code is licensed as GNU General Public License (v3) and the Documentation is licensed as Creative Commons (CC-BY-SA-3.0) and the copyright is owned by Frappe Technologies Pvt Ltd (Frappe) and Contributors. -## Logo and Trademark +## Logo and Trademark Policy -The brand name ERPNext and the logo are trademarks of Frappe Technologies Pvt. Ltd. - -### Introduction - -Frappe Technologies Pvt. Ltd. (Frappe) owns and oversees the trademarks for the ERPNext name and logos. We have developed this trademark usage policy with the following goals in mind: - -- We’d like to make it easy for anyone to use the ERPNext name or logo for community-oriented efforts that help spread and improve ERPNext. -- We’d like to make it clear how ERPNext-related businesses and projects can (and cannot) use the ERPNext name and logo. -- We’d like to make it hard for anyone to use the ERPNext name and logo to unfairly profit from, trick or confuse people who are looking for official ERPNext resources. - -### Frappe Trademark Usage Policy - -Permission from Frappe is required to use the ERPNext name or logo as part of any project, product, service, domain or company name. - -We will grant permission to use the ERPNext name and logo for projects that meet the following criteria: - -- The primary purpose of your project is to promote the spread and improvement of the ERPNext software. -- Your project is non-commercial in nature (it can make money to cover its costs or contribute to non-profit entities, but it cannot be run as a for-profit project or business). -Your project neither promotes nor is associated with entities that currently fail to comply with the GPL license under which ERPNext is distributed. -- If your project meets these criteria, you will be permitted to use the ERPNext name and logo to promote your project in any way you see fit with one exception: Please do not use ERPNext as part of a domain name. - -Use of the ERPNext name and logo is additionally allowed in the following situations: - -All other ERPNext-related businesses or projects can use the ERPNext name and logo to refer to and explain their services, but they cannot use them as part of a product, project, service, domain, or company name and they cannot use them in any way that suggests an affiliation with or endorsement by ERPNext or Frappe Technologies or the ERPNext open source project. For example, a consulting company can describe its business as “123 Web Services, offering ERPNext consulting for small businesses,” but cannot call its business “The ERPNext Consulting Company.” - -Similarly, it’s OK to use the ERPNext logo as part of a page that describes your products or services, but it is not OK to use it as part of your company or product logo or branding itself. Under no circumstances is it permitted to use ERPNext as part of a top-level domain name. - -We do not allow the use of the trademark in advertising, including AdSense/AdWords. - -Please note that it is not the goal of this policy to limit commercial activity around ERPNext. We encourage ERPNext-based businesses, and we would love to see hundreds of them. - -When in doubt about your use of the ERPNext name or logo, please contact Frappe Technologies for clarification. - -(inspired by WordPress) +Please read our [Logo and Trademark Policy](TRADEMARK_POLICY.md). diff --git a/TRADEMARK_POLICY.md b/TRADEMARK_POLICY.md new file mode 100644 index 0000000000..244c74778e --- /dev/null +++ b/TRADEMARK_POLICY.md @@ -0,0 +1,36 @@ +## Logo and Trademark Policy + +The brand name ERPNext and the logo are trademarks of Frappe Technologies Pvt. Ltd. + +### Introduction + +Frappe Technologies Pvt. Ltd. (Frappe) owns and oversees the trademarks for the ERPNext name and logos. We have developed this trademark usage policy with the following goals in mind: + +- We’d like to make it easy for anyone to use the ERPNext name or logo for community-oriented efforts that help spread and improve ERPNext. +- We’d like to make it clear how ERPNext-related businesses and projects can (and cannot) use the ERPNext name and logo. +- We’d like to make it hard for anyone to use the ERPNext name and logo to unfairly profit from, trick or confuse people who are looking for official ERPNext resources. + +### Frappe Trademark Usage Policy + +Permission from Frappe is required to use the ERPNext name or logo as part of any project, product, service, domain or company name. + +We will grant permission to use the ERPNext name and logo for projects that meet the following criteria: + +- The primary purpose of your project is to promote the spread and improvement of the ERPNext software. +- Your project is non-commercial in nature (it can make money to cover its costs or contribute to non-profit entities, but it cannot be run as a for-profit project or business). +Your project neither promotes nor is associated with entities that currently fail to comply with the GPL license under which ERPNext is distributed. +- If your project meets these criteria, you will be permitted to use the ERPNext name and logo to promote your project in any way you see fit with one exception: Please do not use ERPNext as part of a domain name. + +Use of the ERPNext name and logo is additionally allowed in the following situations: + +All other ERPNext-related businesses or projects can use the ERPNext name and logo to refer to and explain their services, but they cannot use them as part of a product, project, service, domain, or company name and they cannot use them in any way that suggests an affiliation with or endorsement by ERPNext or Frappe Technologies or the ERPNext open source project. For example, a consulting company can describe its business as “123 Web Services, offering ERPNext consulting for small businesses,” but cannot call its business “The ERPNext Consulting Company.” + +Similarly, it’s OK to use the ERPNext logo as part of a page that describes your products or services, but it is not OK to use it as part of your company or product logo or branding itself. Under no circumstances is it permitted to use ERPNext as part of a top-level domain name. + +We do not allow the use of the trademark in advertising, including AdSense/AdWords. + +Please note that it is not the goal of this policy to limit commercial activity around ERPNext. We encourage ERPNext-based businesses, and we would love to see hundreds of them. + +When in doubt about your use of the ERPNext name or logo, please contact Frappe Technologies for clarification. + +(inspired by WordPress) From 777f0204dd74a06dc6e9527cfb55a2f2ec103663 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Wed, 27 Apr 2022 17:47:40 +0530 Subject: [PATCH 079/106] test: create new item instead of using with _Test Item (#30827) Unnecessary dependency causes flake in stock. The test was reposting all entries for item just to test some behavior that is best tested on a newly created item _anyway_. --- .../delivery_note/test_delivery_note.py | 54 ------------------- .../test_stock_reconciliation.py | 22 ++++---- 2 files changed, 12 insertions(+), 64 deletions(-) diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py index b5a45578c6..f97e7ca9c6 100644 --- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py @@ -78,56 +78,6 @@ class TestDeliveryNote(FrappeTestCase): self.assertFalse(get_gl_entries("Delivery Note", dn.name)) - # def test_delivery_note_gl_entry(self): - # company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company') - - # set_valuation_method("_Test Item", "FIFO") - - # make_stock_entry(target="Stores - TCP1", qty=5, basic_rate=100) - - # stock_in_hand_account = get_inventory_account('_Test Company with perpetual inventory') - # prev_bal = get_balance_on(stock_in_hand_account) - - # dn = create_delivery_note(company='_Test Company with perpetual inventory', warehouse='Stores - TCP1', cost_center = 'Main - TCP1', expense_account = "Cost of Goods Sold - TCP1") - - # gl_entries = get_gl_entries("Delivery Note", dn.name) - # self.assertTrue(gl_entries) - - # stock_value_difference = abs(frappe.db.get_value("Stock Ledger Entry", - # {"voucher_type": "Delivery Note", "voucher_no": dn.name}, "stock_value_difference")) - - # expected_values = { - # stock_in_hand_account: [0.0, stock_value_difference], - # "Cost of Goods Sold - TCP1": [stock_value_difference, 0.0] - # } - # for i, gle in enumerate(gl_entries): - # self.assertEqual([gle.debit, gle.credit], expected_values.get(gle.account)) - - # # check stock in hand balance - # bal = get_balance_on(stock_in_hand_account) - # self.assertEqual(bal, prev_bal - stock_value_difference) - - # # back dated incoming entry - # make_stock_entry(posting_date=add_days(nowdate(), -2), target="Stores - TCP1", - # qty=5, basic_rate=100) - - # gl_entries = get_gl_entries("Delivery Note", dn.name) - # self.assertTrue(gl_entries) - - # stock_value_difference = abs(frappe.db.get_value("Stock Ledger Entry", - # {"voucher_type": "Delivery Note", "voucher_no": dn.name}, "stock_value_difference")) - - # expected_values = { - # stock_in_hand_account: [0.0, stock_value_difference], - # "Cost of Goods Sold - TCP1": [stock_value_difference, 0.0] - # } - # for i, gle in enumerate(gl_entries): - # self.assertEqual([gle.debit, gle.credit], expected_values.get(gle.account)) - - # dn.cancel() - # self.assertTrue(get_gl_entries("Delivery Note", dn.name)) - # set_perpetual_inventory(0, company) - def test_delivery_note_gl_entry_packing_item(self): company = frappe.db.get_value("Warehouse", "Stores - TCP1", "company") @@ -854,8 +804,6 @@ class TestDeliveryNote(FrappeTestCase): company="_Test Company with perpetual inventory", ) - company = frappe.db.get_value("Warehouse", "Stores - TCP1", "company") - set_valuation_method("_Test Item", "FIFO") make_stock_entry(target="Stores - TCP1", qty=5, basic_rate=100) @@ -881,8 +829,6 @@ class TestDeliveryNote(FrappeTestCase): def test_delivery_note_cost_center_with_balance_sheet_account(self): cost_center = "Main - TCP1" - company = frappe.db.get_value("Warehouse", "Stores - TCP1", "company") - set_valuation_method("_Test Item", "FIFO") make_stock_entry(target="Stores - TCP1", qty=5, basic_rate=100) diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py index e826e003c2..1e59aae9a8 100644 --- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py @@ -30,7 +30,6 @@ class TestStockReconciliation(FrappeTestCase): frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1) def tearDown(self): - frappe.flags.dont_execute_stock_reposts = None frappe.local.future_sle = {} def test_reco_for_fifo(self): @@ -40,7 +39,9 @@ class TestStockReconciliation(FrappeTestCase): self._test_reco_sle_gle("Moving Average") def _test_reco_sle_gle(self, valuation_method): - se1, se2, se3 = insert_existing_sle(warehouse="Stores - TCP1") + item_code = make_item(properties={"valuation_method": valuation_method}).name + + se1, se2, se3 = insert_existing_sle(warehouse="Stores - TCP1", item_code=item_code) company = frappe.db.get_value("Warehouse", "Stores - TCP1", "company") # [[qty, valuation_rate, posting_date, # posting_time, expected_stock_value, bin_qty, bin_valuation]] @@ -54,11 +55,9 @@ class TestStockReconciliation(FrappeTestCase): ] for d in input_data: - set_valuation_method("_Test Item", valuation_method) - last_sle = get_previous_sle( { - "item_code": "_Test Item", + "item_code": item_code, "warehouse": "Stores - TCP1", "posting_date": d[2], "posting_time": d[3], @@ -67,6 +66,7 @@ class TestStockReconciliation(FrappeTestCase): # submit stock reconciliation stock_reco = create_stock_reconciliation( + item_code=item_code, qty=d[0], rate=d[1], posting_date=d[2], @@ -481,9 +481,11 @@ class TestStockReconciliation(FrappeTestCase): """ from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note + frappe.db.rollback() + # repost will make this test useless, qty should update in realtime without reposts frappe.flags.dont_execute_stock_reposts = True - frappe.db.rollback() + self.addCleanup(frappe.flags.pop, "dont_execute_stock_reposts") item_code = make_item().name warehouse = "_Test Warehouse - _TC" @@ -594,26 +596,26 @@ def create_batch_item_with_batch(item_name, batch_id): b.save() -def insert_existing_sle(warehouse): +def insert_existing_sle(warehouse, item_code="_Test Item"): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry se1 = make_stock_entry( posting_date="2012-12-15", posting_time="02:00", - item_code="_Test Item", + item_code=item_code, target=warehouse, qty=10, basic_rate=700, ) se2 = make_stock_entry( - posting_date="2012-12-25", posting_time="03:00", item_code="_Test Item", source=warehouse, qty=15 + posting_date="2012-12-25", posting_time="03:00", item_code=item_code, source=warehouse, qty=15 ) se3 = make_stock_entry( posting_date="2013-01-05", posting_time="07:00", - item_code="_Test Item", + item_code=item_code, target=warehouse, qty=15, basic_rate=1200, From 69d369dd7fd1df23d036b45240e88591147794f3 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 27 Apr 2022 19:20:36 +0530 Subject: [PATCH 080/106] refactor: Remove education domain from ERPNext --- erpnext/education/__init__.py | 17 - erpnext/education/api.py | 444 ---------- .../course_wise_enrollment.json | 31 - .../course_wise_student_count.json | 31 - .../instructor_gender_diversity_ratio.json | 31 - .../program_enrollments.json | 30 - .../program_wise_enrollment.json | 31 - .../program_wise_fee_collection.json | 28 - ...ent_category_wise_program_enrollments.json | 31 - .../student_gender_diversity_ratio.json | 30 - erpnext/education/doctype/__init__.py | 0 .../doctype/academic_term/__init__.py | 0 .../doctype/academic_term/academic_term.js | 8 - .../doctype/academic_term/academic_term.json | 216 ----- .../doctype/academic_term/academic_term.py | 70 -- .../academic_term/academic_term_dashboard.py | 13 - .../academic_term/test_academic_term.py | 10 - .../doctype/academic_term/test_records.json | 27 - .../doctype/academic_year/__init__.py | 0 .../doctype/academic_year/academic_year.js | 2 - .../doctype/academic_year/academic_year.json | 154 ---- .../doctype/academic_year/academic_year.py | 18 - .../academic_year/academic_year_dashboard.py | 16 - .../academic_year/test_academic_year.py | 10 - .../doctype/academic_year/test_records.json | 18 - erpnext/education/doctype/article/__init__.py | 0 erpnext/education/doctype/article/article.js | 56 -- .../education/doctype/article/article.json | 81 -- erpnext/education/doctype/article/article.py | 22 - .../education/doctype/article/test_article.py | 8 - .../doctype/assessment_criteria/__init__.py | 0 .../assessment_criteria.js | 8 - .../assessment_criteria.json | 125 --- .../assessment_criteria.py | 15 - .../test_assessment_criteria.py | 10 - .../assessment_criteria/test_records.json | 8 - .../assessment_criteria_group/__init__.py | 0 .../assessment_criteria_group.js | 8 - .../assessment_criteria_group.json | 94 --- .../assessment_criteria_group.py | 9 - .../test_assessment_criteria_group.py | 10 - .../doctype/assessment_group/__init__.py | 0 .../assessment_group/assessment_group.js | 8 - .../assessment_group/assessment_group.json | 90 --- .../assessment_group/assessment_group.py | 9 - .../assessment_group_dashboard.py | 11 - .../assessment_group/assessment_group_tree.js | 3 - .../assessment_group/test_assessment_group.py | 10 - .../doctype/assessment_plan/__init__.py | 0 .../assessment_plan/assessment_plan.js | 78 -- .../assessment_plan/assessment_plan.json | 227 ------ .../assessment_plan/assessment_plan.py | 60 -- .../assessment_plan_dashboard.py | 12 - .../assessment_plan/test_assessment_plan.py | 10 - .../assessment_plan_criteria/__init__.py | 0 .../assessment_plan_criteria.json | 134 --- .../assessment_plan_criteria.py | 9 - .../doctype/assessment_result/__init__.py | 0 .../assessment_result/assessment_result.js | 125 --- .../assessment_result/assessment_result.json | 203 ----- .../assessment_result/assessment_result.py | 55 -- .../assessment_result_dashboard.py | 12 - .../test_assessment_result.py | 17 - .../assessment_result_detail/__init__.py | 0 .../assessment_result_detail.json | 66 -- .../assessment_result_detail.py | 9 - .../assessment_result_tool/__init__.py | 0 .../assessment_result_tool.js | 162 ---- .../assessment_result_tool.json | 235 ------ .../assessment_result_tool.py | 9 - .../test_assessment_result_tool.py | 8 - .../doctype/content_activity/__init__.py | 0 .../content_activity/content_activity.json | 141 ---- .../content_activity/content_activity.py | 9 - .../doctype/content_question/__init__.py | 0 .../content_question/content_question.js | 8 - .../content_question/content_question.json | 76 -- .../content_question/content_question.py | 9 - .../content_question/test_content_question.py | 8 - erpnext/education/doctype/course/__init__.py | 0 erpnext/education/doctype/course/course.js | 79 -- erpnext/education/doctype/course/course.json | 137 ---- erpnext/education/doctype/course/course.py | 59 -- .../doctype/course/course_dashboard.py | 18 - .../education/doctype/course/test_course.py | 45 -- .../doctype/course/test_records.json | 14 - .../doctype/course_activity/__init__.py | 0 .../course_activity/course_activity.js | 8 - .../course_activity/course_activity.json | 301 ------- .../course_activity/course_activity.py | 18 - .../course_activity/test_course_activity.py | 30 - .../course_assessment_criteria/__init__.py | 0 .../course_assessment_criteria.json | 134 --- .../course_assessment_criteria.py | 9 - .../doctype/course_content/__init__.py | 0 .../doctype/course_content/course_content.js | 8 - .../course_content/course_content.json | 142 ---- .../doctype/course_content/course_content.py | 9 - .../course_content/test_course_content.py | 8 - .../doctype/course_enrollment/__init__.py | 0 .../course_enrollment/course_enrollment.js | 8 - .../course_enrollment/course_enrollment.json | 233 ------ .../course_enrollment/course_enrollment.py | 112 --- .../course_enrollment_dashboard.py | 11 - .../test_course_enrollment.py | 57 -- .../doctype/course_schedule/__init__.py | 0 .../course_schedule/course_schedule.js | 16 - .../course_schedule/course_schedule.json | 143 ---- .../course_schedule/course_schedule.py | 64 -- .../course_schedule_calendar.js | 38 - .../course_schedule_dashboard.py | 11 - .../course_schedule/test_course_schedule.py | 98 --- .../course_scheduling_tool/__init__.py | 0 .../course_scheduling_tool.js | 44 - .../course_scheduling_tool.json | 168 ---- .../course_scheduling_tool.py | 119 --- .../test_course_scheduling_tool.py | 8 - .../doctype/course_topic/__init__.py | 0 .../doctype/course_topic/course_topic.js | 8 - .../doctype/course_topic/course_topic.json | 109 --- .../doctype/course_topic/course_topic.py | 9 - .../doctype/course_topic/test_course_topic.py | 8 - .../doctype/education_settings/__init__.py | 0 .../education_settings/education_settings.js | 8 - .../education_settings.json | 149 ---- .../education_settings/education_settings.py | 44 - .../test_education_settings.py | 8 - .../doctype/fee_category/__init__.py | 0 .../doctype/fee_category/fee_category.js | 8 - .../doctype/fee_category/fee_category.json | 171 ---- .../doctype/fee_category/fee_category.py | 9 - .../doctype/fee_category/test_fee_category.py | 10 - .../doctype/fee_category/test_records.json | 11 - .../doctype/fee_component/__init__.py | 0 .../doctype/fee_component/fee_component.json | 169 ---- .../doctype/fee_component/fee_component.py | 9 - .../doctype/fee_schedule/__init__.py | 0 .../doctype/fee_schedule/fee_schedule.js | 133 --- .../doctype/fee_schedule/fee_schedule.json | 327 -------- .../doctype/fee_schedule/fee_schedule.py | 173 ---- .../fee_schedule/fee_schedule_dashboard.py | 6 - .../doctype/fee_schedule/fee_schedule_list.js | 14 - .../doctype/fee_schedule/test_fee_schedule.py | 8 - .../doctype/fee_schedule_program/__init__.py | 0 .../fee_schedule_program.json | 142 ---- .../fee_schedule_program.py | 9 - .../fee_schedule_student_group/__init__.py | 0 .../fee_schedule_student_group.json | 109 --- .../fee_schedule_student_group.py | 9 - .../doctype/fee_structure/__init__.py | 0 .../doctype/fee_structure/fee_structure.js | 72 -- .../doctype/fee_structure/fee_structure.json | 215 ----- .../doctype/fee_structure/fee_structure.py | 36 - .../fee_structure/fee_structure_dashboard.py | 11 - .../fee_structure/test_fee_structure.py | 10 - .../doctype/fee_structure/test_records.json | 42 - erpnext/education/doctype/fees/__init__.py | 0 erpnext/education/doctype/fees/fees.js | 197 ----- erpnext/education/doctype/fees/fees.json | 395 --------- erpnext/education/doctype/fees/fees.py | 162 ---- erpnext/education/doctype/fees/fees_list.js | 12 - erpnext/education/doctype/fees/test_fees.py | 59 -- .../doctype/grading_scale/__init__.py | 0 .../doctype/grading_scale/grading_scale.js | 8 - .../doctype/grading_scale/grading_scale.json | 226 ------ .../doctype/grading_scale/grading_scale.py | 20 - .../grading_scale/grading_scale_dashboard.py | 12 - .../grading_scale/test_grading_scale.py | 10 - .../doctype/grading_scale/test_records.json | 19 - .../grading_scale_interval/__init__.py | 0 .../grading_scale_interval.json | 133 --- .../grading_scale_interval.py | 9 - .../education/doctype/guardian/__init__.py | 0 .../education/doctype/guardian/guardian.js | 20 - .../education/doctype/guardian/guardian.json | 580 ------------- .../education/doctype/guardian/guardian.py | 57 -- .../doctype/guardian/test_guardian.py | 10 - .../doctype/guardian_interest/__init__.py | 0 .../guardian_interest/guardian_interest.json | 72 -- .../guardian_interest/guardian_interest.py | 9 - .../doctype/guardian_student/__init__.py | 0 .../guardian_student/guardian_student.json | 132 --- .../guardian_student/guardian_student.py | 9 - .../education/doctype/instructor/__init__.py | 0 .../doctype/instructor/instructor.js | 64 -- .../doctype/instructor/instructor.json | 125 --- .../doctype/instructor/instructor.py | 50 -- .../instructor/instructor_dashboard.py | 17 - .../doctype/instructor/test_instructor.py | 10 - .../doctype/instructor/test_records.json | 12 - .../doctype/instructor_log/__init__.py | 0 .../instructor_log/instructor_log.json | 88 -- .../doctype/instructor_log/instructor_log.py | 9 - erpnext/education/doctype/options/__init__.py | 0 .../education/doctype/options/options.json | 107 --- erpnext/education/doctype/options/options.py | 9 - erpnext/education/doctype/program/__init__.py | 0 erpnext/education/doctype/program/program.js | 8 - .../education/doctype/program/program.json | 177 ---- erpnext/education/doctype/program/program.py | 15 - .../doctype/program/program_dashboard.py | 13 - .../education/doctype/program/test_program.py | 96 --- .../doctype/program/test_records.json | 12 - .../doctype/program_course/__init__.py | 0 .../program_course/program_course.json | 50 -- .../doctype/program_course/program_course.py | 9 - .../doctype/program_enrollment/__init__.py | 0 .../program_enrollment/program_enrollment.js | 104 --- .../program_enrollment.json | 218 ----- .../program_enrollment/program_enrollment.py | 220 ----- .../program_enrollment_dashboard.py | 9 - .../test_program_enrollment.py | 38 - .../program_enrollment_course/__init__.py | 0 .../program_enrollment_course.json | 107 --- .../program_enrollment_course.py | 9 - .../program_enrollment_fee/__init__.py | 0 .../program_enrollment_fee.json | 192 ----- .../program_enrollment_fee.py | 9 - .../program_enrollment_tool/__init__.py | 0 .../program_enrollment_tool.js | 51 -- .../program_enrollment_tool.json | 553 ------------- .../program_enrollment_tool.py | 95 --- .../test_program_enrollment_tool.py | 8 - .../__init__.py | 0 .../program_enrollment_tool_student.json | 68 -- .../program_enrollment_tool_student.py | 9 - .../education/doctype/program_fee/__init__.py | 0 .../doctype/program_fee/program_fee.json | 224 ----- .../doctype/program_fee/program_fee.py | 9 - .../education/doctype/question/__init__.py | 0 .../education/doctype/question/question.js | 8 - .../education/doctype/question/question.json | 80 -- .../education/doctype/question/question.py | 45 -- .../doctype/question/test_question.py | 8 - erpnext/education/doctype/quiz/__init__.py | 0 erpnext/education/doctype/quiz/quiz.js | 71 -- erpnext/education/doctype/quiz/quiz.json | 128 --- erpnext/education/doctype/quiz/quiz.py | 73 -- erpnext/education/doctype/quiz/test_quiz.py | 8 - .../doctype/quiz_activity/__init__.py | 0 .../doctype/quiz_activity/quiz_activity.js | 8 - .../doctype/quiz_activity/quiz_activity.json | 163 ---- .../doctype/quiz_activity/quiz_activity.py | 9 - .../quiz_activity/test_quiz_activity.py | 8 - .../doctype/quiz_question/__init__.py | 0 .../doctype/quiz_question/quiz_question.json | 40 - .../doctype/quiz_question/quiz_question.py | 9 - .../education/doctype/quiz_result/__init__.py | 0 .../doctype/quiz_result/quiz_result.js | 8 - .../doctype/quiz_result/quiz_result.json | 52 -- .../doctype/quiz_result/quiz_result.py | 9 - .../doctype/quiz_result/test_quiz_result.py | 8 - erpnext/education/doctype/room/__init__.py | 0 erpnext/education/doctype/room/room.js | 2 - erpnext/education/doctype/room/room.json | 161 ---- erpnext/education/doctype/room/room.py | 9 - .../education/doctype/room/room_dashboard.py | 14 - .../education/doctype/room/test_records.json | 17 - erpnext/education/doctype/room/test_room.py | 10 - .../doctype/school_house/__init__.py | 0 .../doctype/school_house/school_house.js | 8 - .../doctype/school_house/school_house.json | 94 --- .../doctype/school_house/school_house.py | 9 - .../doctype/school_house/test_school_house.py | 8 - erpnext/education/doctype/student/__init__.py | 0 erpnext/education/doctype/student/student.js | 63 -- .../education/doctype/student/student.json | 304 ------- erpnext/education/doctype/student/student.py | 223 ----- .../doctype/student/student_dashboard.py | 24 - .../education/doctype/student/student_list.js | 3 - .../doctype/student/test_records.json | 35 - .../education/doctype/student/test_student.py | 82 -- .../doctype/student_admission/__init__.py | 0 .../student_admission/student_admission.js | 22 - .../student_admission/student_admission.json | 122 --- .../student_admission/student_admission.py | 59 -- .../templates/student_admission.html | 77 -- .../templates/student_admission_row.html | 44 - .../test_student_admission.py | 10 - .../student_admission_program/__init__.py | 0 .../student_admission_program.json | 73 -- .../student_admission_program.py | 9 - .../doctype/student_applicant/__init__.py | 0 .../student_applicant/student_applicant.js | 62 -- .../student_applicant/student_applicant.json | 300 ------- .../student_applicant/student_applicant.py | 94 --- .../student_applicant_list.js | 21 - .../test_student_applicant.py | 10 - .../doctype/student_attendance/__init__.py | 0 .../student_attendance/student_attendance.js | 5 - .../student_attendance.json | 134 --- .../student_attendance/student_attendance.py | 132 --- .../student_attendance_dashboard.py | 12 - .../student_attendance_list.js | 11 - .../test_student_attendance.py | 10 - .../student_attendance_tool/__init__.py | 0 .../student_attendance_tool.js | 196 ----- .../student_attendance_tool.json | 118 --- .../student_attendance_tool.py | 60 -- .../test_student_attendance_tool.py | 8 - .../doctype/student_batch_name/__init__.py | 0 .../student_batch_name/student_batch_name.js | 8 - .../student_batch_name.json | 94 --- .../student_batch_name/student_batch_name.py | 9 - .../student_batch_name/test_records.json | 8 - .../test_student_batch_name.py | 10 - .../doctype/student_category/__init__.py | 0 .../student_category/student_category.js | 8 - .../student_category/student_category.json | 93 --- .../student_category/student_category.py | 9 - .../student_category_dashboard.py | 8 - .../student_category/test_student_category.py | 10 - .../doctype/student_group/__init__.py | 0 .../doctype/student_group/student_group.js | 145 ---- .../doctype/student_group/student_group.json | 161 ---- .../doctype/student_group/student_group.py | 200 ----- .../student_group/student_group_dashboard.py | 14 - .../doctype/student_group/test_records.json | 34 - .../student_group/test_student_group.py | 50 -- .../student_group_creation_tool/__init__.py | 0 .../student_group_creation_tool.js | 40 - .../student_group_creation_tool.json | 309 ------- .../student_group_creation_tool.py | 101 --- .../test_student_group_creation_tool.py | 8 - .../__init__.py | 0 .../student_group_creation_tool_course.json | 272 ------- .../student_group_creation_tool_course.py | 9 - .../student_group_instructor/__init__.py | 0 .../student_group_instructor.json | 142 ---- .../student_group_instructor.py | 9 - .../doctype/student_group_student/__init__.py | 0 .../student_group_student.json | 204 ----- .../student_group_student.py | 9 - .../doctype/student_guardian/__init__.py | 0 .../student_guardian/student_guardian.json | 141 ---- .../student_guardian/student_guardian.py | 9 - .../doctype/student_language/__init__.py | 0 .../student_language/student_language.js | 8 - .../student_language/student_language.json | 98 --- .../student_language/student_language.py | 9 - .../student_language/test_student_language.py | 10 - .../student_leave_application/__init__.py | 0 .../student_leave_application.js | 8 - .../student_leave_application.json | 165 ---- .../student_leave_application.py | 135 ---- .../student_leave_application_dashboard.py | 2 - .../test_student_leave_application.py | 131 --- .../education/doctype/student_log/__init__.py | 0 .../doctype/student_log/student_log.js | 8 - .../doctype/student_log/student_log.json | 423 ---------- .../doctype/student_log/student_log.py | 9 - .../doctype/student_log/test_student_log.py | 10 - .../__init__.py | 0 .../student_report_generation_tool.html | 371 --------- .../student_report_generation_tool.js | 66 -- .../student_report_generation_tool.json | 618 -------------- .../student_report_generation_tool.py | 121 --- .../test_student_report_generation_tool.py | 8 - .../doctype/student_sibling/__init__.py | 0 .../student_sibling/student_sibling.json | 306 ------- .../student_sibling/student_sibling.py | 9 - .../doctype/student_siblings/__init__.py | 0 .../student_siblings/student_siblings.json | 141 ---- .../student_siblings/student_siblings.py | 9 - erpnext/education/doctype/topic/__init__.py | 0 erpnext/education/doctype/topic/test_topic.py | 53 -- erpnext/education/doctype/topic/topic.js | 55 -- erpnext/education/doctype/topic/topic.json | 90 --- erpnext/education/doctype/topic/topic.py | 76 -- .../doctype/topic_content/__init__.py | 0 .../topic_content/test_topic_content.py | 8 - .../doctype/topic_content/topic_content.js | 8 - .../doctype/topic_content/topic_content.json | 44 - .../doctype/topic_content/topic_content.py | 9 - .../education/education.json | 62 -- .../education/education.json | 50 -- .../program_enrollments.json | 23 - .../student_applicants_to_review.json | 23 - .../total_instructors/total_instructors.json | 23 - .../total_students/total_students.json | 23 - .../create_a_course/create_a_course.json | 19 - .../create_a_program/create_a_program.json | 19 - .../create_a_student/create_a_student.json | 19 - .../create_a_topic/create_a_topic.json | 19 - .../create_an_instructor.json | 19 - .../enroll_a_student_in_a_program.json | 19 - .../introduction_to_program_and_courses.json | 19 - .../introduction_to_student_attendance.json | 19 - .../introduction_to_student_group.json | 20 - erpnext/education/report/__init__.py | 0 .../report/absent_student_report/__init__.py | 0 .../absent_student_report.js | 15 - .../absent_student_report.json | 24 - .../absent_student_report.py | 132 --- .../report/assessment_plan_status/__init__.py | 0 .../assessment_plan_status.js | 28 - .../assessment_plan_status.json | 24 - .../assessment_plan_status.py | 187 ----- .../course_wise_assessment_report/__init__.py | 0 .../course_wise_assessment_report.html | 50 -- .../course_wise_assessment_report.js | 40 - .../course_wise_assessment_report.json | 28 - .../course_wise_assessment_report.py | 303 ------- .../final_assessment_grades/__init__.py | 0 .../final_assessment_grades.js | 38 - .../final_assessment_grades.json | 27 - .../final_assessment_grades.py | 96 --- .../program_wise_fee_collection/__init__.py | 0 .../program_wise_fee_collection.js | 22 - .../program_wise_fee_collection.json | 32 - .../program_wise_fee_collection.py | 122 --- .../__init__.py | 0 .../student_and_guardian_contact_details.js | 29 - .../student_and_guardian_contact_details.json | 27 - .../student_and_guardian_contact_details.py | 151 ---- .../student_batch_wise_attendance/__init__.py | 0 .../student_batch_wise_attendance.js | 12 - .../student_batch_wise_attendance.json | 24 - .../student_batch_wise_attendance.py | 91 --- .../report/student_fee_collection/__init__.py | 0 .../student_fee_collection.json | 25 - .../__init__.py | 0 .../student_monthly_attendance_sheet.js | 42 - .../student_monthly_attendance_sheet.json | 24 - .../student_monthly_attendance_sheet.py | 154 ---- erpnext/education/setup.py | 60 -- erpnext/education/utils.py | 449 ---------- erpnext/education/web_form/__init__.py | 0 .../web_form/student_applicant/__init__.py | 0 .../student_applicant/student_applicant.js | 3 - .../student_applicant/student_applicant.json | 250 ------ .../student_applicant/student_applicant.py | 3 - .../workspace/education/education.json | 765 ------------------ 433 files changed, 24838 deletions(-) delete mode 100644 erpnext/education/__init__.py delete mode 100644 erpnext/education/api.py delete mode 100644 erpnext/education/dashboard_chart/course_wise_enrollment/course_wise_enrollment.json delete mode 100644 erpnext/education/dashboard_chart/course_wise_student_count/course_wise_student_count.json delete mode 100644 erpnext/education/dashboard_chart/instructor_gender_diversity_ratio/instructor_gender_diversity_ratio.json delete mode 100644 erpnext/education/dashboard_chart/program_enrollments/program_enrollments.json delete mode 100644 erpnext/education/dashboard_chart/program_wise_enrollment/program_wise_enrollment.json delete mode 100644 erpnext/education/dashboard_chart/program_wise_fee_collection/program_wise_fee_collection.json delete mode 100644 erpnext/education/dashboard_chart/student_category_wise_program_enrollments/student_category_wise_program_enrollments.json delete mode 100644 erpnext/education/dashboard_chart/student_gender_diversity_ratio/student_gender_diversity_ratio.json delete mode 100644 erpnext/education/doctype/__init__.py delete mode 100644 erpnext/education/doctype/academic_term/__init__.py delete mode 100644 erpnext/education/doctype/academic_term/academic_term.js delete mode 100644 erpnext/education/doctype/academic_term/academic_term.json delete mode 100644 erpnext/education/doctype/academic_term/academic_term.py delete mode 100644 erpnext/education/doctype/academic_term/academic_term_dashboard.py delete mode 100644 erpnext/education/doctype/academic_term/test_academic_term.py delete mode 100644 erpnext/education/doctype/academic_term/test_records.json delete mode 100644 erpnext/education/doctype/academic_year/__init__.py delete mode 100644 erpnext/education/doctype/academic_year/academic_year.js delete mode 100644 erpnext/education/doctype/academic_year/academic_year.json delete mode 100644 erpnext/education/doctype/academic_year/academic_year.py delete mode 100644 erpnext/education/doctype/academic_year/academic_year_dashboard.py delete mode 100644 erpnext/education/doctype/academic_year/test_academic_year.py delete mode 100644 erpnext/education/doctype/academic_year/test_records.json delete mode 100644 erpnext/education/doctype/article/__init__.py delete mode 100644 erpnext/education/doctype/article/article.js delete mode 100644 erpnext/education/doctype/article/article.json delete mode 100644 erpnext/education/doctype/article/article.py delete mode 100644 erpnext/education/doctype/article/test_article.py delete mode 100644 erpnext/education/doctype/assessment_criteria/__init__.py delete mode 100644 erpnext/education/doctype/assessment_criteria/assessment_criteria.js delete mode 100644 erpnext/education/doctype/assessment_criteria/assessment_criteria.json delete mode 100644 erpnext/education/doctype/assessment_criteria/assessment_criteria.py delete mode 100644 erpnext/education/doctype/assessment_criteria/test_assessment_criteria.py delete mode 100644 erpnext/education/doctype/assessment_criteria/test_records.json delete mode 100644 erpnext/education/doctype/assessment_criteria_group/__init__.py delete mode 100644 erpnext/education/doctype/assessment_criteria_group/assessment_criteria_group.js delete mode 100644 erpnext/education/doctype/assessment_criteria_group/assessment_criteria_group.json delete mode 100644 erpnext/education/doctype/assessment_criteria_group/assessment_criteria_group.py delete mode 100644 erpnext/education/doctype/assessment_criteria_group/test_assessment_criteria_group.py delete mode 100644 erpnext/education/doctype/assessment_group/__init__.py delete mode 100644 erpnext/education/doctype/assessment_group/assessment_group.js delete mode 100644 erpnext/education/doctype/assessment_group/assessment_group.json delete mode 100644 erpnext/education/doctype/assessment_group/assessment_group.py delete mode 100644 erpnext/education/doctype/assessment_group/assessment_group_dashboard.py delete mode 100644 erpnext/education/doctype/assessment_group/assessment_group_tree.js delete mode 100644 erpnext/education/doctype/assessment_group/test_assessment_group.py delete mode 100644 erpnext/education/doctype/assessment_plan/__init__.py delete mode 100644 erpnext/education/doctype/assessment_plan/assessment_plan.js delete mode 100644 erpnext/education/doctype/assessment_plan/assessment_plan.json delete mode 100644 erpnext/education/doctype/assessment_plan/assessment_plan.py delete mode 100644 erpnext/education/doctype/assessment_plan/assessment_plan_dashboard.py delete mode 100644 erpnext/education/doctype/assessment_plan/test_assessment_plan.py delete mode 100644 erpnext/education/doctype/assessment_plan_criteria/__init__.py delete mode 100644 erpnext/education/doctype/assessment_plan_criteria/assessment_plan_criteria.json delete mode 100644 erpnext/education/doctype/assessment_plan_criteria/assessment_plan_criteria.py delete mode 100644 erpnext/education/doctype/assessment_result/__init__.py delete mode 100644 erpnext/education/doctype/assessment_result/assessment_result.js delete mode 100644 erpnext/education/doctype/assessment_result/assessment_result.json delete mode 100644 erpnext/education/doctype/assessment_result/assessment_result.py delete mode 100644 erpnext/education/doctype/assessment_result/assessment_result_dashboard.py delete mode 100644 erpnext/education/doctype/assessment_result/test_assessment_result.py delete mode 100644 erpnext/education/doctype/assessment_result_detail/__init__.py delete mode 100644 erpnext/education/doctype/assessment_result_detail/assessment_result_detail.json delete mode 100644 erpnext/education/doctype/assessment_result_detail/assessment_result_detail.py delete mode 100644 erpnext/education/doctype/assessment_result_tool/__init__.py delete mode 100644 erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js delete mode 100644 erpnext/education/doctype/assessment_result_tool/assessment_result_tool.json delete mode 100644 erpnext/education/doctype/assessment_result_tool/assessment_result_tool.py delete mode 100644 erpnext/education/doctype/assessment_result_tool/test_assessment_result_tool.py delete mode 100644 erpnext/education/doctype/content_activity/__init__.py delete mode 100644 erpnext/education/doctype/content_activity/content_activity.json delete mode 100644 erpnext/education/doctype/content_activity/content_activity.py delete mode 100644 erpnext/education/doctype/content_question/__init__.py delete mode 100644 erpnext/education/doctype/content_question/content_question.js delete mode 100644 erpnext/education/doctype/content_question/content_question.json delete mode 100644 erpnext/education/doctype/content_question/content_question.py delete mode 100644 erpnext/education/doctype/content_question/test_content_question.py delete mode 100644 erpnext/education/doctype/course/__init__.py delete mode 100644 erpnext/education/doctype/course/course.js delete mode 100644 erpnext/education/doctype/course/course.json delete mode 100644 erpnext/education/doctype/course/course.py delete mode 100644 erpnext/education/doctype/course/course_dashboard.py delete mode 100644 erpnext/education/doctype/course/test_course.py delete mode 100644 erpnext/education/doctype/course/test_records.json delete mode 100644 erpnext/education/doctype/course_activity/__init__.py delete mode 100644 erpnext/education/doctype/course_activity/course_activity.js delete mode 100644 erpnext/education/doctype/course_activity/course_activity.json delete mode 100644 erpnext/education/doctype/course_activity/course_activity.py delete mode 100644 erpnext/education/doctype/course_activity/test_course_activity.py delete mode 100644 erpnext/education/doctype/course_assessment_criteria/__init__.py delete mode 100644 erpnext/education/doctype/course_assessment_criteria/course_assessment_criteria.json delete mode 100644 erpnext/education/doctype/course_assessment_criteria/course_assessment_criteria.py delete mode 100644 erpnext/education/doctype/course_content/__init__.py delete mode 100644 erpnext/education/doctype/course_content/course_content.js delete mode 100644 erpnext/education/doctype/course_content/course_content.json delete mode 100644 erpnext/education/doctype/course_content/course_content.py delete mode 100644 erpnext/education/doctype/course_content/test_course_content.py delete mode 100644 erpnext/education/doctype/course_enrollment/__init__.py delete mode 100644 erpnext/education/doctype/course_enrollment/course_enrollment.js delete mode 100644 erpnext/education/doctype/course_enrollment/course_enrollment.json delete mode 100644 erpnext/education/doctype/course_enrollment/course_enrollment.py delete mode 100644 erpnext/education/doctype/course_enrollment/course_enrollment_dashboard.py delete mode 100644 erpnext/education/doctype/course_enrollment/test_course_enrollment.py delete mode 100644 erpnext/education/doctype/course_schedule/__init__.py delete mode 100644 erpnext/education/doctype/course_schedule/course_schedule.js delete mode 100644 erpnext/education/doctype/course_schedule/course_schedule.json delete mode 100644 erpnext/education/doctype/course_schedule/course_schedule.py delete mode 100644 erpnext/education/doctype/course_schedule/course_schedule_calendar.js delete mode 100644 erpnext/education/doctype/course_schedule/course_schedule_dashboard.py delete mode 100644 erpnext/education/doctype/course_schedule/test_course_schedule.py delete mode 100644 erpnext/education/doctype/course_scheduling_tool/__init__.py delete mode 100644 erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js delete mode 100644 erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.json delete mode 100644 erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.py delete mode 100644 erpnext/education/doctype/course_scheduling_tool/test_course_scheduling_tool.py delete mode 100644 erpnext/education/doctype/course_topic/__init__.py delete mode 100644 erpnext/education/doctype/course_topic/course_topic.js delete mode 100644 erpnext/education/doctype/course_topic/course_topic.json delete mode 100644 erpnext/education/doctype/course_topic/course_topic.py delete mode 100644 erpnext/education/doctype/course_topic/test_course_topic.py delete mode 100644 erpnext/education/doctype/education_settings/__init__.py delete mode 100644 erpnext/education/doctype/education_settings/education_settings.js delete mode 100644 erpnext/education/doctype/education_settings/education_settings.json delete mode 100644 erpnext/education/doctype/education_settings/education_settings.py delete mode 100644 erpnext/education/doctype/education_settings/test_education_settings.py delete mode 100644 erpnext/education/doctype/fee_category/__init__.py delete mode 100644 erpnext/education/doctype/fee_category/fee_category.js delete mode 100644 erpnext/education/doctype/fee_category/fee_category.json delete mode 100644 erpnext/education/doctype/fee_category/fee_category.py delete mode 100644 erpnext/education/doctype/fee_category/test_fee_category.py delete mode 100644 erpnext/education/doctype/fee_category/test_records.json delete mode 100644 erpnext/education/doctype/fee_component/__init__.py delete mode 100644 erpnext/education/doctype/fee_component/fee_component.json delete mode 100644 erpnext/education/doctype/fee_component/fee_component.py delete mode 100644 erpnext/education/doctype/fee_schedule/__init__.py delete mode 100644 erpnext/education/doctype/fee_schedule/fee_schedule.js delete mode 100644 erpnext/education/doctype/fee_schedule/fee_schedule.json delete mode 100644 erpnext/education/doctype/fee_schedule/fee_schedule.py delete mode 100644 erpnext/education/doctype/fee_schedule/fee_schedule_dashboard.py delete mode 100644 erpnext/education/doctype/fee_schedule/fee_schedule_list.js delete mode 100644 erpnext/education/doctype/fee_schedule/test_fee_schedule.py delete mode 100644 erpnext/education/doctype/fee_schedule_program/__init__.py delete mode 100644 erpnext/education/doctype/fee_schedule_program/fee_schedule_program.json delete mode 100644 erpnext/education/doctype/fee_schedule_program/fee_schedule_program.py delete mode 100644 erpnext/education/doctype/fee_schedule_student_group/__init__.py delete mode 100644 erpnext/education/doctype/fee_schedule_student_group/fee_schedule_student_group.json delete mode 100644 erpnext/education/doctype/fee_schedule_student_group/fee_schedule_student_group.py delete mode 100644 erpnext/education/doctype/fee_structure/__init__.py delete mode 100644 erpnext/education/doctype/fee_structure/fee_structure.js delete mode 100644 erpnext/education/doctype/fee_structure/fee_structure.json delete mode 100644 erpnext/education/doctype/fee_structure/fee_structure.py delete mode 100644 erpnext/education/doctype/fee_structure/fee_structure_dashboard.py delete mode 100644 erpnext/education/doctype/fee_structure/test_fee_structure.py delete mode 100644 erpnext/education/doctype/fee_structure/test_records.json delete mode 100644 erpnext/education/doctype/fees/__init__.py delete mode 100644 erpnext/education/doctype/fees/fees.js delete mode 100644 erpnext/education/doctype/fees/fees.json delete mode 100644 erpnext/education/doctype/fees/fees.py delete mode 100644 erpnext/education/doctype/fees/fees_list.js delete mode 100644 erpnext/education/doctype/fees/test_fees.py delete mode 100644 erpnext/education/doctype/grading_scale/__init__.py delete mode 100644 erpnext/education/doctype/grading_scale/grading_scale.js delete mode 100644 erpnext/education/doctype/grading_scale/grading_scale.json delete mode 100644 erpnext/education/doctype/grading_scale/grading_scale.py delete mode 100644 erpnext/education/doctype/grading_scale/grading_scale_dashboard.py delete mode 100644 erpnext/education/doctype/grading_scale/test_grading_scale.py delete mode 100644 erpnext/education/doctype/grading_scale/test_records.json delete mode 100644 erpnext/education/doctype/grading_scale_interval/__init__.py delete mode 100644 erpnext/education/doctype/grading_scale_interval/grading_scale_interval.json delete mode 100644 erpnext/education/doctype/grading_scale_interval/grading_scale_interval.py delete mode 100644 erpnext/education/doctype/guardian/__init__.py delete mode 100644 erpnext/education/doctype/guardian/guardian.js delete mode 100644 erpnext/education/doctype/guardian/guardian.json delete mode 100644 erpnext/education/doctype/guardian/guardian.py delete mode 100644 erpnext/education/doctype/guardian/test_guardian.py delete mode 100644 erpnext/education/doctype/guardian_interest/__init__.py delete mode 100644 erpnext/education/doctype/guardian_interest/guardian_interest.json delete mode 100644 erpnext/education/doctype/guardian_interest/guardian_interest.py delete mode 100644 erpnext/education/doctype/guardian_student/__init__.py delete mode 100644 erpnext/education/doctype/guardian_student/guardian_student.json delete mode 100644 erpnext/education/doctype/guardian_student/guardian_student.py delete mode 100644 erpnext/education/doctype/instructor/__init__.py delete mode 100644 erpnext/education/doctype/instructor/instructor.js delete mode 100644 erpnext/education/doctype/instructor/instructor.json delete mode 100644 erpnext/education/doctype/instructor/instructor.py delete mode 100644 erpnext/education/doctype/instructor/instructor_dashboard.py delete mode 100644 erpnext/education/doctype/instructor/test_instructor.py delete mode 100644 erpnext/education/doctype/instructor/test_records.json delete mode 100644 erpnext/education/doctype/instructor_log/__init__.py delete mode 100644 erpnext/education/doctype/instructor_log/instructor_log.json delete mode 100644 erpnext/education/doctype/instructor_log/instructor_log.py delete mode 100644 erpnext/education/doctype/options/__init__.py delete mode 100644 erpnext/education/doctype/options/options.json delete mode 100644 erpnext/education/doctype/options/options.py delete mode 100644 erpnext/education/doctype/program/__init__.py delete mode 100644 erpnext/education/doctype/program/program.js delete mode 100644 erpnext/education/doctype/program/program.json delete mode 100644 erpnext/education/doctype/program/program.py delete mode 100644 erpnext/education/doctype/program/program_dashboard.py delete mode 100644 erpnext/education/doctype/program/test_program.py delete mode 100644 erpnext/education/doctype/program/test_records.json delete mode 100644 erpnext/education/doctype/program_course/__init__.py delete mode 100644 erpnext/education/doctype/program_course/program_course.json delete mode 100644 erpnext/education/doctype/program_course/program_course.py delete mode 100644 erpnext/education/doctype/program_enrollment/__init__.py delete mode 100644 erpnext/education/doctype/program_enrollment/program_enrollment.js delete mode 100644 erpnext/education/doctype/program_enrollment/program_enrollment.json delete mode 100644 erpnext/education/doctype/program_enrollment/program_enrollment.py delete mode 100644 erpnext/education/doctype/program_enrollment/program_enrollment_dashboard.py delete mode 100644 erpnext/education/doctype/program_enrollment/test_program_enrollment.py delete mode 100644 erpnext/education/doctype/program_enrollment_course/__init__.py delete mode 100644 erpnext/education/doctype/program_enrollment_course/program_enrollment_course.json delete mode 100644 erpnext/education/doctype/program_enrollment_course/program_enrollment_course.py delete mode 100644 erpnext/education/doctype/program_enrollment_fee/__init__.py delete mode 100644 erpnext/education/doctype/program_enrollment_fee/program_enrollment_fee.json delete mode 100644 erpnext/education/doctype/program_enrollment_fee/program_enrollment_fee.py delete mode 100644 erpnext/education/doctype/program_enrollment_tool/__init__.py delete mode 100644 erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.js delete mode 100644 erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.json delete mode 100644 erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.py delete mode 100644 erpnext/education/doctype/program_enrollment_tool/test_program_enrollment_tool.py delete mode 100644 erpnext/education/doctype/program_enrollment_tool_student/__init__.py delete mode 100644 erpnext/education/doctype/program_enrollment_tool_student/program_enrollment_tool_student.json delete mode 100644 erpnext/education/doctype/program_enrollment_tool_student/program_enrollment_tool_student.py delete mode 100644 erpnext/education/doctype/program_fee/__init__.py delete mode 100644 erpnext/education/doctype/program_fee/program_fee.json delete mode 100644 erpnext/education/doctype/program_fee/program_fee.py delete mode 100644 erpnext/education/doctype/question/__init__.py delete mode 100644 erpnext/education/doctype/question/question.js delete mode 100644 erpnext/education/doctype/question/question.json delete mode 100644 erpnext/education/doctype/question/question.py delete mode 100644 erpnext/education/doctype/question/test_question.py delete mode 100644 erpnext/education/doctype/quiz/__init__.py delete mode 100644 erpnext/education/doctype/quiz/quiz.js delete mode 100644 erpnext/education/doctype/quiz/quiz.json delete mode 100644 erpnext/education/doctype/quiz/quiz.py delete mode 100644 erpnext/education/doctype/quiz/test_quiz.py delete mode 100644 erpnext/education/doctype/quiz_activity/__init__.py delete mode 100644 erpnext/education/doctype/quiz_activity/quiz_activity.js delete mode 100644 erpnext/education/doctype/quiz_activity/quiz_activity.json delete mode 100644 erpnext/education/doctype/quiz_activity/quiz_activity.py delete mode 100644 erpnext/education/doctype/quiz_activity/test_quiz_activity.py delete mode 100644 erpnext/education/doctype/quiz_question/__init__.py delete mode 100644 erpnext/education/doctype/quiz_question/quiz_question.json delete mode 100644 erpnext/education/doctype/quiz_question/quiz_question.py delete mode 100644 erpnext/education/doctype/quiz_result/__init__.py delete mode 100644 erpnext/education/doctype/quiz_result/quiz_result.js delete mode 100644 erpnext/education/doctype/quiz_result/quiz_result.json delete mode 100644 erpnext/education/doctype/quiz_result/quiz_result.py delete mode 100644 erpnext/education/doctype/quiz_result/test_quiz_result.py delete mode 100644 erpnext/education/doctype/room/__init__.py delete mode 100644 erpnext/education/doctype/room/room.js delete mode 100644 erpnext/education/doctype/room/room.json delete mode 100644 erpnext/education/doctype/room/room.py delete mode 100644 erpnext/education/doctype/room/room_dashboard.py delete mode 100644 erpnext/education/doctype/room/test_records.json delete mode 100644 erpnext/education/doctype/room/test_room.py delete mode 100644 erpnext/education/doctype/school_house/__init__.py delete mode 100644 erpnext/education/doctype/school_house/school_house.js delete mode 100644 erpnext/education/doctype/school_house/school_house.json delete mode 100644 erpnext/education/doctype/school_house/school_house.py delete mode 100644 erpnext/education/doctype/school_house/test_school_house.py delete mode 100644 erpnext/education/doctype/student/__init__.py delete mode 100644 erpnext/education/doctype/student/student.js delete mode 100644 erpnext/education/doctype/student/student.json delete mode 100644 erpnext/education/doctype/student/student.py delete mode 100644 erpnext/education/doctype/student/student_dashboard.py delete mode 100644 erpnext/education/doctype/student/student_list.js delete mode 100644 erpnext/education/doctype/student/test_records.json delete mode 100644 erpnext/education/doctype/student/test_student.py delete mode 100644 erpnext/education/doctype/student_admission/__init__.py delete mode 100644 erpnext/education/doctype/student_admission/student_admission.js delete mode 100644 erpnext/education/doctype/student_admission/student_admission.json delete mode 100644 erpnext/education/doctype/student_admission/student_admission.py delete mode 100644 erpnext/education/doctype/student_admission/templates/student_admission.html delete mode 100644 erpnext/education/doctype/student_admission/templates/student_admission_row.html delete mode 100644 erpnext/education/doctype/student_admission/test_student_admission.py delete mode 100644 erpnext/education/doctype/student_admission_program/__init__.py delete mode 100644 erpnext/education/doctype/student_admission_program/student_admission_program.json delete mode 100644 erpnext/education/doctype/student_admission_program/student_admission_program.py delete mode 100644 erpnext/education/doctype/student_applicant/__init__.py delete mode 100644 erpnext/education/doctype/student_applicant/student_applicant.js delete mode 100644 erpnext/education/doctype/student_applicant/student_applicant.json delete mode 100644 erpnext/education/doctype/student_applicant/student_applicant.py delete mode 100644 erpnext/education/doctype/student_applicant/student_applicant_list.js delete mode 100644 erpnext/education/doctype/student_applicant/test_student_applicant.py delete mode 100644 erpnext/education/doctype/student_attendance/__init__.py delete mode 100644 erpnext/education/doctype/student_attendance/student_attendance.js delete mode 100644 erpnext/education/doctype/student_attendance/student_attendance.json delete mode 100644 erpnext/education/doctype/student_attendance/student_attendance.py delete mode 100644 erpnext/education/doctype/student_attendance/student_attendance_dashboard.py delete mode 100644 erpnext/education/doctype/student_attendance/student_attendance_list.js delete mode 100644 erpnext/education/doctype/student_attendance/test_student_attendance.py delete mode 100644 erpnext/education/doctype/student_attendance_tool/__init__.py delete mode 100644 erpnext/education/doctype/student_attendance_tool/student_attendance_tool.js delete mode 100644 erpnext/education/doctype/student_attendance_tool/student_attendance_tool.json delete mode 100644 erpnext/education/doctype/student_attendance_tool/student_attendance_tool.py delete mode 100644 erpnext/education/doctype/student_attendance_tool/test_student_attendance_tool.py delete mode 100644 erpnext/education/doctype/student_batch_name/__init__.py delete mode 100644 erpnext/education/doctype/student_batch_name/student_batch_name.js delete mode 100644 erpnext/education/doctype/student_batch_name/student_batch_name.json delete mode 100644 erpnext/education/doctype/student_batch_name/student_batch_name.py delete mode 100644 erpnext/education/doctype/student_batch_name/test_records.json delete mode 100644 erpnext/education/doctype/student_batch_name/test_student_batch_name.py delete mode 100644 erpnext/education/doctype/student_category/__init__.py delete mode 100644 erpnext/education/doctype/student_category/student_category.js delete mode 100644 erpnext/education/doctype/student_category/student_category.json delete mode 100644 erpnext/education/doctype/student_category/student_category.py delete mode 100644 erpnext/education/doctype/student_category/student_category_dashboard.py delete mode 100644 erpnext/education/doctype/student_category/test_student_category.py delete mode 100644 erpnext/education/doctype/student_group/__init__.py delete mode 100644 erpnext/education/doctype/student_group/student_group.js delete mode 100644 erpnext/education/doctype/student_group/student_group.json delete mode 100644 erpnext/education/doctype/student_group/student_group.py delete mode 100644 erpnext/education/doctype/student_group/student_group_dashboard.py delete mode 100644 erpnext/education/doctype/student_group/test_records.json delete mode 100644 erpnext/education/doctype/student_group/test_student_group.py delete mode 100644 erpnext/education/doctype/student_group_creation_tool/__init__.py delete mode 100644 erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.js delete mode 100644 erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.json delete mode 100644 erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.py delete mode 100644 erpnext/education/doctype/student_group_creation_tool/test_student_group_creation_tool.py delete mode 100644 erpnext/education/doctype/student_group_creation_tool_course/__init__.py delete mode 100644 erpnext/education/doctype/student_group_creation_tool_course/student_group_creation_tool_course.json delete mode 100644 erpnext/education/doctype/student_group_creation_tool_course/student_group_creation_tool_course.py delete mode 100644 erpnext/education/doctype/student_group_instructor/__init__.py delete mode 100644 erpnext/education/doctype/student_group_instructor/student_group_instructor.json delete mode 100644 erpnext/education/doctype/student_group_instructor/student_group_instructor.py delete mode 100644 erpnext/education/doctype/student_group_student/__init__.py delete mode 100644 erpnext/education/doctype/student_group_student/student_group_student.json delete mode 100644 erpnext/education/doctype/student_group_student/student_group_student.py delete mode 100644 erpnext/education/doctype/student_guardian/__init__.py delete mode 100644 erpnext/education/doctype/student_guardian/student_guardian.json delete mode 100644 erpnext/education/doctype/student_guardian/student_guardian.py delete mode 100644 erpnext/education/doctype/student_language/__init__.py delete mode 100644 erpnext/education/doctype/student_language/student_language.js delete mode 100644 erpnext/education/doctype/student_language/student_language.json delete mode 100644 erpnext/education/doctype/student_language/student_language.py delete mode 100644 erpnext/education/doctype/student_language/test_student_language.py delete mode 100644 erpnext/education/doctype/student_leave_application/__init__.py delete mode 100644 erpnext/education/doctype/student_leave_application/student_leave_application.js delete mode 100644 erpnext/education/doctype/student_leave_application/student_leave_application.json delete mode 100644 erpnext/education/doctype/student_leave_application/student_leave_application.py delete mode 100644 erpnext/education/doctype/student_leave_application/student_leave_application_dashboard.py delete mode 100644 erpnext/education/doctype/student_leave_application/test_student_leave_application.py delete mode 100644 erpnext/education/doctype/student_log/__init__.py delete mode 100644 erpnext/education/doctype/student_log/student_log.js delete mode 100644 erpnext/education/doctype/student_log/student_log.json delete mode 100644 erpnext/education/doctype/student_log/student_log.py delete mode 100644 erpnext/education/doctype/student_log/test_student_log.py delete mode 100644 erpnext/education/doctype/student_report_generation_tool/__init__.py delete mode 100644 erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html delete mode 100644 erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.js delete mode 100644 erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.json delete mode 100644 erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.py delete mode 100644 erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.py delete mode 100644 erpnext/education/doctype/student_sibling/__init__.py delete mode 100644 erpnext/education/doctype/student_sibling/student_sibling.json delete mode 100644 erpnext/education/doctype/student_sibling/student_sibling.py delete mode 100644 erpnext/education/doctype/student_siblings/__init__.py delete mode 100644 erpnext/education/doctype/student_siblings/student_siblings.json delete mode 100644 erpnext/education/doctype/student_siblings/student_siblings.py delete mode 100644 erpnext/education/doctype/topic/__init__.py delete mode 100644 erpnext/education/doctype/topic/test_topic.py delete mode 100644 erpnext/education/doctype/topic/topic.js delete mode 100644 erpnext/education/doctype/topic/topic.json delete mode 100644 erpnext/education/doctype/topic/topic.py delete mode 100644 erpnext/education/doctype/topic_content/__init__.py delete mode 100644 erpnext/education/doctype/topic_content/test_topic_content.py delete mode 100644 erpnext/education/doctype/topic_content/topic_content.js delete mode 100644 erpnext/education/doctype/topic_content/topic_content.json delete mode 100644 erpnext/education/doctype/topic_content/topic_content.py delete mode 100644 erpnext/education/education_dashboard/education/education.json delete mode 100644 erpnext/education/module_onboarding/education/education.json delete mode 100644 erpnext/education/number_card/program_enrollments/program_enrollments.json delete mode 100644 erpnext/education/number_card/student_applicants_to_review/student_applicants_to_review.json delete mode 100644 erpnext/education/number_card/total_instructors/total_instructors.json delete mode 100644 erpnext/education/number_card/total_students/total_students.json delete mode 100644 erpnext/education/onboarding_step/create_a_course/create_a_course.json delete mode 100644 erpnext/education/onboarding_step/create_a_program/create_a_program.json delete mode 100644 erpnext/education/onboarding_step/create_a_student/create_a_student.json delete mode 100644 erpnext/education/onboarding_step/create_a_topic/create_a_topic.json delete mode 100644 erpnext/education/onboarding_step/create_an_instructor/create_an_instructor.json delete mode 100644 erpnext/education/onboarding_step/enroll_a_student_in_a_program/enroll_a_student_in_a_program.json delete mode 100644 erpnext/education/onboarding_step/introduction_to_program_and_courses/introduction_to_program_and_courses.json delete mode 100644 erpnext/education/onboarding_step/introduction_to_student_attendance/introduction_to_student_attendance.json delete mode 100644 erpnext/education/onboarding_step/introduction_to_student_group/introduction_to_student_group.json delete mode 100644 erpnext/education/report/__init__.py delete mode 100644 erpnext/education/report/absent_student_report/__init__.py delete mode 100644 erpnext/education/report/absent_student_report/absent_student_report.js delete mode 100644 erpnext/education/report/absent_student_report/absent_student_report.json delete mode 100644 erpnext/education/report/absent_student_report/absent_student_report.py delete mode 100644 erpnext/education/report/assessment_plan_status/__init__.py delete mode 100644 erpnext/education/report/assessment_plan_status/assessment_plan_status.js delete mode 100644 erpnext/education/report/assessment_plan_status/assessment_plan_status.json delete mode 100644 erpnext/education/report/assessment_plan_status/assessment_plan_status.py delete mode 100644 erpnext/education/report/course_wise_assessment_report/__init__.py delete mode 100644 erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.html delete mode 100644 erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.js delete mode 100644 erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.json delete mode 100644 erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py delete mode 100644 erpnext/education/report/final_assessment_grades/__init__.py delete mode 100644 erpnext/education/report/final_assessment_grades/final_assessment_grades.js delete mode 100644 erpnext/education/report/final_assessment_grades/final_assessment_grades.json delete mode 100644 erpnext/education/report/final_assessment_grades/final_assessment_grades.py delete mode 100644 erpnext/education/report/program_wise_fee_collection/__init__.py delete mode 100644 erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.js delete mode 100644 erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.json delete mode 100644 erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.py delete mode 100644 erpnext/education/report/student_and_guardian_contact_details/__init__.py delete mode 100644 erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.js delete mode 100644 erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.json delete mode 100644 erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py delete mode 100644 erpnext/education/report/student_batch_wise_attendance/__init__.py delete mode 100644 erpnext/education/report/student_batch_wise_attendance/student_batch_wise_attendance.js delete mode 100644 erpnext/education/report/student_batch_wise_attendance/student_batch_wise_attendance.json delete mode 100644 erpnext/education/report/student_batch_wise_attendance/student_batch_wise_attendance.py delete mode 100644 erpnext/education/report/student_fee_collection/__init__.py delete mode 100644 erpnext/education/report/student_fee_collection/student_fee_collection.json delete mode 100644 erpnext/education/report/student_monthly_attendance_sheet/__init__.py delete mode 100644 erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.js delete mode 100644 erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.json delete mode 100644 erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.py delete mode 100644 erpnext/education/setup.py delete mode 100644 erpnext/education/utils.py delete mode 100644 erpnext/education/web_form/__init__.py delete mode 100644 erpnext/education/web_form/student_applicant/__init__.py delete mode 100644 erpnext/education/web_form/student_applicant/student_applicant.js delete mode 100644 erpnext/education/web_form/student_applicant/student_applicant.json delete mode 100644 erpnext/education/web_form/student_applicant/student_applicant.py delete mode 100644 erpnext/education/workspace/education/education.json diff --git a/erpnext/education/__init__.py b/erpnext/education/__init__.py deleted file mode 100644 index f6f84b3730..0000000000 --- a/erpnext/education/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -import frappe -from frappe import _ - - -class StudentNotInGroupError(frappe.ValidationError): - pass - - -def validate_student_belongs_to_group(student, student_group): - groups = frappe.db.get_all("Student Group Student", ["parent"], dict(student=student, active=1)) - if not student_group in [d.parent for d in groups]: - frappe.throw( - _("Student {0} does not belong to group {1}").format( - frappe.bold(student), frappe.bold(student_group) - ), - StudentNotInGroupError, - ) diff --git a/erpnext/education/api.py b/erpnext/education/api.py deleted file mode 100644 index 8fd1725b2d..0000000000 --- a/erpnext/education/api.py +++ /dev/null @@ -1,444 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -import json - -import frappe -from frappe import _ -from frappe.email.doctype.email_group.email_group import add_subscribers -from frappe.model.mapper import get_mapped_doc -from frappe.utils import cstr, flt, getdate - - -def get_course(program): - """Return list of courses for a particular program - :param program: Program - """ - courses = frappe.db.sql( - """select course, course_name from `tabProgram Course` where parent=%s""", (program), as_dict=1 - ) - return courses - - -@frappe.whitelist() -def enroll_student(source_name): - """Creates a Student Record and returns a Program Enrollment. - - :param source_name: Student Applicant. - """ - frappe.publish_realtime("enroll_student_progress", {"progress": [1, 4]}, user=frappe.session.user) - student = get_mapped_doc( - "Student Applicant", - source_name, - {"Student Applicant": {"doctype": "Student", "field_map": {"name": "student_applicant"}}}, - ignore_permissions=True, - ) - student.save() - - student_applicant = frappe.db.get_value( - "Student Applicant", source_name, ["student_category", "program"], as_dict=True - ) - program_enrollment = frappe.new_doc("Program Enrollment") - program_enrollment.student = student.name - program_enrollment.student_category = student_applicant.student_category - program_enrollment.student_name = student.title - program_enrollment.program = student_applicant.program - frappe.publish_realtime("enroll_student_progress", {"progress": [2, 4]}, user=frappe.session.user) - return program_enrollment - - -@frappe.whitelist() -def check_attendance_records_exist(course_schedule=None, student_group=None, date=None): - """Check if Attendance Records are made against the specified Course Schedule or Student Group for given date. - - :param course_schedule: Course Schedule. - :param student_group: Student Group. - :param date: Date. - """ - if course_schedule: - return frappe.get_list("Student Attendance", filters={"course_schedule": course_schedule}) - else: - return frappe.get_list( - "Student Attendance", filters={"student_group": student_group, "date": date} - ) - - -@frappe.whitelist() -def mark_attendance( - students_present, students_absent, course_schedule=None, student_group=None, date=None -): - """Creates Multiple Attendance Records. - - :param students_present: Students Present JSON. - :param students_absent: Students Absent JSON. - :param course_schedule: Course Schedule. - :param student_group: Student Group. - :param date: Date. - """ - - if student_group: - academic_year = frappe.db.get_value("Student Group", student_group, "academic_year") - if academic_year: - year_start_date, year_end_date = frappe.db.get_value( - "Academic Year", academic_year, ["year_start_date", "year_end_date"] - ) - if getdate(date) < getdate(year_start_date) or getdate(date) > getdate(year_end_date): - frappe.throw( - _("Attendance cannot be marked outside of Academic Year {0}").format(academic_year) - ) - - present = json.loads(students_present) - absent = json.loads(students_absent) - - for d in present: - make_attendance_records( - d["student"], d["student_name"], "Present", course_schedule, student_group, date - ) - - for d in absent: - make_attendance_records( - d["student"], d["student_name"], "Absent", course_schedule, student_group, date - ) - - frappe.db.commit() - frappe.msgprint(_("Attendance has been marked successfully.")) - - -def make_attendance_records( - student, student_name, status, course_schedule=None, student_group=None, date=None -): - """Creates/Update Attendance Record. - - :param student: Student. - :param student_name: Student Name. - :param course_schedule: Course Schedule. - :param status: Status (Present/Absent) - """ - student_attendance = frappe.get_doc( - { - "doctype": "Student Attendance", - "student": student, - "course_schedule": course_schedule, - "student_group": student_group, - "date": date, - } - ) - if not student_attendance: - student_attendance = frappe.new_doc("Student Attendance") - student_attendance.student = student - student_attendance.student_name = student_name - student_attendance.course_schedule = course_schedule - student_attendance.student_group = student_group - student_attendance.date = date - student_attendance.status = status - student_attendance.save() - student_attendance.submit() - - -@frappe.whitelist() -def get_student_guardians(student): - """Returns List of Guardians of a Student. - - :param student: Student. - """ - guardians = frappe.get_all("Student Guardian", fields=["guardian"], filters={"parent": student}) - return guardians - - -@frappe.whitelist() -def get_student_group_students(student_group, include_inactive=0): - """Returns List of student, student_name in Student Group. - - :param student_group: Student Group. - """ - if include_inactive: - students = frappe.get_all( - "Student Group Student", - fields=["student", "student_name"], - filters={"parent": student_group}, - order_by="group_roll_number", - ) - else: - students = frappe.get_all( - "Student Group Student", - fields=["student", "student_name"], - filters={"parent": student_group, "active": 1}, - order_by="group_roll_number", - ) - return students - - -@frappe.whitelist() -def get_fee_structure(program, academic_term=None): - """Returns Fee Structure. - - :param program: Program. - :param academic_term: Academic Term. - """ - fee_structure = frappe.db.get_values( - "Fee Structure", {"program": program, "academic_term": academic_term}, "name", as_dict=True - ) - return fee_structure[0].name if fee_structure else None - - -@frappe.whitelist() -def get_fee_components(fee_structure): - """Returns Fee Components. - - :param fee_structure: Fee Structure. - """ - if fee_structure: - fs = frappe.get_all( - "Fee Component", - fields=["fees_category", "description", "amount"], - filters={"parent": fee_structure}, - order_by="idx", - ) - return fs - - -@frappe.whitelist() -def get_fee_schedule(program, student_category=None): - """Returns Fee Schedule. - - :param program: Program. - :param student_category: Student Category - """ - fs = frappe.get_all( - "Program Fee", - fields=["academic_term", "fee_structure", "due_date", "amount"], - filters={"parent": program, "student_category": student_category}, - order_by="idx", - ) - return fs - - -@frappe.whitelist() -def collect_fees(fees, amt): - paid_amount = flt(amt) + flt(frappe.db.get_value("Fees", fees, "paid_amount")) - total_amount = flt(frappe.db.get_value("Fees", fees, "total_amount")) - frappe.db.set_value("Fees", fees, "paid_amount", paid_amount) - frappe.db.set_value("Fees", fees, "outstanding_amount", (total_amount - paid_amount)) - return paid_amount - - -@frappe.whitelist() -def get_course_schedule_events(start, end, filters=None): - """Returns events for Course Schedule Calendar view rendering. - - :param start: Start date-time. - :param end: End date-time. - :param filters: Filters (JSON). - """ - from frappe.desk.calendar import get_event_conditions - - conditions = get_event_conditions("Course Schedule", filters) - - data = frappe.db.sql( - """select name, course, color, - timestamp(schedule_date, from_time) as from_time, - timestamp(schedule_date, to_time) as to_time, - room, student_group, 0 as 'allDay' - from `tabCourse Schedule` - where ( schedule_date between %(start)s and %(end)s ) - {conditions}""".format( - conditions=conditions - ), - {"start": start, "end": end}, - as_dict=True, - update={"allDay": 0}, - ) - - return data - - -@frappe.whitelist() -def get_assessment_criteria(course): - """Returns Assessmemt Criteria and their Weightage from Course Master. - - :param Course: Course - """ - return frappe.get_all( - "Course Assessment Criteria", - fields=["assessment_criteria", "weightage"], - filters={"parent": course}, - order_by="idx", - ) - - -@frappe.whitelist() -def get_assessment_students(assessment_plan, student_group): - student_list = get_student_group_students(student_group) - for i, student in enumerate(student_list): - result = get_result(student.student, assessment_plan) - if result: - student_result = {} - for d in result.details: - student_result.update({d.assessment_criteria: [cstr(d.score), d.grade]}) - student_result.update( - {"total_score": [cstr(result.total_score), result.grade], "comment": result.comment} - ) - student.update( - {"assessment_details": student_result, "docstatus": result.docstatus, "name": result.name} - ) - else: - student.update({"assessment_details": None}) - return student_list - - -@frappe.whitelist() -def get_assessment_details(assessment_plan): - """Returns Assessment Criteria and Maximum Score from Assessment Plan Master. - - :param Assessment Plan: Assessment Plan - """ - return frappe.get_all( - "Assessment Plan Criteria", - fields=["assessment_criteria", "maximum_score", "docstatus"], - filters={"parent": assessment_plan}, - order_by="idx", - ) - - -@frappe.whitelist() -def get_result(student, assessment_plan): - """Returns Submitted Result of given student for specified Assessment Plan - - :param Student: Student - :param Assessment Plan: Assessment Plan - """ - results = frappe.get_all( - "Assessment Result", - filters={"student": student, "assessment_plan": assessment_plan, "docstatus": ("!=", 2)}, - ) - if results: - return frappe.get_doc("Assessment Result", results[0]) - else: - return None - - -@frappe.whitelist() -def get_grade(grading_scale, percentage): - """Returns Grade based on the Grading Scale and Score. - - :param Grading Scale: Grading Scale - :param Percentage: Score Percentage Percentage - """ - grading_scale_intervals = {} - if not hasattr(frappe.local, "grading_scale"): - grading_scale = frappe.get_all( - "Grading Scale Interval", fields=["grade_code", "threshold"], filters={"parent": grading_scale} - ) - frappe.local.grading_scale = grading_scale - for d in frappe.local.grading_scale: - grading_scale_intervals.update({d.threshold: d.grade_code}) - intervals = sorted(grading_scale_intervals.keys(), key=float, reverse=True) - for interval in intervals: - if flt(percentage) >= interval: - grade = grading_scale_intervals.get(interval) - break - else: - grade = "" - return grade - - -@frappe.whitelist() -def mark_assessment_result(assessment_plan, scores): - student_score = json.loads(scores) - assessment_details = [] - for criteria in student_score.get("assessment_details"): - assessment_details.append( - {"assessment_criteria": criteria, "score": flt(student_score["assessment_details"][criteria])} - ) - assessment_result = get_assessment_result_doc(student_score["student"], assessment_plan) - assessment_result.update( - { - "student": student_score.get("student"), - "assessment_plan": assessment_plan, - "comment": student_score.get("comment"), - "total_score": student_score.get("total_score"), - "details": assessment_details, - } - ) - assessment_result.save() - details = {} - for d in assessment_result.details: - details.update({d.assessment_criteria: d.grade}) - assessment_result_dict = { - "name": assessment_result.name, - "student": assessment_result.student, - "total_score": assessment_result.total_score, - "grade": assessment_result.grade, - "details": details, - } - return assessment_result_dict - - -@frappe.whitelist() -def submit_assessment_results(assessment_plan, student_group): - total_result = 0 - student_list = get_student_group_students(student_group) - for i, student in enumerate(student_list): - doc = get_result(student.student, assessment_plan) - if doc and doc.docstatus == 0: - total_result += 1 - doc.submit() - return total_result - - -def get_assessment_result_doc(student, assessment_plan): - assessment_result = frappe.get_all( - "Assessment Result", - filters={"student": student, "assessment_plan": assessment_plan, "docstatus": ("!=", 2)}, - ) - if assessment_result: - doc = frappe.get_doc("Assessment Result", assessment_result[0]) - if doc.docstatus == 0: - return doc - elif doc.docstatus == 1: - frappe.msgprint(_("Result already Submitted")) - return None - else: - return frappe.new_doc("Assessment Result") - - -@frappe.whitelist() -def update_email_group(doctype, name): - if not frappe.db.exists("Email Group", name): - email_group = frappe.new_doc("Email Group") - email_group.title = name - email_group.save() - email_list = [] - students = [] - if doctype == "Student Group": - students = get_student_group_students(name) - for stud in students: - for guard in get_student_guardians(stud.student): - email = frappe.db.get_value("Guardian", guard.guardian, "email_address") - if email: - email_list.append(email) - add_subscribers(name, email_list) - - -@frappe.whitelist() -def get_current_enrollment(student, academic_year=None): - current_academic_year = academic_year or frappe.defaults.get_defaults().academic_year - program_enrollment_list = frappe.db.sql( - """ - select - name as program_enrollment, student_name, program, student_batch_name as student_batch, - student_category, academic_term, academic_year - from - `tabProgram Enrollment` - where - student = %s and academic_year = %s - order by creation""", - (student, current_academic_year), - as_dict=1, - ) - - if program_enrollment_list: - return program_enrollment_list[0] - else: - return None diff --git a/erpnext/education/dashboard_chart/course_wise_enrollment/course_wise_enrollment.json b/erpnext/education/dashboard_chart/course_wise_enrollment/course_wise_enrollment.json deleted file mode 100644 index 9c5f784648..0000000000 --- a/erpnext/education/dashboard_chart/course_wise_enrollment/course_wise_enrollment.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "based_on": "", - "chart_name": "Course wise Enrollment", - "chart_type": "Group By", - "creation": "2020-07-23 18:24:38.214220", - "docstatus": 0, - "doctype": "Dashboard Chart", - "document_type": "Course Enrollment", - "dynamic_filters_json": "[]", - "filters_json": "[[\"Course Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false]]", - "group_by_based_on": "course", - "group_by_type": "Count", - "idx": 0, - "is_public": 1, - "is_standard": 1, - "last_synced_on": "2020-07-27 17:50:32.490587", - "modified": "2020-07-27 17:54:09.829206", - "modified_by": "Administrator", - "module": "Education", - "name": "Course wise Enrollment", - "number_of_groups": 0, - "owner": "Administrator", - "source": "", - "time_interval": "Yearly", - "timeseries": 0, - "timespan": "Last Year", - "type": "Percentage", - "use_report_chart": 0, - "value_based_on": "", - "y_axis": [] -} \ No newline at end of file diff --git a/erpnext/education/dashboard_chart/course_wise_student_count/course_wise_student_count.json b/erpnext/education/dashboard_chart/course_wise_student_count/course_wise_student_count.json deleted file mode 100644 index 5441518def..0000000000 --- a/erpnext/education/dashboard_chart/course_wise_student_count/course_wise_student_count.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "based_on": "", - "chart_name": "Course wise Student Count", - "chart_type": "Group By", - "creation": "2020-07-27 17:24:39.136163", - "docstatus": 0, - "doctype": "Dashboard Chart", - "document_type": "Course Enrollment", - "dynamic_filters_json": "[]", - "filters_json": "[[\"Course Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false]]", - "group_by_based_on": "course", - "group_by_type": "Count", - "idx": 0, - "is_public": 1, - "is_standard": 1, - "last_synced_on": "2020-07-27 17:24:56.184236", - "modified": "2020-07-27 17:25:46.232846", - "modified_by": "Administrator", - "module": "Education", - "name": "Course wise Student Count", - "number_of_groups": 0, - "owner": "Administrator", - "source": "", - "time_interval": "Yearly", - "timeseries": 0, - "timespan": "Last Year", - "type": "Donut", - "use_report_chart": 0, - "value_based_on": "", - "y_axis": [] -} \ No newline at end of file diff --git a/erpnext/education/dashboard_chart/instructor_gender_diversity_ratio/instructor_gender_diversity_ratio.json b/erpnext/education/dashboard_chart/instructor_gender_diversity_ratio/instructor_gender_diversity_ratio.json deleted file mode 100644 index b7ee509b92..0000000000 --- a/erpnext/education/dashboard_chart/instructor_gender_diversity_ratio/instructor_gender_diversity_ratio.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "based_on": "", - "chart_name": "Instructor Gender Diversity Ratio", - "chart_type": "Group By", - "creation": "2020-07-23 18:35:02.544019", - "docstatus": 0, - "doctype": "Dashboard Chart", - "document_type": "Instructor", - "dynamic_filters_json": "[]", - "filters_json": "[[\"Instructor\",\"status\",\"=\",\"Active\",false]]", - "group_by_based_on": "gender", - "group_by_type": "Count", - "idx": 0, - "is_public": 1, - "is_standard": 1, - "last_synced_on": "2020-07-27 17:50:32.783820", - "modified": "2020-07-27 17:55:41.595260", - "modified_by": "Administrator", - "module": "Education", - "name": "Instructor Gender Diversity Ratio", - "number_of_groups": 0, - "owner": "Administrator", - "source": "", - "time_interval": "Yearly", - "timeseries": 0, - "timespan": "Last Year", - "type": "Donut", - "use_report_chart": 0, - "value_based_on": "", - "y_axis": [] -} \ No newline at end of file diff --git a/erpnext/education/dashboard_chart/program_enrollments/program_enrollments.json b/erpnext/education/dashboard_chart/program_enrollments/program_enrollments.json deleted file mode 100644 index 2a4a4a3e0c..0000000000 --- a/erpnext/education/dashboard_chart/program_enrollments/program_enrollments.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "based_on": "enrollment_date", - "chart_name": "Program Enrollments", - "chart_type": "Count", - "creation": "2020-07-23 18:27:53.641616", - "docstatus": 0, - "doctype": "Dashboard Chart", - "document_type": "Program Enrollment", - "dynamic_filters_json": "[]", - "filters_json": "[[\"Program Enrollment\",\"docstatus\",\"=\",\"1\",false]]", - "group_by_type": "Count", - "idx": 0, - "is_public": 1, - "is_standard": 1, - "last_synced_on": "2020-07-27 17:50:32.203069", - "modified": "2020-07-27 17:51:59.022909", - "modified_by": "Administrator", - "module": "Education", - "name": "Program Enrollments", - "number_of_groups": 0, - "owner": "Administrator", - "source": "", - "time_interval": "Daily", - "timeseries": 1, - "timespan": "Last Month", - "type": "Line", - "use_report_chart": 0, - "value_based_on": "", - "y_axis": [] -} \ No newline at end of file diff --git a/erpnext/education/dashboard_chart/program_wise_enrollment/program_wise_enrollment.json b/erpnext/education/dashboard_chart/program_wise_enrollment/program_wise_enrollment.json deleted file mode 100644 index 2ba138e332..0000000000 --- a/erpnext/education/dashboard_chart/program_wise_enrollment/program_wise_enrollment.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "based_on": "", - "chart_name": "Program wise Enrollment", - "chart_type": "Group By", - "creation": "2020-07-23 18:23:45.192748", - "docstatus": 0, - "doctype": "Dashboard Chart", - "document_type": "Program Enrollment", - "dynamic_filters_json": "[]", - "filters_json": "[[\"Program Enrollment\",\"docstatus\",\"=\",\"1\",false],[\"Program Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false]]", - "group_by_based_on": "program", - "group_by_type": "Count", - "idx": 0, - "is_public": 1, - "is_standard": 1, - "last_synced_on": "2020-07-27 17:50:32.629321", - "modified": "2020-07-27 17:53:36.269098", - "modified_by": "Administrator", - "module": "Education", - "name": "Program wise Enrollment", - "number_of_groups": 0, - "owner": "Administrator", - "source": "", - "time_interval": "Yearly", - "timeseries": 0, - "timespan": "Last Year", - "type": "Percentage", - "use_report_chart": 0, - "value_based_on": "", - "y_axis": [] -} \ No newline at end of file diff --git a/erpnext/education/dashboard_chart/program_wise_fee_collection/program_wise_fee_collection.json b/erpnext/education/dashboard_chart/program_wise_fee_collection/program_wise_fee_collection.json deleted file mode 100644 index 38c1b6d7f3..0000000000 --- a/erpnext/education/dashboard_chart/program_wise_fee_collection/program_wise_fee_collection.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "chart_name": "Program wise Fee Collection", - "chart_type": "Report", - "creation": "2020-08-05 16:19:53.398335", - "custom_options": "", - "docstatus": 0, - "doctype": "Dashboard Chart", - "dynamic_filters_json": "{\"from_date\":\"frappe.datetime.add_months(frappe.datetime.get_today(), -1)\",\"to_date\":\"frappe.datetime.nowdate()\"}", - "filters_json": "{}", - "group_by_type": "Count", - "idx": 0, - "is_public": 1, - "is_standard": 1, - "modified": "2020-08-05 16:20:47.436847", - "modified_by": "Administrator", - "module": "Education", - "name": "Program wise Fee Collection", - "number_of_groups": 0, - "owner": "Administrator", - "report_name": "Program wise Fee Collection", - "time_interval": "Yearly", - "timeseries": 0, - "timespan": "Last Year", - "type": "Bar", - "use_report_chart": 1, - "x_field": "", - "y_axis": [] -} \ No newline at end of file diff --git a/erpnext/education/dashboard_chart/student_category_wise_program_enrollments/student_category_wise_program_enrollments.json b/erpnext/education/dashboard_chart/student_category_wise_program_enrollments/student_category_wise_program_enrollments.json deleted file mode 100644 index 88871457ec..0000000000 --- a/erpnext/education/dashboard_chart/student_category_wise_program_enrollments/student_category_wise_program_enrollments.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "based_on": "", - "chart_name": "Student Category wise Program Enrollments", - "chart_type": "Group By", - "creation": "2020-07-27 17:37:47.116446", - "docstatus": 0, - "doctype": "Dashboard Chart", - "document_type": "Program Enrollment", - "dynamic_filters_json": "[]", - "filters_json": "[[\"Program Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false],[\"Program Enrollment\",\"docstatus\",\"=\",\"1\",false]]", - "group_by_based_on": "student_category", - "group_by_type": "Count", - "idx": 0, - "is_public": 1, - "is_standard": 1, - "last_synced_on": "2020-07-27 17:46:54.901911", - "modified": "2020-07-27 17:47:21.370866", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Category wise Program Enrollments", - "number_of_groups": 0, - "owner": "Administrator", - "source": "", - "time_interval": "Yearly", - "timeseries": 0, - "timespan": "Last Year", - "type": "Donut", - "use_report_chart": 0, - "value_based_on": "", - "y_axis": [] -} \ No newline at end of file diff --git a/erpnext/education/dashboard_chart/student_gender_diversity_ratio/student_gender_diversity_ratio.json b/erpnext/education/dashboard_chart/student_gender_diversity_ratio/student_gender_diversity_ratio.json deleted file mode 100644 index ce602d29ee..0000000000 --- a/erpnext/education/dashboard_chart/student_gender_diversity_ratio/student_gender_diversity_ratio.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "based_on": "", - "chart_name": "Student Gender Diversity Ratio", - "chart_type": "Group By", - "creation": "2020-07-23 18:12:15.972123", - "docstatus": 0, - "doctype": "Dashboard Chart", - "document_type": "Student", - "dynamic_filters_json": "[]", - "filters_json": "[[\"Student\",\"enabled\",\"=\",1,false]]", - "group_by_based_on": "gender", - "group_by_type": "Count", - "idx": 0, - "is_public": 1, - "is_standard": 1, - "modified": "2020-07-23 18:12:21.606772", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Gender Diversity Ratio", - "number_of_groups": 0, - "owner": "Administrator", - "source": "", - "time_interval": "Yearly", - "timeseries": 0, - "timespan": "Last Year", - "type": "Donut", - "use_report_chart": 0, - "value_based_on": "", - "y_axis": [] -} \ No newline at end of file diff --git a/erpnext/education/doctype/__init__.py b/erpnext/education/doctype/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/academic_term/__init__.py b/erpnext/education/doctype/academic_term/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/academic_term/academic_term.js b/erpnext/education/doctype/academic_term/academic_term.js deleted file mode 100644 index 26d66f0b2b..0000000000 --- a/erpnext/education/doctype/academic_term/academic_term.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Academic Term', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/academic_term/academic_term.json b/erpnext/education/doctype/academic_term/academic_term.json deleted file mode 100644 index 06c5b1acfc..0000000000 --- a/erpnext/education/doctype/academic_term/academic_term.json +++ /dev/null @@ -1,216 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:title", - "beta": 0, - "creation": "2015-09-08 17:19:19.158228", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 0, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "academic_year", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 1, - "label": "Academic Year", - "length": 0, - "no_copy": 0, - "options": "Academic Year", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "term_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Term Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "term_start_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Term Start Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "term_end_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Term End Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "title", - "fieldtype": "Data", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Title", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2017-11-10 19:05:58.567627", - "modified_by": "Administrator", - "module": "Education", - "name": "Academic Term", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "name", - "sort_order": "DESC", - "title_field": "title", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/academic_term/academic_term.py b/erpnext/education/doctype/academic_term/academic_term.py deleted file mode 100644 index b44fe99a30..0000000000 --- a/erpnext/education/doctype/academic_term/academic_term.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.utils import getdate - - -class AcademicTerm(Document): - def autoname(self): - self.name = self.academic_year + " ({})".format(self.term_name) if self.term_name else "" - - def validate(self): - # Check if entry with same academic_year and the term_name already exists - validate_duplication(self) - self.title = self.academic_year + " ({})".format(self.term_name) if self.term_name else "" - - # Check that start of academic year is earlier than end of academic year - if ( - self.term_start_date - and self.term_end_date - and getdate(self.term_start_date) > getdate(self.term_end_date) - ): - frappe.throw( - _( - "The Term End Date cannot be earlier than the Term Start Date. Please correct the dates and try again." - ) - ) - - # Check that the start of the term is not before the start of the academic year - # and end of term is not after the end of the academic year""" - - year = frappe.get_doc("Academic Year", self.academic_year) - if ( - self.term_start_date - and getdate(year.year_start_date) - and (getdate(self.term_start_date) < getdate(year.year_start_date)) - ): - frappe.throw( - _( - "The Term Start Date cannot be earlier than the Year Start Date of the Academic Year to which the term is linked (Academic Year {}). Please correct the dates and try again." - ).format(self.academic_year) - ) - - if ( - self.term_end_date - and getdate(year.year_end_date) - and (getdate(self.term_end_date) > getdate(year.year_end_date)) - ): - frappe.throw( - _( - "The Term End Date cannot be later than the Year End Date of the Academic Year to which the term is linked (Academic Year {}). Please correct the dates and try again." - ).format(self.academic_year) - ) - - -def validate_duplication(self): - term = frappe.db.sql( - """select name from `tabAcademic Term` where academic_year= %s and term_name= %s - and docstatus<2 and name != %s""", - (self.academic_year, self.term_name, self.name), - ) - if term: - frappe.throw( - _( - "An academic term with this 'Academic Year' {0} and 'Term Name' {1} already exists. Please modify these entries and try again." - ).format(self.academic_year, self.term_name) - ) diff --git a/erpnext/education/doctype/academic_term/academic_term_dashboard.py b/erpnext/education/doctype/academic_term/academic_term_dashboard.py deleted file mode 100644 index 348c04d3f6..0000000000 --- a/erpnext/education/doctype/academic_term/academic_term_dashboard.py +++ /dev/null @@ -1,13 +0,0 @@ -from frappe import _ - - -def get_data(): - return { - "fieldname": "academic_term", - "transactions": [ - {"label": _("Student"), "items": ["Student Applicant", "Student Group", "Student Log"]}, - {"label": _("Fee"), "items": ["Fees", "Fee Schedule", "Fee Structure"]}, - {"label": _("Program"), "items": ["Program Enrollment"]}, - {"label": _("Assessment"), "items": ["Assessment Plan", "Assessment Result"]}, - ], - } diff --git a/erpnext/education/doctype/academic_term/test_academic_term.py b/erpnext/education/doctype/academic_term/test_academic_term.py deleted file mode 100644 index b4516b3a42..0000000000 --- a/erpnext/education/doctype/academic_term/test_academic_term.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Academic Term') - - -class TestAcademicTerm(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/academic_term/test_records.json b/erpnext/education/doctype/academic_term/test_records.json deleted file mode 100644 index 6bd365561f..0000000000 --- a/erpnext/education/doctype/academic_term/test_records.json +++ /dev/null @@ -1,27 +0,0 @@ -[ - { - "doctype": "Academic Term", - "academic_year": "2014-2015", - "term_name": "_Test Academic Term" - }, - { - "doctype": "Academic Term", - "academic_year": "2014-2015", - "term_name": "_Test Academic Term 1" - }, - { - "doctype": "Academic Term", - "academic_year": "2014-2015", - "term_name": "_Test Academic Term 2" - }, - { - "doctype": "Academic Term", - "academic_year": "2017-2018", - "term_name": "_Test AT1" - }, - { - "doctype": "Academic Term", - "academic_year": "2017-2018", - "term_name": "_Test AT2" - } -] \ No newline at end of file diff --git a/erpnext/education/doctype/academic_year/__init__.py b/erpnext/education/doctype/academic_year/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/academic_year/academic_year.js b/erpnext/education/doctype/academic_year/academic_year.js deleted file mode 100644 index 20e25281ff..0000000000 --- a/erpnext/education/doctype/academic_year/academic_year.js +++ /dev/null @@ -1,2 +0,0 @@ -frappe.ui.form.on("Academic Year", { -}); diff --git a/erpnext/education/doctype/academic_year/academic_year.json b/erpnext/education/doctype/academic_year/academic_year.json deleted file mode 100644 index 5df89a7682..0000000000 --- a/erpnext/education/doctype/academic_year/academic_year.json +++ /dev/null @@ -1,154 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 0, - "autoname": "field:academic_year_name", - "beta": 0, - "creation": "2015-09-07 12:49:51.303026", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 0, - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "academic_year_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Academic Year Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "year_start_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Year Start Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "year_end_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Year End Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2017-11-10 19:06:08.123090", - "modified_by": "Administrator", - "module": "Education", - "name": "Academic Year", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/academic_year/academic_year.py b/erpnext/education/doctype/academic_year/academic_year.py deleted file mode 100644 index 2a0438b775..0000000000 --- a/erpnext/education/doctype/academic_year/academic_year.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document - - -class AcademicYear(Document): - def validate(self): - # Check that start of academic year is earlier than end of academic year - if self.year_start_date and self.year_end_date and self.year_start_date > self.year_end_date: - frappe.throw( - _( - "The Year End Date cannot be earlier than the Year Start Date. Please correct the dates and try again." - ) - ) diff --git a/erpnext/education/doctype/academic_year/academic_year_dashboard.py b/erpnext/education/doctype/academic_year/academic_year_dashboard.py deleted file mode 100644 index c69c97017a..0000000000 --- a/erpnext/education/doctype/academic_year/academic_year_dashboard.py +++ /dev/null @@ -1,16 +0,0 @@ -from frappe import _ - - -def get_data(): - return { - "fieldname": "academic_year", - "transactions": [ - { - "label": _("Student"), - "items": ["Student Admission", "Student Applicant", "Student Group", "Student Log"], - }, - {"label": _("Fee"), "items": ["Fees", "Fee Schedule", "Fee Structure"]}, - {"label": _("Academic Term and Program"), "items": ["Academic Term", "Program Enrollment"]}, - {"label": _("Assessment"), "items": ["Assessment Plan", "Assessment Result"]}, - ], - } diff --git a/erpnext/education/doctype/academic_year/test_academic_year.py b/erpnext/education/doctype/academic_year/test_academic_year.py deleted file mode 100644 index e51cd0e235..0000000000 --- a/erpnext/education/doctype/academic_year/test_academic_year.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Academic Year') - - -class TestAcademicYear(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/academic_year/test_records.json b/erpnext/education/doctype/academic_year/test_records.json deleted file mode 100644 index 5eb5e2e360..0000000000 --- a/erpnext/education/doctype/academic_year/test_records.json +++ /dev/null @@ -1,18 +0,0 @@ -[ - { - "doctype": "Academic Year", - "academic_year_name": "2014-2015" - }, - { - "doctype": "Academic Year", - "academic_year_name": "2015-2016" - }, - { - "doctype": "Academic Year", - "academic_year_name": "2016-2017" - }, - { - "doctype": "Academic Year", - "academic_year_name": "2017-2018" - } -] \ No newline at end of file diff --git a/erpnext/education/doctype/article/__init__.py b/erpnext/education/doctype/article/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/article/article.js b/erpnext/education/doctype/article/article.js deleted file mode 100644 index 85b387f621..0000000000 --- a/erpnext/education/doctype/article/article.js +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Article', { - refresh: function(frm) { - if (!frm.doc.__islocal) { - frm.add_custom_button(__('Add to Topics'), function() { - frm.trigger('add_article_to_topics'); - }, __('Action')); - } - }, - - add_article_to_topics: function(frm) { - get_topics_without_article(frm.doc.name).then(r => { - if (r.message.length) { - frappe.prompt([ - { - fieldname: 'topics', - label: __('Topics'), - fieldtype: 'MultiSelectPills', - get_data: function() { - return r.message; - } - } - ], - function(data) { - frappe.call({ - method: 'erpnext.education.doctype.topic.topic.add_content_to_topics', - args: { - 'content_type': 'Article', - 'content': frm.doc.name, - 'topics': data.topics, - }, - callback: function(r) { - if (!r.exc) { - frm.reload_doc(); - } - }, - freeze: true, - freeze_message: __('...Adding Article to Topics') - }); - }, __('Add Article to Topics'), __('Add')); - } else { - frappe.msgprint(__('This article is already added to the existing topics')); - } - }); - } -}); - -let get_topics_without_article = function(article) { - return frappe.call({ - type: 'GET', - method: 'erpnext.education.doctype.article.article.get_topics_without_article', - args: {'article': article} - }); -}; diff --git a/erpnext/education/doctype/article/article.json b/erpnext/education/doctype/article/article.json deleted file mode 100644 index 2fad5af8d3..0000000000 --- a/erpnext/education/doctype/article/article.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:title", - "creation": "2018-10-17 05:45:38.471670", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "title", - "author", - "content", - "publish_date" - ], - "fields": [ - { - "fieldname": "title", - "fieldtype": "Data", - "label": "Title", - "unique": 1 - }, - { - "fieldname": "author", - "fieldtype": "Data", - "label": "Author" - }, - { - "fieldname": "content", - "fieldtype": "Text Editor", - "label": "Content" - }, - { - "fieldname": "publish_date", - "fieldtype": "Date", - "label": "Publish Date" - } - ], - "modified": "2019-06-12 12:36:58.740340", - "modified_by": "Administrator", - "module": "Education", - "name": "Article", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "share": 1, - "write": 1 - }, - { - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "LMS User", - "share": 1 - } - ], - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/education/doctype/article/article.py b/erpnext/education/doctype/article/article.py deleted file mode 100644 index 12b6618e73..0000000000 --- a/erpnext/education/doctype/article/article.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe.model.document import Document - - -class Article(Document): - def get_article(self): - pass - - -@frappe.whitelist() -def get_topics_without_article(article): - data = [] - for entry in frappe.db.get_all("Topic"): - topic = frappe.get_doc("Topic", entry.name) - topic_contents = [tc.content for tc in topic.topic_content] - if not topic_contents or article not in topic_contents: - data.append(topic.name) - return data diff --git a/erpnext/education/doctype/article/test_article.py b/erpnext/education/doctype/article/test_article.py deleted file mode 100644 index 2ea5c82a8b..0000000000 --- a/erpnext/education/doctype/article/test_article.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestArticle(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/assessment_criteria/__init__.py b/erpnext/education/doctype/assessment_criteria/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/assessment_criteria/assessment_criteria.js b/erpnext/education/doctype/assessment_criteria/assessment_criteria.js deleted file mode 100644 index 44b9ca3d23..0000000000 --- a/erpnext/education/doctype/assessment_criteria/assessment_criteria.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Assessment Criteria', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/assessment_criteria/assessment_criteria.json b/erpnext/education/doctype/assessment_criteria/assessment_criteria.json deleted file mode 100644 index 9e228fd368..0000000000 --- a/erpnext/education/doctype/assessment_criteria/assessment_criteria.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 0, - "autoname": "field:assessment_criteria", - "beta": 0, - "creation": "2016-12-14 16:40:15.144115", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "assessment_criteria", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Assessment Criteria", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 1, - "collapsible": 0, - "columns": 0, - "fieldname": "assessment_criteria_group", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Assessment Criteria Group", - "length": 0, - "no_copy": 0, - "options": "Assessment Criteria Group", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2017-11-10 19:08:11.311304", - "modified_by": "Administrator", - "module": "Education", - "name": "Assessment Criteria", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/assessment_criteria/assessment_criteria.py b/erpnext/education/doctype/assessment_criteria/assessment_criteria.py deleted file mode 100644 index ef9692a8eb..0000000000 --- a/erpnext/education/doctype/assessment_criteria/assessment_criteria.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document - -STD_CRITERIA = ["total", "total score", "total grade", "maximum score", "score", "grade"] - - -class AssessmentCriteria(Document): - def validate(self): - if self.assessment_criteria.lower() in STD_CRITERIA: - frappe.throw(_("Can't create standard criteria. Please rename the criteria")) diff --git a/erpnext/education/doctype/assessment_criteria/test_assessment_criteria.py b/erpnext/education/doctype/assessment_criteria/test_assessment_criteria.py deleted file mode 100644 index 90ff575445..0000000000 --- a/erpnext/education/doctype/assessment_criteria/test_assessment_criteria.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Assessment Criteria') - - -class TestAssessmentCriteria(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/assessment_criteria/test_records.json b/erpnext/education/doctype/assessment_criteria/test_records.json deleted file mode 100644 index 7af63b39f7..0000000000 --- a/erpnext/education/doctype/assessment_criteria/test_records.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "assessment_criteria": "_Test Assessment Criteria" - }, - { - "assessment_criteria": "_Test Assessment Criteria 1" - } -] \ No newline at end of file diff --git a/erpnext/education/doctype/assessment_criteria_group/__init__.py b/erpnext/education/doctype/assessment_criteria_group/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/assessment_criteria_group/assessment_criteria_group.js b/erpnext/education/doctype/assessment_criteria_group/assessment_criteria_group.js deleted file mode 100644 index 89358d210f..0000000000 --- a/erpnext/education/doctype/assessment_criteria_group/assessment_criteria_group.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Assessment Criteria Group', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/assessment_criteria_group/assessment_criteria_group.json b/erpnext/education/doctype/assessment_criteria_group/assessment_criteria_group.json deleted file mode 100644 index 5765b4b3f7..0000000000 --- a/erpnext/education/doctype/assessment_criteria_group/assessment_criteria_group.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:assessment_criteria_group", - "beta": 0, - "creation": "2017-01-27 15:17:38.855910", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "assessment_criteria_group", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Assessment Criteria Group", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2017-11-10 19:11:45.334917", - "modified_by": "Administrator", - "module": "Education", - "name": "Assessment Criteria Group", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/assessment_criteria_group/assessment_criteria_group.py b/erpnext/education/doctype/assessment_criteria_group/assessment_criteria_group.py deleted file mode 100644 index d284db595c..0000000000 --- a/erpnext/education/doctype/assessment_criteria_group/assessment_criteria_group.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class AssessmentCriteriaGroup(Document): - pass diff --git a/erpnext/education/doctype/assessment_criteria_group/test_assessment_criteria_group.py b/erpnext/education/doctype/assessment_criteria_group/test_assessment_criteria_group.py deleted file mode 100644 index b52aef8381..0000000000 --- a/erpnext/education/doctype/assessment_criteria_group/test_assessment_criteria_group.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Assessment Criteria Group') - - -class TestAssessmentCriteriaGroup(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/assessment_group/__init__.py b/erpnext/education/doctype/assessment_group/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/assessment_group/assessment_group.js b/erpnext/education/doctype/assessment_group/assessment_group.js deleted file mode 100644 index 6be51023ab..0000000000 --- a/erpnext/education/doctype/assessment_group/assessment_group.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Assessment Group', { - onload: function(frm) { - frm.list_route = "Tree/Assessment Group"; - } -}); diff --git a/erpnext/education/doctype/assessment_group/assessment_group.json b/erpnext/education/doctype/assessment_group/assessment_group.json deleted file mode 100644 index a8ffaf43f0..0000000000 --- a/erpnext/education/doctype/assessment_group/assessment_group.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "actions": [], - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:assessment_group_name", - "creation": "2016-08-04 04:42:48.319388", - "doctype": "DocType", - "editable_grid": 1, - "field_order": [ - "assessment_group_name", - "is_group", - "section_break_2", - "parent_assessment_group", - "lft", - "rgt", - "old_parent" - ], - "fields": [ - { - "fieldname": "assessment_group_name", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Assessment Group Name", - "reqd": 1, - "unique": 1 - }, - { - "default": "0", - "fieldname": "is_group", - "fieldtype": "Check", - "label": "Is Group" - }, - { - "fieldname": "section_break_2", - "fieldtype": "Section Break", - "hidden": 1 - }, - { - "fieldname": "parent_assessment_group", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Parent Assessment Group", - "options": "Assessment Group", - "reqd": 1 - }, - { - "fieldname": "lft", - "fieldtype": "Int", - "label": "lft" - }, - { - "fieldname": "rgt", - "fieldtype": "Int", - "label": "rgt" - }, - { - "fieldname": "old_parent", - "fieldtype": "Link", - "ignore_user_permissions": 1, - "label": "old_parent", - "options": "Assessment Group" - } - ], - "is_tree": 1, - "links": [], - "modified": "2020-03-18 18:01:14.710416", - "modified_by": "Administrator", - "module": "Education", - "name": "Assessment Group", - "nsm_parent_field": "parent_assessment_group", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "write": 1 - } - ], - "quick_entry": 1, - "restrict_to_domain": "Education", - "sort_field": "modified", - "sort_order": "DESC" -} \ No newline at end of file diff --git a/erpnext/education/doctype/assessment_group/assessment_group.py b/erpnext/education/doctype/assessment_group/assessment_group.py deleted file mode 100644 index d606ffb41a..0000000000 --- a/erpnext/education/doctype/assessment_group/assessment_group.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class AssessmentGroup(Document): - pass diff --git a/erpnext/education/doctype/assessment_group/assessment_group_dashboard.py b/erpnext/education/doctype/assessment_group/assessment_group_dashboard.py deleted file mode 100644 index 7c75100b70..0000000000 --- a/erpnext/education/doctype/assessment_group/assessment_group_dashboard.py +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - -from frappe import _ - - -def get_data(): - return { - "fieldname": "assessment_group", - "transactions": [{"label": _("Assessment"), "items": ["Assessment Plan", "Assessment Result"]}], - } diff --git a/erpnext/education/doctype/assessment_group/assessment_group_tree.js b/erpnext/education/doctype/assessment_group/assessment_group_tree.js deleted file mode 100644 index e0dfaa31fd..0000000000 --- a/erpnext/education/doctype/assessment_group/assessment_group_tree.js +++ /dev/null @@ -1,3 +0,0 @@ -frappe.treeview_settings["Assessment Group"] = { - -} diff --git a/erpnext/education/doctype/assessment_group/test_assessment_group.py b/erpnext/education/doctype/assessment_group/test_assessment_group.py deleted file mode 100644 index 6f05caae94..0000000000 --- a/erpnext/education/doctype/assessment_group/test_assessment_group.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Assessment Group') - - -class TestAssessmentGroup(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/assessment_plan/__init__.py b/erpnext/education/doctype/assessment_plan/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/assessment_plan/assessment_plan.js b/erpnext/education/doctype/assessment_plan/assessment_plan.js deleted file mode 100644 index cf545c41af..0000000000 --- a/erpnext/education/doctype/assessment_plan/assessment_plan.js +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - - -frappe.ui.form.on('Assessment Plan', { - onload: function(frm) { - frm.set_query('assessment_group', function(doc, cdt, cdn) { - return{ - filters: { - 'is_group': 0 - } - }; - }); - frm.set_query('grading_scale', function(){ - return { - filters: { - docstatus: 1 - } - }; - }); - }, - - refresh: function(frm) { - if (frm.doc.docstatus == 1) { - frm.add_custom_button(__('Assessment Result Tool'), function() { - frappe.route_options = { - assessment_plan: frm.doc.name, - student_group: frm.doc.student_group - } - frappe.set_route('Form', 'Assessment Result Tool'); - }, __('Tools')); - } - - frm.set_query('course', function() { - return { - query: 'erpnext.education.doctype.program_enrollment.program_enrollment.get_program_courses', - filters: { - 'program': frm.doc.program - } - }; - }); - - frm.set_query('academic_term', function() { - return { - filters: { - 'academic_year': frm.doc.academic_year - } - }; - }); - }, - - course: function(frm) { - if (frm.doc.course && frm.doc.maximum_assessment_score) { - frappe.call({ - method: 'erpnext.education.api.get_assessment_criteria', - args: { - course: frm.doc.course - }, - callback: function(r) { - if (r.message) { - frm.doc.assessment_criteria = []; - $.each(r.message, function(i, d) { - var row = frappe.model.add_child(frm.doc, 'Assessment Plan Criteria', 'assessment_criteria'); - row.assessment_criteria = d.assessment_criteria; - row.maximum_score = d.weightage / 100 * frm.doc.maximum_assessment_score; - }); - } - refresh_field('assessment_criteria'); - - } - }); - } - }, - - maximum_assessment_score: function(frm) { - frm.trigger('course'); - } -}); diff --git a/erpnext/education/doctype/assessment_plan/assessment_plan.json b/erpnext/education/doctype/assessment_plan/assessment_plan.json deleted file mode 100644 index 5066fdf391..0000000000 --- a/erpnext/education/doctype/assessment_plan/assessment_plan.json +++ /dev/null @@ -1,227 +0,0 @@ -{ - "actions": [], - "allow_import": 1, - "autoname": "EDU-ASP-.YYYY.-.#####", - "creation": "2015-11-12 16:34:34.658092", - "doctype": "DocType", - "document_type": "Setup", - "engine": "InnoDB", - "field_order": [ - "student_group", - "assessment_name", - "assessment_group", - "grading_scale", - "column_break_2", - "program", - "course", - "academic_year", - "academic_term", - "section_break_5", - "schedule_date", - "room", - "examiner", - "examiner_name", - "column_break_4", - "from_time", - "to_time", - "supervisor", - "supervisor_name", - "section_break_20", - "maximum_assessment_score", - "assessment_criteria", - "amended_from" - ], - "fields": [ - { - "fieldname": "student_group", - "fieldtype": "Link", - "in_global_search": 1, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Student Group", - "options": "Student Group", - "reqd": 1 - }, - { - "fieldname": "assessment_name", - "fieldtype": "Data", - "in_global_search": 1, - "label": "Assessment Name" - }, - { - "fieldname": "assessment_group", - "fieldtype": "Link", - "in_standard_filter": 1, - "label": "Assessment Group", - "options": "Assessment Group", - "reqd": 1 - }, - { - "fetch_from": "course.default_grading_scale", - "fetch_if_empty": 1, - "fieldname": "grading_scale", - "fieldtype": "Link", - "in_standard_filter": 1, - "label": "Grading Scale", - "options": "Grading Scale", - "reqd": 1 - }, - { - "fieldname": "column_break_2", - "fieldtype": "Column Break" - }, - { - "fetch_from": "student_group.course", - "fetch_if_empty": 1, - "fieldname": "course", - "fieldtype": "Link", - "in_global_search": 1, - "in_standard_filter": 1, - "label": "Course", - "options": "Course", - "reqd": 1 - }, - { - "fetch_from": "student_group.program", - "fieldname": "program", - "fieldtype": "Link", - "in_global_search": 1, - "label": "Program", - "options": "Program" - }, - { - "fetch_from": "student_group.academic_year", - "fieldname": "academic_year", - "fieldtype": "Link", - "label": "Academic Year", - "options": "Academic Year" - }, - { - "fetch_from": "student_group.academic_term", - "fieldname": "academic_term", - "fieldtype": "Link", - "label": "Academic Term", - "options": "Academic Term" - }, - { - "fieldname": "section_break_5", - "fieldtype": "Section Break", - "label": "Schedule" - }, - { - "default": "Today", - "fieldname": "schedule_date", - "fieldtype": "Date", - "in_list_view": 1, - "label": "Schedule Date", - "no_copy": 1, - "reqd": 1 - }, - { - "fieldname": "room", - "fieldtype": "Link", - "label": "Room", - "options": "Room" - }, - { - "fieldname": "examiner", - "fieldtype": "Link", - "label": "Examiner", - "options": "Instructor" - }, - { - "fetch_from": "examiner.instructor_name", - "fieldname": "examiner_name", - "fieldtype": "Data", - "label": "Examiner Name", - "read_only": 1 - }, - { - "fieldname": "column_break_4", - "fieldtype": "Column Break" - }, - { - "fieldname": "from_time", - "fieldtype": "Time", - "label": "From Time", - "no_copy": 1, - "reqd": 1 - }, - { - "fieldname": "to_time", - "fieldtype": "Time", - "label": "To Time", - "no_copy": 1, - "reqd": 1 - }, - { - "fieldname": "supervisor", - "fieldtype": "Link", - "label": "Supervisor", - "options": "Instructor" - }, - { - "fetch_from": "supervisor.instructor_name", - "fieldname": "supervisor_name", - "fieldtype": "Data", - "in_global_search": 1, - "label": "Supervisor Name", - "read_only": 1 - }, - { - "fieldname": "section_break_20", - "fieldtype": "Section Break", - "label": "Evaluate" - }, - { - "fieldname": "maximum_assessment_score", - "fieldtype": "Float", - "label": "Maximum Assessment Score", - "reqd": 1 - }, - { - "fieldname": "assessment_criteria", - "fieldtype": "Table", - "label": "Assessment Criteria", - "options": "Assessment Plan Criteria", - "reqd": 1 - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Assessment Plan", - "print_hide": 1, - "read_only": 1 - } - ], - "is_submittable": 1, - "links": [], - "modified": "2020-10-23 15:55:35.076251", - "modified_by": "Administrator", - "module": "Education", - "name": "Assessment Plan", - "owner": "Administrator", - "permissions": [ - { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "submit": 1, - "write": 1 - } - ], - "restrict_to_domain": "Education", - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "assessment_name" -} \ No newline at end of file diff --git a/erpnext/education/doctype/assessment_plan/assessment_plan.py b/erpnext/education/doctype/assessment_plan/assessment_plan.py deleted file mode 100644 index e1265b4208..0000000000 --- a/erpnext/education/doctype/assessment_plan/assessment_plan.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document - - -class AssessmentPlan(Document): - def validate(self): - self.validate_overlap() - self.validate_max_score() - self.validate_assessment_criteria() - - def validate_overlap(self): - """Validates overlap for Student Group, Instructor, Room""" - - from erpnext.education.utils import validate_overlap_for - - # Validate overlapping course schedules. - if self.student_group: - validate_overlap_for(self, "Course Schedule", "student_group") - - validate_overlap_for(self, "Course Schedule", "instructor") - validate_overlap_for(self, "Course Schedule", "room") - - # validate overlapping assessment schedules. - if self.student_group: - validate_overlap_for(self, "Assessment Plan", "student_group") - - validate_overlap_for(self, "Assessment Plan", "room") - validate_overlap_for(self, "Assessment Plan", "supervisor", self.supervisor) - - def validate_max_score(self): - max_score = 0 - for d in self.assessment_criteria: - max_score += d.maximum_score - if self.maximum_assessment_score != max_score: - frappe.throw( - _("Sum of Scores of Assessment Criteria needs to be {0}.").format( - self.maximum_assessment_score - ) - ) - - def validate_assessment_criteria(self): - assessment_criteria_list = frappe.db.sql_list( - """ select apc.assessment_criteria - from `tabAssessment Plan` ap , `tabAssessment Plan Criteria` apc - where ap.name = apc.parent and ap.course=%s and ap.student_group=%s and ap.assessment_group=%s - and ap.name != %s and ap.docstatus=1""", - (self.course, self.student_group, self.assessment_group, self.name), - ) - for d in self.assessment_criteria: - if d.assessment_criteria in assessment_criteria_list: - frappe.throw( - _("You have already assessed for the assessment criteria {}.").format( - frappe.bold(d.assessment_criteria) - ) - ) diff --git a/erpnext/education/doctype/assessment_plan/assessment_plan_dashboard.py b/erpnext/education/doctype/assessment_plan/assessment_plan_dashboard.py deleted file mode 100644 index f9c583a80f..0000000000 --- a/erpnext/education/doctype/assessment_plan/assessment_plan_dashboard.py +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - -from frappe import _ - - -def get_data(): - return { - "fieldname": "assessment_plan", - "transactions": [{"label": _("Assessment"), "items": ["Assessment Result"]}], - "reports": [{"label": _("Report"), "items": ["Assessment Plan Status"]}], - } diff --git a/erpnext/education/doctype/assessment_plan/test_assessment_plan.py b/erpnext/education/doctype/assessment_plan/test_assessment_plan.py deleted file mode 100644 index e294c50ce4..0000000000 --- a/erpnext/education/doctype/assessment_plan/test_assessment_plan.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Assessment Plan') - - -class TestAssessmentPlan(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/assessment_plan_criteria/__init__.py b/erpnext/education/doctype/assessment_plan_criteria/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/assessment_plan_criteria/assessment_plan_criteria.json b/erpnext/education/doctype/assessment_plan_criteria/assessment_plan_criteria.json deleted file mode 100644 index d9ad0cb952..0000000000 --- a/erpnext/education/doctype/assessment_plan_criteria/assessment_plan_criteria.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "", - "beta": 0, - "creation": "2016-12-14 17:20:27.738226", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "assessment_criteria", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Assessment Criteria", - "length": 0, - "no_copy": 0, - "options": "Assessment Criteria", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_2", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "maximum_score", - "fieldtype": "Float", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Maximum Score", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2017-11-10 19:10:50.560006", - "modified_by": "Administrator", - "module": "Education", - "name": "Assessment Plan Criteria", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/assessment_plan_criteria/assessment_plan_criteria.py b/erpnext/education/doctype/assessment_plan_criteria/assessment_plan_criteria.py deleted file mode 100644 index 2cd17d6b95..0000000000 --- a/erpnext/education/doctype/assessment_plan_criteria/assessment_plan_criteria.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class AssessmentPlanCriteria(Document): - pass diff --git a/erpnext/education/doctype/assessment_result/__init__.py b/erpnext/education/doctype/assessment_result/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/assessment_result/assessment_result.js b/erpnext/education/doctype/assessment_result/assessment_result.js deleted file mode 100644 index b6d28817b5..0000000000 --- a/erpnext/education/doctype/assessment_result/assessment_result.js +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Assessment Result', { - refresh: function(frm) { - if (!frm.doc.__islocal) { - frm.trigger('setup_chart'); - } - - frm.get_field('details').grid.cannot_add_rows = true; - - frm.set_query('course', function() { - return { - query: 'erpnext.education.doctype.program_enrollment.program_enrollment.get_program_courses', - filters: { - 'program': frm.doc.program - } - }; - }); - - frm.set_query('academic_term', function() { - return { - filters: { - 'academic_year': frm.doc.academic_year - } - }; - }); - }, - - onload: function(frm) { - frm.set_query('assessment_plan', function() { - return { - filters: { - docstatus: 1 - } - }; - }); - }, - - assessment_plan: function(frm) { - if (frm.doc.assessment_plan) { - frappe.call({ - method: 'erpnext.education.api.get_assessment_details', - args: { - assessment_plan: frm.doc.assessment_plan - }, - callback: function(r) { - if (r.message) { - frappe.model.clear_table(frm.doc, 'details'); - $.each(r.message, function(i, d) { - var row = frm.add_child('details'); - row.assessment_criteria = d.assessment_criteria; - row.maximum_score = d.maximum_score; - }); - frm.refresh_field('details'); - } - } - }); - } - }, - - setup_chart: function(frm) { - let labels = []; - let maximum_scores = []; - let scores = []; - $.each(frm.doc.details, function(_i, e) { - labels.push(e.assessment_criteria); - maximum_scores.push(e.maximum_score); - scores.push(e.score); - }); - - if (labels.length && maximum_scores.length && scores.length) { - frm.dashboard.chart_area.empty().removeClass('hidden'); - new frappe.Chart('.form-graph', { - title: 'Assessment Results', - data: { - labels: labels, - datasets: [ - { - name: 'Maximum Score', - chartType: 'bar', - values: maximum_scores, - }, - { - name: 'Score Obtained', - chartType: 'bar', - values: scores, - } - ] - }, - colors: ['#4CA746', '#98D85B'], - type: 'bar' - }); - } - } -}); - -frappe.ui.form.on('Assessment Result Detail', { - score: function(frm, cdt, cdn) { - var d = locals[cdt][cdn]; - - if (!d.maximum_score || !frm.doc.grading_scale) { - d.score = ''; - frappe.throw(__('Please fill in all the details to generate Assessment Result.')); - } - - if (d.score > d.maximum_score) { - frappe.throw(__('Score cannot be greater than Maximum Score')); - } - else { - frappe.call({ - method: 'erpnext.education.api.get_grade', - args: { - grading_scale: frm.doc.grading_scale, - percentage: ((d.score/d.maximum_score) * 100) - }, - callback: function(r) { - if (r.message) { - frappe.model.set_value(cdt, cdn, 'grade', r.message); - } - } - }); - } - } -}); diff --git a/erpnext/education/doctype/assessment_result/assessment_result.json b/erpnext/education/doctype/assessment_result/assessment_result.json deleted file mode 100644 index 7a893aabb8..0000000000 --- a/erpnext/education/doctype/assessment_result/assessment_result.json +++ /dev/null @@ -1,203 +0,0 @@ -{ - "actions": [], - "allow_import": 1, - "autoname": "EDU-RES-.YYYY.-.#####", - "creation": "2015-11-13 17:18:06.468332", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "assessment_plan", - "program", - "course", - "academic_year", - "academic_term", - "column_break_3", - "student", - "student_name", - "student_group", - "assessment_group", - "grading_scale", - "section_break_5", - "details", - "section_break_8", - "maximum_score", - "column_break_11", - "total_score", - "grade", - "section_break_13", - "comment", - "amended_from" - ], - "fields": [ - { - "fieldname": "assessment_plan", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Assessment Plan", - "options": "Assessment Plan", - "reqd": 1 - }, - { - "fetch_from": "assessment_plan.program", - "fieldname": "program", - "fieldtype": "Link", - "label": "Program", - "options": "Program" - }, - { - "fetch_from": "assessment_plan.course", - "fieldname": "course", - "fieldtype": "Link", - "label": "Course", - "options": "Course" - }, - { - "fetch_from": "assessment_plan.academic_year", - "fieldname": "academic_year", - "fieldtype": "Link", - "label": "Academic Year", - "options": "Academic Year" - }, - { - "fetch_from": "assessment_plan.academic_term", - "fieldname": "academic_term", - "fieldtype": "Link", - "label": "Academic Term", - "options": "Academic Term" - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fieldname": "student", - "fieldtype": "Link", - "in_global_search": 1, - "label": "Student", - "options": "Student", - "reqd": 1 - }, - { - "fetch_from": "student.title", - "fieldname": "student_name", - "fieldtype": "Data", - "in_global_search": 1, - "in_list_view": 1, - "label": "Student Name", - "read_only": 1 - }, - { - "fetch_from": "assessment_plan.student_group", - "fieldname": "student_group", - "fieldtype": "Link", - "label": "Student Group", - "options": "Student Group" - }, - { - "fetch_from": "assessment_plan.assessment_group", - "fieldname": "assessment_group", - "fieldtype": "Link", - "label": "Assessment Group", - "options": "Assessment Group" - }, - { - "fetch_from": "assessment_plan.grading_scale", - "fieldname": "grading_scale", - "fieldtype": "Link", - "label": "Grading Scale", - "options": "Grading Scale", - "read_only": 1 - }, - { - "fieldname": "section_break_5", - "fieldtype": "Section Break", - "label": "Result" - }, - { - "fieldname": "details", - "fieldtype": "Table", - "label": "Details", - "options": "Assessment Result Detail", - "reqd": 1 - }, - { - "fieldname": "section_break_8", - "fieldtype": "Section Break" - }, - { - "fetch_from": "assessment_plan.maximum_assessment_score", - "fieldname": "maximum_score", - "fieldtype": "Float", - "label": "Maximum Score", - "read_only": 1 - }, - { - "fetch_from": "assessment_plan.maximum_assessment_score", - "fieldname": "column_break_11", - "fieldtype": "Column Break" - }, - { - "fieldname": "total_score", - "fieldtype": "Float", - "in_list_view": 1, - "label": "Total Score", - "read_only": 1 - }, - { - "fieldname": "grade", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Grade", - "read_only": 1 - }, - { - "fieldname": "section_break_13", - "fieldtype": "Section Break", - "label": "Summary" - }, - { - "fieldname": "comment", - "fieldtype": "Small Text", - "label": "Comment" - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Assessment Result", - "print_hide": 1, - "read_only": 1 - } - ], - "is_submittable": 1, - "links": [], - "modified": "2020-08-03 11:47:54.119486", - "modified_by": "Administrator", - "module": "Education", - "name": "Assessment Result", - "owner": "Administrator", - "permissions": [ - { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "submit": 1, - "write": 1 - } - ], - "restrict_to_domain": "Education", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "student_name" -} \ No newline at end of file diff --git a/erpnext/education/doctype/assessment_result/assessment_result.py b/erpnext/education/doctype/assessment_result/assessment_result.py deleted file mode 100644 index 1d485c139e..0000000000 --- a/erpnext/education/doctype/assessment_result/assessment_result.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.utils import flt -from frappe.utils.csvutils import getlink - -import erpnext.education -from erpnext.education.api import get_assessment_details, get_grade - - -class AssessmentResult(Document): - def validate(self): - erpnext.education.validate_student_belongs_to_group(self.student, self.student_group) - self.validate_maximum_score() - self.validate_grade() - self.validate_duplicate() - - def validate_maximum_score(self): - assessment_details = get_assessment_details(self.assessment_plan) - max_scores = {} - for d in assessment_details: - max_scores.update({d.assessment_criteria: d.maximum_score}) - - for d in self.details: - d.maximum_score = max_scores.get(d.assessment_criteria) - if d.score > d.maximum_score: - frappe.throw(_("Score cannot be greater than Maximum Score")) - - def validate_grade(self): - self.total_score = 0.0 - for d in self.details: - d.grade = get_grade(self.grading_scale, (flt(d.score) / d.maximum_score) * 100) - self.total_score += d.score - self.grade = get_grade(self.grading_scale, (self.total_score / self.maximum_score) * 100) - - def validate_duplicate(self): - assessment_result = frappe.get_list( - "Assessment Result", - filters={ - "name": ("not in", [self.name]), - "student": self.student, - "assessment_plan": self.assessment_plan, - "docstatus": ("!=", 2), - }, - ) - if assessment_result: - frappe.throw( - _("Assessment Result record {0} already exists.").format( - getlink("Assessment Result", assessment_result[0].name) - ) - ) diff --git a/erpnext/education/doctype/assessment_result/assessment_result_dashboard.py b/erpnext/education/doctype/assessment_result/assessment_result_dashboard.py deleted file mode 100644 index 5501f9221a..0000000000 --- a/erpnext/education/doctype/assessment_result/assessment_result_dashboard.py +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - -from frappe import _ - - -def get_data(): - return { - "reports": [ - {"label": _("Reports"), "items": ["Final Assessment Grades", "Course wise Assessment Report"]} - ] - } diff --git a/erpnext/education/doctype/assessment_result/test_assessment_result.py b/erpnext/education/doctype/assessment_result/test_assessment_result.py deleted file mode 100644 index 4872f48eda..0000000000 --- a/erpnext/education/doctype/assessment_result/test_assessment_result.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -from erpnext.education.api import get_grade - -# test_records = frappe.get_test_records('Assessment Result') - - -class TestAssessmentResult(unittest.TestCase): - def test_grade(self): - grade = get_grade("_Test Grading Scale", 80) - self.assertEqual("A", grade) - - grade = get_grade("_Test Grading Scale", 70) - self.assertEqual("B", grade) diff --git a/erpnext/education/doctype/assessment_result_detail/__init__.py b/erpnext/education/doctype/assessment_result_detail/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/assessment_result_detail/assessment_result_detail.json b/erpnext/education/doctype/assessment_result_detail/assessment_result_detail.json deleted file mode 100644 index 450f41cbbb..0000000000 --- a/erpnext/education/doctype/assessment_result_detail/assessment_result_detail.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "actions": [], - "creation": "2016-12-14 17:44:35.583123", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "assessment_criteria", - "maximum_score", - "column_break_2", - "score", - "grade" - ], - "fields": [ - { - "columns": 4, - "fieldname": "assessment_criteria", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Assessment Criteria", - "options": "Assessment Criteria", - "read_only": 1, - "reqd": 1 - }, - { - "columns": 2, - "fieldname": "maximum_score", - "fieldtype": "Float", - "in_list_view": 1, - "label": "Maximum Score", - "read_only": 1 - }, - { - "fieldname": "column_break_2", - "fieldtype": "Column Break" - }, - { - "columns": 2, - "fieldname": "score", - "fieldtype": "Float", - "in_list_view": 1, - "label": "Score", - "reqd": 1 - }, - { - "columns": 2, - "fieldname": "grade", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Grade", - "read_only": 1 - } - ], - "istable": 1, - "links": [], - "modified": "2020-07-31 13:27:17.699022", - "modified_by": "Administrator", - "module": "Education", - "name": "Assessment Result Detail", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "restrict_to_domain": "Education", - "sort_field": "modified", - "sort_order": "DESC" -} \ No newline at end of file diff --git a/erpnext/education/doctype/assessment_result_detail/assessment_result_detail.py b/erpnext/education/doctype/assessment_result_detail/assessment_result_detail.py deleted file mode 100644 index 5ef11297eb..0000000000 --- a/erpnext/education/doctype/assessment_result_detail/assessment_result_detail.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class AssessmentResultDetail(Document): - pass diff --git a/erpnext/education/doctype/assessment_result_tool/__init__.py b/erpnext/education/doctype/assessment_result_tool/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js b/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js deleted file mode 100644 index 053f0c2f1b..0000000000 --- a/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - - -frappe.ui.form.on('Assessment Result Tool', { - setup: function(frm) { - frm.add_fetch("assessment_plan", "student_group", "student_group"); - }, - - refresh: function(frm) { - if (frappe.route_options) { - frm.set_value("student_group", frappe.route_options.student_group); - frm.set_value("assessment_plan", frappe.route_options.assessment_plan); - frappe.route_options = null; - } else { - frm.trigger("assessment_plan"); - } - frm.disable_save(); - frm.page.clear_indicator(); - }, - - assessment_plan: function(frm) { - frm.doc.show_submit = false; - if(frm.doc.assessment_plan) { - if (!frm.doc.student_group) - return - frappe.call({ - method: "erpnext.education.api.get_assessment_students", - args: { - "assessment_plan": frm.doc.assessment_plan, - "student_group": frm.doc.student_group - }, - callback: function(r) { - if (r.message) { - frm.doc.students = r.message; - frm.events.render_table(frm); - for (let value of r.message) { - if (!value.docstatus) { - frm.doc.show_submit = true; - break; - } - } - frm.events.submit_result(frm); - } - } - }); - } - }, - - render_table: function(frm) { - $(frm.fields_dict.result_html.wrapper).empty(); - let assessment_plan = frm.doc.assessment_plan; - frappe.call({ - method: "erpnext.education.api.get_assessment_details", - args: { - assessment_plan: assessment_plan - }, - callback: function(r) { - frm.events.get_marks(frm, r.message); - } - }); - }, - - get_marks: function(frm, criteria_list) { - let max_total_score = 0; - criteria_list.forEach(function(c) { - max_total_score += c.maximum_score - }); - var result_table = $(frappe.render_template('assessment_result_tool', { - frm: frm, - students: frm.doc.students, - criteria: criteria_list, - max_total_score: max_total_score - })); - result_table.appendTo(frm.fields_dict.result_html.wrapper); - - result_table.on('change', 'input', function(e) { - let $input = $(e.target); - let student = $input.data().student; - let max_score = $input.data().maxScore; - let value = $input.val(); - if(value < 0) { - $input.val(0); - } else if(value > max_score) { - $input.val(max_score); - } - let total_score = 0; - let student_scores = {}; - student_scores["assessment_details"] = {} - result_table.find(`input[data-student=${student}].student-result-data`) - .each(function(el, input) { - let $input = $(input); - let criteria = $input.data().criteria; - let value = parseFloat($input.val()); - if (!Number.isNaN(value)) { - student_scores["assessment_details"][criteria] = value; - } - total_score += value; - }); - if(!Number.isNaN(total_score)) { - result_table.find(`span[data-student=${student}].total-score`).html(total_score); - } - if (Object.keys(student_scores["assessment_details"]).length === criteria_list.length) { - student_scores["student"] = student; - student_scores["total_score"] = total_score; - result_table.find(`[data-student=${student}].result-comment`) - .each(function(el, input){ - student_scores["comment"] = $(input).val(); - }); - frappe.call({ - method: "erpnext.education.api.mark_assessment_result", - args: { - "assessment_plan": frm.doc.assessment_plan, - "scores": student_scores - }, - callback: function(r) { - let assessment_result = r.message; - if (!frm.doc.show_submit) { - frm.doc.show_submit = true; - frm.events.submit_result; - } - for (var criteria of Object.keys(assessment_result.details)) { - result_table.find(`[data-criteria=${criteria}][data-student=${assessment_result - .student}].student-result-grade`).each(function(e1, input) { - $(input).html(assessment_result.details[criteria]); - }); - } - result_table.find(`span[data-student=${assessment_result.student}].total-score-grade`).html(assessment_result.grade); - let link_span = result_table.find(`span[data-student=${assessment_result.student}].total-result-link`); - $(link_span).css("display", "block"); - $(link_span).find("a").attr("href", "/app/assessment-result/"+assessment_result.name); - } - }); - } - }); - }, - - submit_result: function(frm) { - if (frm.doc.show_submit) { - frm.page.set_primary_action(__("Submit"), function() { - frappe.call({ - method: "erpnext.education.api.submit_assessment_results", - args: { - "assessment_plan": frm.doc.assessment_plan, - "student_group": frm.doc.student_group - }, - callback: function(r) { - if (r.message) { - frappe.msgprint(__("{0} Result submittted", [r.message])); - } else { - frappe.msgprint(__("No Result to submit")); - } - frm.events.assessment_plan(frm); - } - }); - }); - } - else { - frm.page.clear_primary_action(); - } - } -}); diff --git a/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.json b/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.json deleted file mode 100644 index ddef100ff5..0000000000 --- a/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.json +++ /dev/null @@ -1,235 +0,0 @@ -{ - "allow_copy": 1, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2017-01-05 12:27:48.951036", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "fieldname": "assessment_plan", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Assessment Plan", - "length": 0, - "no_copy": 0, - "options": "Assessment Plan", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_2", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student_group", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Student Group", - "length": 0, - "no_copy": 0, - "options": "Student Group", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "assessment_plan", - "fieldname": "section_break_5", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "result_html", - "fieldtype": "HTML", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Result HTML", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 1, - "hide_toolbar": 1, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 1, - "istable": 0, - "max_attachments": 0, - "modified": "2017-12-27 09:36:37.155890", - "modified_by": "Administrator", - "module": "Education", - "name": "Assessment Result Tool", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 0, - "role": "Academics User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 1 - }, - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 0, - "role": "Instructor", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.py b/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.py deleted file mode 100644 index 4b953bec15..0000000000 --- a/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class AssessmentResultTool(Document): - pass diff --git a/erpnext/education/doctype/assessment_result_tool/test_assessment_result_tool.py b/erpnext/education/doctype/assessment_result_tool/test_assessment_result_tool.py deleted file mode 100644 index 49e0be08f0..0000000000 --- a/erpnext/education/doctype/assessment_result_tool/test_assessment_result_tool.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestAssessmentResultTool(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/content_activity/__init__.py b/erpnext/education/doctype/content_activity/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/content_activity/content_activity.json b/erpnext/education/doctype/content_activity/content_activity.json deleted file mode 100644 index b4c95dad9c..0000000000 --- a/erpnext/education/doctype/content_activity/content_activity.json +++ /dev/null @@ -1,141 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-10-16 03:55:53.283893", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "content", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Content", - "length": 0, - "no_copy": 0, - "options": "Content", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "content.content_type", - "fieldname": "content_type", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Content Type", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "last_activity", - "fieldtype": "Datetime", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Last Activity ", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-10-16 03:55:58.202436", - "modified_by": "Administrator", - "module": "Education", - "name": "Content Activity", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/content_activity/content_activity.py b/erpnext/education/doctype/content_activity/content_activity.py deleted file mode 100644 index f30cb87a9e..0000000000 --- a/erpnext/education/doctype/content_activity/content_activity.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class ContentActivity(Document): - pass diff --git a/erpnext/education/doctype/content_question/__init__.py b/erpnext/education/doctype/content_question/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/content_question/content_question.js b/erpnext/education/doctype/content_question/content_question.js deleted file mode 100644 index 7615f5efcf..0000000000 --- a/erpnext/education/doctype/content_question/content_question.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Content Question', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/content_question/content_question.json b/erpnext/education/doctype/content_question/content_question.json deleted file mode 100644 index d390e8ef70..0000000000 --- a/erpnext/education/doctype/content_question/content_question.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-10-15 14:35:40.728454", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "question_link", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Question Link", - "length": 0, - "no_copy": 0, - "options": "Question", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-10-15 14:41:31.729083", - "modified_by": "Administrator", - "module": "Education", - "name": "Content Question", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/content_question/content_question.py b/erpnext/education/doctype/content_question/content_question.py deleted file mode 100644 index f52f0c85d3..0000000000 --- a/erpnext/education/doctype/content_question/content_question.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class ContentQuestion(Document): - pass diff --git a/erpnext/education/doctype/content_question/test_content_question.py b/erpnext/education/doctype/content_question/test_content_question.py deleted file mode 100644 index 63a5a96700..0000000000 --- a/erpnext/education/doctype/content_question/test_content_question.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestContentQuestion(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/course/__init__.py b/erpnext/education/doctype/course/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/course/course.js b/erpnext/education/doctype/course/course.js deleted file mode 100644 index bd8d62c8d2..0000000000 --- a/erpnext/education/doctype/course/course.js +++ /dev/null @@ -1,79 +0,0 @@ -frappe.ui.form.on('Course', { - refresh: function(frm) { - if (!cur_frm.doc.__islocal) { - frm.add_custom_button(__('Add to Programs'), function() { - frm.trigger('add_course_to_programs') - }, __('Action')); - } - - frm.set_query('default_grading_scale', function(){ - return { - filters: { - docstatus: 1 - } - } - }); - }, - - add_course_to_programs: function(frm) { - get_programs_without_course(frm.doc.name).then(r => { - if (r.message.length) { - frappe.prompt([ - { - fieldname: 'programs', - label: __('Programs'), - fieldtype: 'MultiSelectPills', - get_data: function() { - return r.message; - } - }, - { - fieldtype: 'Check', - label: __('Is Mandatory'), - fieldname: 'mandatory', - } - ], - function(data) { - frappe.call({ - method: 'erpnext.education.doctype.course.course.add_course_to_programs', - args: { - 'course': frm.doc.name, - 'programs': data.programs, - 'mandatory': data.mandatory - }, - callback: function(r) { - if (!r.exc) { - frm.reload_doc(); - } - }, - freeze: true, - freeze_message: __('...Adding Course to Programs') - }) - }, __('Add Course to Programs'), __('Add')); - } else { - frappe.msgprint(__('This course is already added to the existing programs')); - } - }); - } -}); - -frappe.ui.form.on('Course Topic', { - topics_add: function(frm){ - frm.fields_dict['topics'].grid.get_field('topic').get_query = function(doc){ - var topics_list = []; - if(!doc.__islocal) topics_list.push(doc.name); - $.each(doc.topics, function(idx, val){ - if (val.topic) topics_list.push(val.topic); - }); - return { filters: [['Topic', 'name', 'not in', topics_list]] }; - }; - } -}); - -let get_programs_without_course = function(course) { - return frappe.call({ - type: 'GET', - method: 'erpnext.education.doctype.course.course.get_programs_without_course', - args: {'course': course} - }); -} diff --git a/erpnext/education/doctype/course/course.json b/erpnext/education/doctype/course/course.json deleted file mode 100644 index da10db1857..0000000000 --- a/erpnext/education/doctype/course/course.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:course_name", - "creation": "2015-09-07 12:39:55.181893", - "doctype": "DocType", - "engine": "InnoDB", - "field_order": [ - "course_name", - "department", - "section_break_6", - "topics", - "description", - "hero_image", - "assessment", - "default_grading_scale", - "assessment_criteria" - ], - "fields": [ - { - "fieldname": "course_name", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Course Name", - "reqd": 1, - "unique": 1 - }, - { - "fieldname": "department", - "fieldtype": "Link", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Department", - "options": "Department" - }, - { - "fieldname": "section_break_6", - "fieldtype": "Section Break", - "label": "Portal Settings" - }, - { - "fieldname": "topics", - "fieldtype": "Table", - "label": "Topics", - "options": "Course Topic" - }, - { - "fieldname": "hero_image", - "fieldtype": "Attach Image", - "hidden": 1, - "label": "Hero Image" - }, - { - "fieldname": "assessment", - "fieldtype": "Section Break", - "label": "Assessment" - }, - { - "fieldname": "default_grading_scale", - "fieldtype": "Link", - "label": "Default Grading Scale", - "options": "Grading Scale" - }, - { - "fieldname": "assessment_criteria", - "fieldtype": "Table", - "label": "Assessment Criteria", - "options": "Course Assessment Criteria" - }, - { - "fieldname": "description", - "fieldtype": "Small Text", - "label": "Description" - } - ], - "image_field": "hero_image", - "modified": "2020-03-29 12:50:27.677589", - "modified_by": "Administrator", - "module": "Education", - "name": "Course", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Administrator", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Education Manager", - "share": 1, - "write": 1 - } - ], - "restrict_to_domain": "Education", - "search_fields": "course_name", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC" -} \ No newline at end of file diff --git a/erpnext/education/doctype/course/course.py b/erpnext/education/doctype/course/course.py deleted file mode 100644 index baf72e8cb7..0000000000 --- a/erpnext/education/doctype/course/course.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -import json - -import frappe -from frappe import _ -from frappe.model.document import Document - - -class Course(Document): - def validate(self): - self.validate_assessment_criteria() - - def validate_assessment_criteria(self): - if self.assessment_criteria: - total_weightage = 0 - for criteria in self.assessment_criteria: - total_weightage += criteria.weightage or 0 - if total_weightage != 100: - frappe.throw(_("Total Weightage of all Assessment Criteria must be 100%")) - - def get_topics(self): - topic_data = [] - for topic in self.topics: - topic_doc = frappe.get_doc("Topic", topic.topic) - if topic_doc.topic_content: - topic_data.append(topic_doc) - return topic_data - - -@frappe.whitelist() -def add_course_to_programs(course, programs, mandatory=False): - programs = json.loads(programs) - for entry in programs: - program = frappe.get_doc("Program", entry) - program.append("courses", {"course": course, "course_name": course, "mandatory": mandatory}) - program.flags.ignore_mandatory = True - program.save() - frappe.db.commit() - frappe.msgprint( - _("Course {0} has been added to all the selected programs successfully.").format( - frappe.bold(course) - ), - title=_("Programs updated"), - indicator="green", - ) - - -@frappe.whitelist() -def get_programs_without_course(course): - data = [] - for entry in frappe.db.get_all("Program"): - program = frappe.get_doc("Program", entry.name) - courses = [c.course for c in program.courses] - if not courses or course not in courses: - data.append(program.name) - return data diff --git a/erpnext/education/doctype/course/course_dashboard.py b/erpnext/education/doctype/course/course_dashboard.py deleted file mode 100644 index 6ba4475079..0000000000 --- a/erpnext/education/doctype/course/course_dashboard.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - -from frappe import _ - - -def get_data(): - return { - "fieldname": "course", - "transactions": [ - { - "label": _("Program and Course"), - "items": ["Program", "Course Enrollment", "Course Schedule"], - }, - {"label": _("Student"), "items": ["Student Group"]}, - {"label": _("Assessment"), "items": ["Assessment Plan", "Assessment Result"]}, - ], - } diff --git a/erpnext/education/doctype/course/test_course.py b/erpnext/education/doctype/course/test_course.py deleted file mode 100644 index caddefef3e..0000000000 --- a/erpnext/education/doctype/course/test_course.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and Contributors -# See license.txt - -import unittest - -import frappe - -from erpnext.education.doctype.topic.test_topic import make_topic, make_topic_and_linked_content - -# test_records = frappe.get_test_records('Course') - - -class TestCourse(unittest.TestCase): - def setUp(self): - make_topic_and_linked_content("_Test Topic 1", [{"type": "Article", "name": "_Test Article 1"}]) - make_topic_and_linked_content("_Test Topic 2", [{"type": "Article", "name": "_Test Article 2"}]) - make_course_and_linked_topic("_Test Course 1", ["_Test Topic 1", "_Test Topic 2"]) - - def test_get_topics(self): - course = frappe.get_doc("Course", "_Test Course 1") - topics = course.get_topics() - self.assertEqual(topics[0].name, "_Test Topic 1") - self.assertEqual(topics[1].name, "_Test Topic 2") - frappe.db.rollback() - - -def make_course(name): - try: - course = frappe.get_doc("Course", name) - except frappe.DoesNotExistError: - course = frappe.get_doc({"doctype": "Course", "course_name": name, "course_code": name}).insert() - return course.name - - -def make_course_and_linked_topic(course_name, topic_name_list): - try: - course = frappe.get_doc("Course", course_name) - except frappe.DoesNotExistError: - make_course(course_name) - course = frappe.get_doc("Course", course_name) - topic_list = [make_topic(topic_name) for topic_name in topic_name_list] - for topic in topic_list: - course.append("topics", {"topic": topic}) - course.save() - return course diff --git a/erpnext/education/doctype/course/test_records.json b/erpnext/education/doctype/course/test_records.json deleted file mode 100644 index 1e7467aed2..0000000000 --- a/erpnext/education/doctype/course/test_records.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "course_name": "TC100", - "course_abbreviation": "TC" - }, - { - "course_name": "TC101", - "course_abbreviation": "TC1" - }, - { - "course_name": "TC102", - "course_abbreviation": "TC2" - } -] \ No newline at end of file diff --git a/erpnext/education/doctype/course_activity/__init__.py b/erpnext/education/doctype/course_activity/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/course_activity/course_activity.js b/erpnext/education/doctype/course_activity/course_activity.js deleted file mode 100644 index 5115fc415e..0000000000 --- a/erpnext/education/doctype/course_activity/course_activity.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Course Activity', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/course_activity/course_activity.json b/erpnext/education/doctype/course_activity/course_activity.json deleted file mode 100644 index 3e23c90da0..0000000000 --- a/erpnext/education/doctype/course_activity/course_activity.json +++ /dev/null @@ -1,301 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "format:EDU-CA-{YYYY}-{#####}", - "beta": 1, - "creation": "2018-10-01 17:35:54.391413", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "enrollment", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Course Enrollment", - "length": 0, - "no_copy": 0, - "options": "Course Enrollment", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "enrollment.course", - "fieldname": "course", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Course", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "enrollment.student", - "fieldname": "student", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Student", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "content_type", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Content Type", - "length": 0, - "no_copy": 0, - "options": "\nArticle\nVideo", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "content", - "fieldtype": "Dynamic Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Content", - "length": 0, - "no_copy": 0, - "options": "content_type", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "activity_date", - "fieldtype": "Datetime", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Activity Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-12-06 11:53:08.006123", - "modified_by": "Administrator", - "module": "Education", - "name": "Course Activity", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - }, - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 1, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "LMS User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 0 - }, - { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 0 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} diff --git a/erpnext/education/doctype/course_activity/course_activity.py b/erpnext/education/doctype/course_activity/course_activity.py deleted file mode 100644 index 784260d07c..0000000000 --- a/erpnext/education/doctype/course_activity/course_activity.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document - - -class CourseActivity(Document): - def validate(self): - self.check_if_enrolled() - - def check_if_enrolled(self): - if frappe.db.exists("Course Enrollment", self.enrollment): - return True - else: - frappe.throw(_("Course Enrollment {0} does not exists").format(self.enrollment)) diff --git a/erpnext/education/doctype/course_activity/test_course_activity.py b/erpnext/education/doctype/course_activity/test_course_activity.py deleted file mode 100644 index 677b60a845..0000000000 --- a/erpnext/education/doctype/course_activity/test_course_activity.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -import frappe - - -class TestCourseActivity(unittest.TestCase): - pass - - -def make_course_activity(enrollment, content_type, content): - activity = frappe.get_all( - "Course Activity", - filters={"enrollment": enrollment, "content_type": content_type, "content": content}, - ) - try: - activity = frappe.get_doc("Course Activity", activity[0]["name"]) - except (IndexError, frappe.DoesNotExistError): - activity = frappe.get_doc( - { - "doctype": "Course Activity", - "enrollment": enrollment, - "content_type": content_type, - "content": content, - "activity_date": frappe.utils.datetime.datetime.now(), - } - ).insert() - return activity diff --git a/erpnext/education/doctype/course_assessment_criteria/__init__.py b/erpnext/education/doctype/course_assessment_criteria/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/course_assessment_criteria/course_assessment_criteria.json b/erpnext/education/doctype/course_assessment_criteria/course_assessment_criteria.json deleted file mode 100644 index 2d8c0b3441..0000000000 --- a/erpnext/education/doctype/course_assessment_criteria/course_assessment_criteria.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "", - "beta": 0, - "creation": "2016-12-14 16:46:46.786353", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "assessment_criteria", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Assessment Criteria", - "length": 0, - "no_copy": 0, - "options": "Assessment Criteria", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_2", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "weightage", - "fieldtype": "Percent", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Weightage", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2017-11-10 19:10:44.710837", - "modified_by": "Administrator", - "module": "Education", - "name": "Course Assessment Criteria", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/course_assessment_criteria/course_assessment_criteria.py b/erpnext/education/doctype/course_assessment_criteria/course_assessment_criteria.py deleted file mode 100644 index 4223741f03..0000000000 --- a/erpnext/education/doctype/course_assessment_criteria/course_assessment_criteria.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class CourseAssessmentCriteria(Document): - pass diff --git a/erpnext/education/doctype/course_content/__init__.py b/erpnext/education/doctype/course_content/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/course_content/course_content.js b/erpnext/education/doctype/course_content/course_content.js deleted file mode 100644 index b9faf99aaf..0000000000 --- a/erpnext/education/doctype/course_content/course_content.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Course Content', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/course_content/course_content.json b/erpnext/education/doctype/course_content/course_content.json deleted file mode 100644 index 378e56005f..0000000000 --- a/erpnext/education/doctype/course_content/course_content.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-10-01 13:04:09.313771", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "", - "fieldname": "content_type", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Content Type", - "length": 0, - "no_copy": 0, - "options": "\nArticle\nVideo\nQuiz", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_2", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "content", - "fieldtype": "Dynamic Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Content", - "length": 0, - "no_copy": 0, - "options": "content_type", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-10-17 07:36:04.029818", - "modified_by": "Administrator", - "module": "Education", - "name": "Course Content", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/course_content/course_content.py b/erpnext/education/doctype/course_content/course_content.py deleted file mode 100644 index abc370ecbe..0000000000 --- a/erpnext/education/doctype/course_content/course_content.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class CourseContent(Document): - pass diff --git a/erpnext/education/doctype/course_content/test_course_content.py b/erpnext/education/doctype/course_content/test_course_content.py deleted file mode 100644 index 49f042e865..0000000000 --- a/erpnext/education/doctype/course_content/test_course_content.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestCourseContent(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/course_enrollment/__init__.py b/erpnext/education/doctype/course_enrollment/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.js b/erpnext/education/doctype/course_enrollment/course_enrollment.js deleted file mode 100644 index b5d3cc56e5..0000000000 --- a/erpnext/education/doctype/course_enrollment/course_enrollment.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Course Enrollment', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.json b/erpnext/education/doctype/course_enrollment/course_enrollment.json deleted file mode 100644 index 6286ec1e66..0000000000 --- a/erpnext/education/doctype/course_enrollment/course_enrollment.json +++ /dev/null @@ -1,233 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "format:EDU-CE-{YYYY}-{#####}", - "beta": 1, - "creation": "2018-10-15 15:35:39.375161", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "program_enrollment", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Program Enrollment", - "length": 0, - "no_copy": 0, - "options": "Program Enrollment", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 1, - "label": "Student", - "length": 0, - "no_copy": 0, - "options": "Student", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "course", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Course", - "length": 0, - "no_copy": 0, - "options": "Course", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "enrollment_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Enrollment Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-11-25 18:59:01.742377", - "modified_by": "Administrator", - "module": "Education", - "name": "Course Enrollment", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - }, - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "LMS User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - }, - { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 0 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.py b/erpnext/education/doctype/course_enrollment/course_enrollment.py deleted file mode 100644 index 18639b1178..0000000000 --- a/erpnext/education/doctype/course_enrollment/course_enrollment.py +++ /dev/null @@ -1,112 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from functools import reduce - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.utils import get_link_to_form - - -class CourseEnrollment(Document): - def validate(self): - self.validate_duplication() - - def get_progress(self, student): - """ - Returns Progress of given student for a particular course enrollment - - :param self: Course Enrollment Object - :param student: Student Object - """ - course = frappe.get_doc("Course", self.course) - topics = course.get_topics() - progress = [] - for topic in topics: - progress.append(student.get_topic_progress(self.name, topic)) - if progress: - return reduce(lambda x, y: x + y, progress) # Flatten out the List - else: - return [] - - def validate_duplication(self): - enrollment = frappe.db.exists( - "Course Enrollment", - { - "student": self.student, - "course": self.course, - "program_enrollment": self.program_enrollment, - "name": ("!=", self.name), - }, - ) - if enrollment: - frappe.throw( - _("Student is already enrolled via Course Enrollment {0}").format( - get_link_to_form("Course Enrollment", enrollment) - ), - title=_("Duplicate Entry"), - ) - - def add_quiz_activity(self, quiz_name, quiz_response, answers, score, status, time_taken): - result = {k: ("Correct" if v else "Wrong") for k, v in answers.items()} - result_data = [] - for key in answers: - item = {} - item["question"] = key - item["quiz_result"] = result[key] - try: - if not quiz_response[key]: - item["selected_option"] = "Unattempted" - elif isinstance(quiz_response[key], list): - item["selected_option"] = ", ".join( - frappe.get_value("Options", res, "option") for res in quiz_response[key] - ) - else: - item["selected_option"] = frappe.get_value("Options", quiz_response[key], "option") - except KeyError: - item["selected_option"] = "Unattempted" - result_data.append(item) - - quiz_activity = frappe.get_doc( - { - "doctype": "Quiz Activity", - "enrollment": self.name, - "quiz": quiz_name, - "activity_date": frappe.utils.datetime.datetime.now(), - "result": result_data, - "score": score, - "status": status, - "time_taken": time_taken, - } - ).insert(ignore_permissions=True) - - def add_activity(self, content_type, content): - activity = check_activity_exists(self.name, content_type, content) - if activity: - return activity - else: - activity = frappe.get_doc( - { - "doctype": "Course Activity", - "enrollment": self.name, - "content_type": content_type, - "content": content, - "activity_date": frappe.utils.datetime.datetime.now(), - } - ) - - activity.insert(ignore_permissions=True) - return activity.name - - -def check_activity_exists(enrollment, content_type, content): - activity = frappe.get_all( - "Course Activity", - filters={"enrollment": enrollment, "content_type": content_type, "content": content}, - ) - if activity: - return activity[0].name - else: - return None diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment_dashboard.py b/erpnext/education/doctype/course_enrollment/course_enrollment_dashboard.py deleted file mode 100644 index 31a90fd5ad..0000000000 --- a/erpnext/education/doctype/course_enrollment/course_enrollment_dashboard.py +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - -from frappe import _ - - -def get_data(): - return { - "fieldname": "enrollment", - "transactions": [{"label": _("Activity"), "items": ["Course Activity", "Quiz Activity"]}], - } diff --git a/erpnext/education/doctype/course_enrollment/test_course_enrollment.py b/erpnext/education/doctype/course_enrollment/test_course_enrollment.py deleted file mode 100644 index 6862e058f0..0000000000 --- a/erpnext/education/doctype/course_enrollment/test_course_enrollment.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -import frappe - -from erpnext.education.doctype.course_activity.test_course_activity import make_course_activity -from erpnext.education.doctype.program.test_program import setup_program -from erpnext.education.doctype.student.test_student import create_student, get_student - - -class TestCourseEnrollment(unittest.TestCase): - def setUp(self): - setup_program() - student = create_student( - {"first_name": "_Test First", "last_name": "_Test Last", "email": "_test_student_1@example.com"} - ) - program_enrollment = student.enroll_in_program("_Test Program") - course_enrollment = frappe.db.get_value( - "Course Enrollment", - { - "course": "_Test Course 1", - "student": student.name, - "program_enrollment": program_enrollment.name, - }, - "name", - ) - make_course_activity(course_enrollment, "Article", "_Test Article 1-1") - - def test_get_progress(self): - student = get_student("_test_student_1@example.com") - program_enrollment_name = frappe.get_list( - "Program Enrollment", filters={"student": student.name, "Program": "_Test Program"} - )[0].name - course_enrollment_name = frappe.get_list( - "Course Enrollment", - filters={ - "student": student.name, - "course": "_Test Course 1", - "program_enrollment": program_enrollment_name, - }, - )[0].name - course_enrollment = frappe.get_doc("Course Enrollment", course_enrollment_name) - progress = course_enrollment.get_progress(student) - finished = {"content": "_Test Article 1-1", "content_type": "Article", "is_complete": True} - self.assertTrue(finished in progress) - frappe.db.rollback() - - def tearDown(self): - for entry in frappe.db.get_all("Course Enrollment"): - frappe.delete_doc("Course Enrollment", entry.name) - - for entry in frappe.db.get_all("Program Enrollment"): - doc = frappe.get_doc("Program Enrollment", entry.name) - doc.cancel() - doc.delete() diff --git a/erpnext/education/doctype/course_schedule/__init__.py b/erpnext/education/doctype/course_schedule/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/course_schedule/course_schedule.js b/erpnext/education/doctype/course_schedule/course_schedule.js deleted file mode 100644 index 366bbd8b0d..0000000000 --- a/erpnext/education/doctype/course_schedule/course_schedule.js +++ /dev/null @@ -1,16 +0,0 @@ -frappe.provide("education"); - -cur_frm.add_fetch("student_group", "course", "course") -frappe.ui.form.on("Course Schedule", { - refresh: function(frm) { - if (!frm.doc.__islocal) { - frm.add_custom_button(__("Mark Attendance"), function() { - frappe.route_options = { - based_on: "Course Schedule", - course_schedule: frm.doc.name - } - frappe.set_route("Form", "Student Attendance Tool"); - }).addClass("btn-primary"); - } - } -}); diff --git a/erpnext/education/doctype/course_schedule/course_schedule.json b/erpnext/education/doctype/course_schedule/course_schedule.json deleted file mode 100644 index 38d9b508f0..0000000000 --- a/erpnext/education/doctype/course_schedule/course_schedule.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "actions": [], - "allow_import": 1, - "autoname": "naming_series:", - "creation": "2015-09-09 16:34:04.960369", - "doctype": "DocType", - "document_type": "Document", - "engine": "InnoDB", - "field_order": [ - "student_group", - "instructor", - "instructor_name", - "column_break_2", - "naming_series", - "course", - "color", - "section_break_6", - "schedule_date", - "room", - "column_break_9", - "from_time", - "to_time", - "title" - ], - "fields": [ - { - "fieldname": "student_group", - "fieldtype": "Link", - "in_global_search": 1, - "in_standard_filter": 1, - "label": "Student Group", - "options": "Student Group", - "reqd": 1 - }, - { - "fieldname": "instructor", - "fieldtype": "Link", - "in_standard_filter": 1, - "label": "Instructor", - "options": "Instructor", - "reqd": 1 - }, - { - "fetch_from": "instructor.instructor_name", - "fieldname": "instructor_name", - "fieldtype": "Read Only", - "in_global_search": 1, - "label": "Instructor Name", - "read_only": 1 - }, - { - "fieldname": "column_break_2", - "fieldtype": "Column Break" - }, - { - "fieldname": "naming_series", - "fieldtype": "Select", - "label": "Naming Series", - "options": "EDU-CSH-.YYYY.-", - "set_only_once": 1 - }, - { - "fieldname": "course", - "fieldtype": "Link", - "in_global_search": 1, - "label": "Course", - "options": "Course", - "reqd": 1 - }, - { - "fieldname": "color", - "fieldtype": "Color", - "label": "Color", - "print_hide": 1 - }, - { - "fieldname": "section_break_6", - "fieldtype": "Section Break" - }, - { - "default": "Today", - "fieldname": "schedule_date", - "fieldtype": "Date", - "label": "Schedule Date" - }, - { - "fieldname": "room", - "fieldtype": "Link", - "label": "Room", - "options": "Room", - "reqd": 1 - }, - { - "fieldname": "column_break_9", - "fieldtype": "Column Break" - }, - { - "fieldname": "from_time", - "fieldtype": "Time", - "in_list_view": 1, - "label": "From Time", - "reqd": 1 - }, - { - "fieldname": "to_time", - "fieldtype": "Time", - "in_list_view": 1, - "label": "To Time", - "reqd": 1 - }, - { - "fieldname": "title", - "fieldtype": "Data", - "hidden": 1, - "label": "Title" - } - ], - "links": [], - "modified": "2021-11-24 11:57:08.164449", - "modified_by": "Administrator", - "module": "Education", - "name": "Course Schedule", - "naming_rule": "By \"Naming Series\" field", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "write": 1 - } - ], - "restrict_to_domain": "Education", - "sort_field": "schedule_date", - "sort_order": "DESC", - "title_field": "title" -} \ No newline at end of file diff --git a/erpnext/education/doctype/course_schedule/course_schedule.py b/erpnext/education/doctype/course_schedule/course_schedule.py deleted file mode 100644 index d2b31f4e05..0000000000 --- a/erpnext/education/doctype/course_schedule/course_schedule.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -from datetime import datetime - -import frappe -from frappe import _ -from frappe.model.document import Document - - -class CourseSchedule(Document): - def validate(self): - self.instructor_name = frappe.db.get_value("Instructor", self.instructor, "instructor_name") - self.set_title() - self.validate_course() - self.validate_date() - self.validate_overlap() - - def set_title(self): - """Set document Title""" - self.title = ( - self.course + " by " + (self.instructor_name if self.instructor_name else self.instructor) - ) - - def validate_course(self): - group_based_on, course = frappe.db.get_value( - "Student Group", self.student_group, ["group_based_on", "course"] - ) - if group_based_on == "Course": - self.course = course - - def validate_date(self): - """Validates if from_time is greater than to_time""" - if self.from_time > self.to_time: - frappe.throw(_("From Time cannot be greater than To Time.")) - - """Handles specicfic case to update schedule date in calendar """ - if isinstance(self.from_time, str): - try: - datetime_obj = datetime.strptime(self.from_time, "%Y-%m-%d %H:%M:%S") - self.schedule_date = datetime_obj - except ValueError: - pass - - def validate_overlap(self): - """Validates overlap for Student Group, Instructor, Room""" - - from erpnext.education.utils import validate_overlap_for - - # Validate overlapping course schedules. - if self.student_group: - validate_overlap_for(self, "Course Schedule", "student_group") - - validate_overlap_for(self, "Course Schedule", "instructor") - validate_overlap_for(self, "Course Schedule", "room") - - # validate overlapping assessment schedules. - if self.student_group: - validate_overlap_for(self, "Assessment Plan", "student_group") - - validate_overlap_for(self, "Assessment Plan", "room") - validate_overlap_for(self, "Assessment Plan", "supervisor", self.instructor) diff --git a/erpnext/education/doctype/course_schedule/course_schedule_calendar.js b/erpnext/education/doctype/course_schedule/course_schedule_calendar.js deleted file mode 100644 index cacd539b22..0000000000 --- a/erpnext/education/doctype/course_schedule/course_schedule_calendar.js +++ /dev/null @@ -1,38 +0,0 @@ -frappe.views.calendar["Course Schedule"] = { - field_map: { - "start": "from_time", - "end": "to_time", - "id": "name", - "title": "course", - "allDay": "allDay", - }, - gantt: false, - order_by: "schedule_date", - filters: [ - { - "fieldtype": "Link", - "fieldname": "student_group", - "options": "Student Group", - "label": __("Student Group") - }, - { - "fieldtype": "Link", - "fieldname": "course", - "options": "Course", - "label": __("Course") - }, - { - "fieldtype": "Link", - "fieldname": "instructor", - "options": "Instructor", - "label": __("Instructor") - }, - { - "fieldtype": "Link", - "fieldname": "room", - "options": "Room", - "label": __("Room") - } - ], - get_events_method: "erpnext.education.api.get_course_schedule_events" -} diff --git a/erpnext/education/doctype/course_schedule/course_schedule_dashboard.py b/erpnext/education/doctype/course_schedule/course_schedule_dashboard.py deleted file mode 100644 index 76a3f04805..0000000000 --- a/erpnext/education/doctype/course_schedule/course_schedule_dashboard.py +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - -from frappe import _ - - -def get_data(): - return { - "fieldname": "course_schedule", - "transactions": [{"label": _("Attendance"), "items": ["Student Attendance"]}], - } diff --git a/erpnext/education/doctype/course_schedule/test_course_schedule.py b/erpnext/education/doctype/course_schedule/test_course_schedule.py deleted file mode 100644 index ac094645ba..0000000000 --- a/erpnext/education/doctype/course_schedule/test_course_schedule.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and Contributors -# See license.txt - -import datetime -import unittest - -import frappe -from frappe.utils import to_timedelta, today -from frappe.utils.data import add_to_date - -from erpnext.education.utils import OverlapError - -# test_records = frappe.get_test_records('Course Schedule') - - -class TestCourseSchedule(unittest.TestCase): - def test_student_group_conflict(self): - cs1 = make_course_schedule_test_record(simulate=True) - - cs2 = make_course_schedule_test_record( - schedule_date=cs1.schedule_date, - from_time=cs1.from_time, - to_time=cs1.to_time, - instructor="_Test Instructor 2", - room=frappe.get_all("Room")[1].name, - do_not_save=1, - ) - self.assertRaises(OverlapError, cs2.save) - - def test_instructor_conflict(self): - cs1 = make_course_schedule_test_record(simulate=True) - - cs2 = make_course_schedule_test_record( - from_time=cs1.from_time, - to_time=cs1.to_time, - student_group="Course-TC101-2014-2015 (_Test Academic Term)", - room=frappe.get_all("Room")[1].name, - do_not_save=1, - ) - self.assertRaises(OverlapError, cs2.save) - - def test_room_conflict(self): - cs1 = make_course_schedule_test_record(simulate=True) - - cs2 = make_course_schedule_test_record( - from_time=cs1.from_time, - to_time=cs1.to_time, - student_group="Course-TC101-2014-2015 (_Test Academic Term)", - instructor="_Test Instructor 2", - do_not_save=1, - ) - self.assertRaises(OverlapError, cs2.save) - - def test_no_conflict(self): - cs1 = make_course_schedule_test_record(simulate=True) - - make_course_schedule_test_record( - from_time=cs1.from_time, - to_time=cs1.to_time, - student_group="Course-TC102-2014-2015 (_Test Academic Term)", - instructor="_Test Instructor 2", - room=frappe.get_all("Room")[1].name, - ) - - def test_update_schedule_date(self): - doc = make_course_schedule_test_record(schedule_date=add_to_date(today(), days=1)) - doc.schedule_date = add_to_date(doc.schedule_date, days=1) - doc.save() - - -def make_course_schedule_test_record(**args): - args = frappe._dict(args) - - course_schedule = frappe.new_doc("Course Schedule") - course_schedule.student_group = ( - args.student_group or "Course-TC101-2014-2015 (_Test Academic Term)" - ) - course_schedule.course = args.course or "TC101" - course_schedule.instructor = args.instructor or "_Test Instructor" - course_schedule.room = args.room or frappe.get_all("Room")[0].name - - course_schedule.schedule_date = args.schedule_date or today() - course_schedule.from_time = args.from_time or to_timedelta("01:00:00") - course_schedule.to_time = args.to_time or course_schedule.from_time + datetime.timedelta(hours=1) - - if not args.do_not_save: - if args.simulate: - while True: - try: - course_schedule.save() - break - except OverlapError: - course_schedule.from_time = course_schedule.from_time + datetime.timedelta(minutes=10) - course_schedule.to_time = course_schedule.from_time + datetime.timedelta(hours=1) - else: - course_schedule.save() - - return course_schedule diff --git a/erpnext/education/doctype/course_scheduling_tool/__init__.py b/erpnext/education/doctype/course_scheduling_tool/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js deleted file mode 100644 index 7b0e4ab47c..0000000000 --- a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - - -frappe.ui.form.on('Course Scheduling Tool', { - setup(frm) { - frm.add_fetch('student_group', 'program', 'program'); - frm.add_fetch('student_group', 'course', 'course'); - frm.add_fetch('student_group', 'academic_year', 'academic_year'); - frm.add_fetch('student_group', 'academic_term', 'academic_term'); - }, - refresh(frm) { - frm.disable_save(); - frm.page.set_primary_action(__('Schedule Course'), () => { - frm.call('schedule_course') - .then(r => { - if (!r.message) { - frappe.throw(__('There were errors creating Course Schedule')); - } - const { course_schedules } = r.message; - if (course_schedules) { - const course_schedules_html = course_schedules.map(c => ` - - ${c.name} - ${c.schedule_date} - - `).join(''); - - const html = ` - - - - - ${course_schedules_html} - -
${__('Following course schedules were created')}
${__("Course")}${__("Date")}
- `; - - frappe.msgprint(html); - } - }); - }); - } -}); diff --git a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.json b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.json deleted file mode 100644 index 13dfe38eea..0000000000 --- a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.json +++ /dev/null @@ -1,168 +0,0 @@ -{ - "actions": [], - "allow_copy": 1, - "creation": "2015-09-23 15:37:38.108475", - "doctype": "DocType", - "document_type": "Setup", - "engine": "InnoDB", - "field_order": [ - "student_group", - "course", - "program", - "column_break_3", - "academic_year", - "academic_term", - "section_break_6", - "instructor", - "instructor_name", - "column_break_9", - "room", - "section_break_7", - "course_start_date", - "course_end_date", - "day", - "reschedule", - "column_break_15", - "from_time", - "to_time" - ], - "fields": [ - { - "fieldname": "student_group", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Student Group", - "options": "Student Group", - "reqd": 1 - }, - { - "fieldname": "course", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Course", - "options": "Course", - "reqd": 1 - }, - { - "fieldname": "program", - "fieldtype": "Link", - "label": "Program", - "options": "Program", - "read_only": 1 - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fieldname": "academic_year", - "fieldtype": "Link", - "label": "Academic Year", - "options": "Academic Year", - "read_only": 1 - }, - { - "fieldname": "academic_term", - "fieldtype": "Link", - "label": "Academic Term", - "options": "Academic Term", - "read_only": 1 - }, - { - "fieldname": "section_break_6", - "fieldtype": "Section Break" - }, - { - "fieldname": "instructor", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Instructor", - "options": "Instructor", - "reqd": 1 - }, - { - "fetch_from": "instructor.instructor_name", - "fieldname": "instructor_name", - "fieldtype": "Read Only", - "label": "Instructor Name", - "read_only": 1 - }, - { - "fieldname": "column_break_9", - "fieldtype": "Column Break" - }, - { - "fieldname": "room", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Room", - "options": "Room", - "reqd": 1 - }, - { - "fieldname": "section_break_7", - "fieldtype": "Section Break" - }, - { - "fieldname": "from_time", - "fieldtype": "Time", - "label": "From Time", - "reqd": 1 - }, - { - "fieldname": "course_start_date", - "fieldtype": "Date", - "label": "Course Start Date", - "reqd": 1 - }, - { - "fieldname": "day", - "fieldtype": "Select", - "label": "Day", - "options": "\nMonday\nTuesday\nWednesday\nThursday\nFriday\nSaturday\nSunday", - "reqd": 1 - }, - { - "default": "0", - "fieldname": "reschedule", - "fieldtype": "Check", - "label": "Reschedule" - }, - { - "fieldname": "column_break_15", - "fieldtype": "Column Break" - }, - { - "fieldname": "to_time", - "fieldtype": "Time", - "label": "To TIme", - "reqd": 1 - }, - { - "fieldname": "course_end_date", - "fieldtype": "Date", - "label": "Course End Date", - "reqd": 1 - } - ], - "hide_toolbar": 1, - "issingle": 1, - "links": [], - "modified": "2021-11-11 09:33:18.874445", - "modified_by": "Administrator", - "module": "Education", - "name": "Course Scheduling Tool", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "read": 1, - "role": "Academics User", - "write": 1 - } - ], - "restrict_to_domain": "Education", - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.py b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.py deleted file mode 100644 index b3072c20b6..0000000000 --- a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.py +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import calendar - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.utils import add_days, getdate - -from erpnext.education.utils import OverlapError - - -class CourseSchedulingTool(Document): - @frappe.whitelist() - def schedule_course(self): - """Creates course schedules as per specified parameters""" - - course_schedules = [] - course_schedules_errors = [] - rescheduled = [] - reschedule_errors = [] - - self.validate_mandatory() - self.validate_date() - self.instructor_name = frappe.db.get_value("Instructor", self.instructor, "instructor_name") - - group_based_on, course = frappe.db.get_value( - "Student Group", self.student_group, ["group_based_on", "course"] - ) - - if group_based_on == "Course": - self.course = course - - if self.reschedule: - rescheduled, reschedule_errors = self.delete_course_schedule(rescheduled, reschedule_errors) - - date = self.course_start_date - while date < self.course_end_date: - if self.day == calendar.day_name[getdate(date).weekday()]: - course_schedule = self.make_course_schedule(date) - try: - course_schedule.save() - except OverlapError: - course_schedules_errors.append(date) - else: - course_schedules.append(course_schedule) - - date = add_days(date, 7) - else: - date = add_days(date, 1) - - return dict( - course_schedules=course_schedules, - course_schedules_errors=course_schedules_errors, - rescheduled=rescheduled, - reschedule_errors=reschedule_errors, - ) - - def validate_mandatory(self): - """Validates all mandatory fields""" - - fields = [ - "course", - "room", - "instructor", - "from_time", - "to_time", - "course_start_date", - "course_end_date", - "day", - ] - for d in fields: - if not self.get(d): - frappe.throw(_("{0} is mandatory").format(self.meta.get_label(d))) - - def validate_date(self): - """Validates if Course Start Date is greater than Course End Date""" - if self.course_start_date > self.course_end_date: - frappe.throw(_("Course Start Date cannot be greater than Course End Date.")) - - def delete_course_schedule(self, rescheduled, reschedule_errors): - """Delete all course schedule within the Date range and specified filters""" - - schedules = frappe.get_list( - "Course Schedule", - fields=["name", "schedule_date"], - filters=[ - ["student_group", "=", self.student_group], - ["course", "=", self.course], - ["schedule_date", ">=", self.course_start_date], - ["schedule_date", "<=", self.course_end_date], - ], - ) - - for d in schedules: - try: - if self.day == calendar.day_name[getdate(d.schedule_date).weekday()]: - frappe.delete_doc("Course Schedule", d.name) - rescheduled.append(d.name) - except Exception: - reschedule_errors.append(d.name) - return rescheduled, reschedule_errors - - def make_course_schedule(self, date): - """Makes a new Course Schedule. - :param date: Date on which Course Schedule will be created.""" - - course_schedule = frappe.new_doc("Course Schedule") - course_schedule.student_group = self.student_group - course_schedule.course = self.course - course_schedule.instructor = self.instructor - course_schedule.instructor_name = self.instructor_name - course_schedule.room = self.room - course_schedule.schedule_date = date - course_schedule.from_time = self.from_time - course_schedule.to_time = self.to_time - return course_schedule diff --git a/erpnext/education/doctype/course_scheduling_tool/test_course_scheduling_tool.py b/erpnext/education/doctype/course_scheduling_tool/test_course_scheduling_tool.py deleted file mode 100644 index 559214bc92..0000000000 --- a/erpnext/education/doctype/course_scheduling_tool/test_course_scheduling_tool.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestCourseSchedulingTool(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/course_topic/__init__.py b/erpnext/education/doctype/course_topic/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/course_topic/course_topic.js b/erpnext/education/doctype/course_topic/course_topic.js deleted file mode 100644 index 7d03ba32ff..0000000000 --- a/erpnext/education/doctype/course_topic/course_topic.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Course Topic', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/course_topic/course_topic.json b/erpnext/education/doctype/course_topic/course_topic.json deleted file mode 100644 index 3fcddc169e..0000000000 --- a/erpnext/education/doctype/course_topic/course_topic.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-12-12 11:51:25.952740", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "topic", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Topic", - "length": 0, - "no_copy": 0, - "options": "Topic", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "topic.topic_name", - "fieldname": "topic_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Topic Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-12-12 13:01:58.960425", - "modified_by": "Administrator", - "module": "Education", - "name": "Course Topic", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/course_topic/course_topic.py b/erpnext/education/doctype/course_topic/course_topic.py deleted file mode 100644 index 3c1cabf795..0000000000 --- a/erpnext/education/doctype/course_topic/course_topic.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class CourseTopic(Document): - pass diff --git a/erpnext/education/doctype/course_topic/test_course_topic.py b/erpnext/education/doctype/course_topic/test_course_topic.py deleted file mode 100644 index a4d370c83d..0000000000 --- a/erpnext/education/doctype/course_topic/test_course_topic.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestCourseTopic(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/education_settings/__init__.py b/erpnext/education/doctype/education_settings/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/education_settings/education_settings.js b/erpnext/education/doctype/education_settings/education_settings.js deleted file mode 100644 index 764d8b4a7f..0000000000 --- a/erpnext/education/doctype/education_settings/education_settings.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Education Settings', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/education_settings/education_settings.json b/erpnext/education/doctype/education_settings/education_settings.json deleted file mode 100644 index 0e548dbf77..0000000000 --- a/erpnext/education/doctype/education_settings/education_settings.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "actions": [], - "creation": "2017-04-05 13:33:04.519313", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "current_academic_year", - "current_academic_term", - "attendance_freeze_date", - "column_break_4", - "validate_batch", - "validate_course", - "academic_term_reqd", - "user_creation_skip", - "section_break_7", - "instructor_created_by", - "web_academy_settings_section", - "enable_lms", - "portal_title", - "description" - ], - "fields": [ - { - "fieldname": "current_academic_year", - "fieldtype": "Link", - "label": "Current Academic Year", - "options": "Academic Year" - }, - { - "fieldname": "current_academic_term", - "fieldtype": "Link", - "label": "Current Academic Term", - "options": "Academic Term" - }, - { - "fieldname": "attendance_freeze_date", - "fieldtype": "Date", - "label": "Attendance Freeze Date" - }, - { - "fieldname": "column_break_4", - "fieldtype": "Column Break" - }, - { - "default": "0", - "description": "For Batch based Student Group, the Student Batch will be validated for every Student from the Program Enrollment.", - "fieldname": "validate_batch", - "fieldtype": "Check", - "label": "Validate Batch for Students in Student Group" - }, - { - "default": "0", - "description": "For Course based Student Group, the Course will be validated for every Student from the enrolled Courses in Program Enrollment.", - "fieldname": "validate_course", - "fieldtype": "Check", - "label": "Validate Enrolled Course for Students in Student Group" - }, - { - "default": "0", - "description": "If enabled, field Academic Term will be Mandatory in Program Enrollment Tool.", - "fieldname": "academic_term_reqd", - "fieldtype": "Check", - "label": "Make Academic Term Mandatory" - }, - { - "fieldname": "section_break_7", - "fieldtype": "Section Break" - }, - { - "default": "Full Name", - "fieldname": "instructor_created_by", - "fieldtype": "Select", - "label": "Instructor Records to be created by", - "options": "Full Name\nNaming Series\nEmployee Number" - }, - { - "fieldname": "web_academy_settings_section", - "fieldtype": "Section Break", - "label": "Learning Management System Settings" - }, - { - "depends_on": "eval: doc.enable_lms", - "fieldname": "portal_title", - "fieldtype": "Data", - "label": "Learning Management System Title" - }, - { - "depends_on": "eval: doc.enable_lms", - "fieldname": "description", - "fieldtype": "Small Text", - "label": "Description" - }, - { - "default": "0", - "fieldname": "enable_lms", - "fieldtype": "Check", - "label": "Enable Learning Management System" - }, - { - "default": "0", - "description": "By default, a new User is created for every new Student. If enabled, no new User will be created when a new Student is created.", - "fieldname": "user_creation_skip", - "fieldtype": "Check", - "label": "Skip User creation for new Student" - } - ], - "issingle": 1, - "links": [], - "modified": "2020-05-07 19:18:10.639356", - "modified_by": "Administrator", - "module": "Education", - "name": "Education Settings", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "print": 1, - "read": 1, - "role": "System Manager", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "print": 1, - "read": 1, - "role": "Education Manager", - "share": 1, - "write": 1 - }, - { - "email": 1, - "print": 1, - "read": 1, - "role": "Guest", - "share": 1 - } - ], - "quick_entry": 1, - "restrict_to_domain": "Education", - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/education/doctype/education_settings/education_settings.py b/erpnext/education/doctype/education_settings/education_settings.py deleted file mode 100644 index 295aa3a4cb..0000000000 --- a/erpnext/education/doctype/education_settings/education_settings.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -import frappe.defaults -from frappe.model.document import Document - -education_keydict = { - # "key in defaults": "key in Global Defaults" - "academic_year": "current_academic_year", - "academic_term": "current_academic_term", - "validate_batch": "validate_batch", - "validate_course": "validate_course", -} - - -class EducationSettings(Document): - def on_update(self): - """update defaults""" - for key in education_keydict: - frappe.db.set_default(key, self.get(education_keydict[key], "")) - - # clear cache - frappe.clear_cache() - - def get_defaults(self): - return frappe.defaults.get_defaults() - - def validate(self): - from frappe.custom.doctype.property_setter.property_setter import make_property_setter - - if self.get("instructor_created_by") == "Naming Series": - make_property_setter( - "Instructor", "naming_series", "hidden", 0, "Check", validate_fields_for_doctype=False - ) - else: - make_property_setter( - "Instructor", "naming_series", "hidden", 1, "Check", validate_fields_for_doctype=False - ) - - -def update_website_context(context): - context["lms_enabled"] = frappe.get_cached_doc("Education Settings").enable_lms diff --git a/erpnext/education/doctype/education_settings/test_education_settings.py b/erpnext/education/doctype/education_settings/test_education_settings.py deleted file mode 100644 index 223e8386b3..0000000000 --- a/erpnext/education/doctype/education_settings/test_education_settings.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestEducationSettings(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/fee_category/__init__.py b/erpnext/education/doctype/fee_category/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/fee_category/fee_category.js b/erpnext/education/doctype/fee_category/fee_category.js deleted file mode 100644 index 96fd9158c7..0000000000 --- a/erpnext/education/doctype/fee_category/fee_category.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Fee Category', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/fee_category/fee_category.json b/erpnext/education/doctype/fee_category/fee_category.json deleted file mode 100644 index c1bfa8e836..0000000000 --- a/erpnext/education/doctype/fee_category/fee_category.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:category_name", - "beta": 0, - "creation": "2015-09-16 13:01:10.448734", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 0, - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "category_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Name", - "length": 0, - "no_copy": 0, - "oldfieldname": "earning_name", - "oldfieldtype": "Data", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "description", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Description", - "length": 0, - "no_copy": 0, - "oldfieldname": "description", - "oldfieldtype": "Small Text", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0, - "width": "300px" - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "icon": "fa fa-flag", - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "menu_index": 0, - "modified": "2017-11-10 18:56:33.824534", - "modified_by": "Administrator", - "module": "Education", - "name": "Fee Category", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - }, - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - }, - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "search_fields": "description", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/fee_category/fee_category.py b/erpnext/education/doctype/fee_category/fee_category.py deleted file mode 100644 index 1faa0c5e95..0000000000 --- a/erpnext/education/doctype/fee_category/fee_category.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class FeeCategory(Document): - pass diff --git a/erpnext/education/doctype/fee_category/test_fee_category.py b/erpnext/education/doctype/fee_category/test_fee_category.py deleted file mode 100644 index 93565a9f92..0000000000 --- a/erpnext/education/doctype/fee_category/test_fee_category.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Fee Category') - - -class TestFeeCategory(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/fee_category/test_records.json b/erpnext/education/doctype/fee_category/test_records.json deleted file mode 100644 index 598c1ed75b..0000000000 --- a/erpnext/education/doctype/fee_category/test_records.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - { - "category_name": "Admission Fee" - }, - { - "category_name": "Tuition Fee" - }, - { - "category_name": "Transportation Fee" - } -] \ No newline at end of file diff --git a/erpnext/education/doctype/fee_component/__init__.py b/erpnext/education/doctype/fee_component/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/fee_component/fee_component.json b/erpnext/education/doctype/fee_component/fee_component.json deleted file mode 100644 index f6e13c48b2..0000000000 --- a/erpnext/education/doctype/fee_component/fee_component.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 1, - "autoname": "", - "beta": 0, - "creation": "2015-09-16 13:07:27.675453", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 1, - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "fees_category", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Fees Category", - "length": 0, - "no_copy": 0, - "oldfieldname": "earning_name", - "oldfieldtype": "Data", - "options": "Fee Category", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "description", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Description", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_2", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Amount", - "length": 0, - "no_copy": 0, - "oldfieldname": "description", - "oldfieldtype": "Small Text", - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0, - "width": "300px" - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "icon": "fa fa-flag", - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2017-11-10 18:58:10.254407", - "modified_by": "Administrator", - "module": "Education", - "name": "Fee Component", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/fee_component/fee_component.py b/erpnext/education/doctype/fee_component/fee_component.py deleted file mode 100644 index c5cf7d9331..0000000000 --- a/erpnext/education/doctype/fee_component/fee_component.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class FeeComponent(Document): - pass diff --git a/erpnext/education/doctype/fee_schedule/__init__.py b/erpnext/education/doctype/fee_schedule/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.js b/erpnext/education/doctype/fee_schedule/fee_schedule.js deleted file mode 100644 index 97691a5b62..0000000000 --- a/erpnext/education/doctype/fee_schedule/fee_schedule.js +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.provide("erpnext.accounts.dimensions"); -frappe.ui.form.on('Fee Schedule', { - setup: function(frm) { - frm.add_fetch('fee_structure', 'receivable_account', 'receivable_account'); - frm.add_fetch('fee_structure', 'income_account', 'income_account'); - frm.add_fetch('fee_structure', 'cost_center', 'cost_center'); - }, - - company: function(frm) { - erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); - }, - - onload: function(frm) { - frm.set_query('receivable_account', function(doc) { - return { - filters: { - 'account_type': 'Receivable', - 'is_group': 0, - 'company': doc.company - } - }; - }); - - frm.set_query('income_account', function(doc) { - return { - filters: { - 'account_type': 'Income Account', - 'is_group': 0, - 'company': doc.company - } - }; - }); - - frm.set_query('student_group', 'student_groups', function() { - return { - 'program': frm.doc.program, - 'academic_term': frm.doc.academic_term, - 'academic_year': frm.doc.academic_year, - 'disabled': 0 - }; - }); - - frappe.realtime.on('fee_schedule_progress', function(data) { - if (data.reload && data.reload === 1) { - frm.reload_doc(); - } - if (data.progress) { - let progress_bar = $(cur_frm.dashboard.progress_area.body).find('.progress-bar'); - if (progress_bar) { - $(progress_bar).removeClass('progress-bar-danger').addClass('progress-bar-success progress-bar-striped'); - $(progress_bar).css('width', data.progress+'%'); - } - } - }); - - erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); - }, - - refresh: function(frm) { - if (!frm.doc.__islocal && frm.doc.__onload && frm.doc.__onload.dashboard_info && - frm.doc.fee_creation_status === 'Successful') { - var info = frm.doc.__onload.dashboard_info; - frm.dashboard.add_indicator(__('Total Collected: {0}', [format_currency(info.total_paid, - info.currency)]), 'blue'); - frm.dashboard.add_indicator(__('Total Outstanding: {0}', [format_currency(info.total_unpaid, - info.currency)]), info.total_unpaid ? 'orange' : 'green'); - } - if (frm.doc.fee_creation_status === 'In Process') { - frm.dashboard.add_progress('Fee Creation Status', '0'); - } - if (frm.doc.docstatus === 1 && !frm.doc.fee_creation_status || frm.doc.fee_creation_status === 'Failed') { - frm.add_custom_button(__('Create Fees'), function() { - frappe.call({ - method: 'create_fees', - doc: frm.doc, - callback: function() { - frm.refresh(); - } - }); - }).addClass('btn-primary');; - } - if (frm.doc.fee_creation_status === 'Successful') { - frm.add_custom_button(__('View Fees Records'), function() { - frappe.route_options = { - fee_schedule: frm.doc.name - }; - frappe.set_route('List', 'Fees'); - }); - } - - }, - - fee_structure: function(frm) { - if (frm.doc.fee_structure) { - frappe.call({ - method: 'erpnext.education.doctype.fee_schedule.fee_schedule.get_fee_structure', - args: { - 'target_doc': frm.doc.name, - 'source_name': frm.doc.fee_structure - }, - callback: function(r) { - var doc = frappe.model.sync(r.message); - frappe.set_route('Form', doc[0].doctype, doc[0].name); - } - }); - } - } -}); - -frappe.ui.form.on('Fee Schedule Student Group', { - student_group: function(frm, cdt, cdn) { - var row = locals[cdt][cdn]; - if (row.student_group && frm.doc.academic_year) { - frappe.call({ - method: 'erpnext.education.doctype.fee_schedule.fee_schedule.get_total_students', - args: { - 'student_group': row.student_group, - 'academic_year': frm.doc.academic_year, - 'academic_term': frm.doc.academic_term, - 'student_category': frm.doc.student_category - }, - callback: function(r) { - if (!r.exc) { - frappe.model.set_value(cdt, cdn, 'total_students', r.message); - } - } - }); - } - } -}) diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.json b/erpnext/education/doctype/fee_schedule/fee_schedule.json deleted file mode 100644 index 23b3212db2..0000000000 --- a/erpnext/education/doctype/fee_schedule/fee_schedule.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "actions": [], - "allow_import": 1, - "autoname": "naming_series:", - "creation": "2017-07-18 15:21:21.527136", - "doctype": "DocType", - "document_type": "Document", - "engine": "InnoDB", - "field_order": [ - "fee_structure", - "posting_date", - "due_date", - "naming_series", - "fee_creation_status", - "send_email", - "column_break_4", - "student_category", - "program", - "academic_year", - "academic_term", - "section_break_10", - "currency", - "student_groups", - "section_break_14", - "components", - "section_break_16", - "column_break_18", - "total_amount", - "grand_total", - "grand_total_in_words", - "edit_printing_settings", - "letter_head", - "column_break_32", - "select_print_heading", - "account", - "receivable_account", - "income_account", - "column_break_39", - "company", - "amended_from", - "accounting_dimensions_section", - "cost_center", - "dimension_col_break", - "section_break_31", - "error_log" - ], - "fields": [ - { - "fieldname": "fee_structure", - "fieldtype": "Link", - "in_global_search": 1, - "in_list_view": 1, - "label": "Fee Structure", - "options": "Fee Structure", - "reqd": 1 - }, - { - "fieldname": "due_date", - "fieldtype": "Date", - "label": "Due Date", - "reqd": 1 - }, - { - "fieldname": "naming_series", - "fieldtype": "Select", - "label": "Naming Series", - "no_copy": 1, - "options": "EDU-FSH-.YYYY.-" - }, - { - "fieldname": "fee_creation_status", - "fieldtype": "Select", - "label": "Fee Creation Status", - "no_copy": 1, - "options": "\nIn Process\nFailed\nSuccessful", - "print_hide": 1, - "read_only": 1 - }, - { - "default": "0", - "fieldname": "send_email", - "fieldtype": "Check", - "label": "Send Payment Request Email" - }, - { - "fieldname": "column_break_4", - "fieldtype": "Column Break" - }, - { - "fieldname": "student_category", - "fieldtype": "Link", - "label": "Student Category", - "options": "Student Category", - "read_only": 1 - }, - { - "fieldname": "program", - "fieldtype": "Link", - "label": "Program", - "options": "Program", - "read_only": 1 - }, - { - "fieldname": "academic_year", - "fieldtype": "Link", - "label": "Academic Year", - "options": "Academic Year", - "reqd": 1 - }, - { - "fieldname": "academic_term", - "fieldtype": "Link", - "label": "Academic Term", - "options": "Academic Term" - }, - { - "fieldname": "section_break_10", - "fieldtype": "Section Break" - }, - { - "fieldname": "currency", - "fieldtype": "Link", - "hidden": 1, - "label": "Currency", - "options": "Currency", - "read_only": 1 - }, - { - "fieldname": "student_groups", - "fieldtype": "Table", - "options": "Fee Schedule Student Group", - "reqd": 1 - }, - { - "fieldname": "section_break_14", - "fieldtype": "Section Break", - "label": "Fee Breakup for each student", - "read_only": 1 - }, - { - "fieldname": "components", - "fieldtype": "Table", - "options": "Fee Component", - "read_only": 1 - }, - { - "fieldname": "section_break_16", - "fieldtype": "Section Break" - }, - { - "fieldname": "column_break_18", - "fieldtype": "Column Break" - }, - { - "default": "0", - "fieldname": "total_amount", - "fieldtype": "Currency", - "label": "Total Amount per Student", - "read_only": 1 - }, - { - "fieldname": "grand_total", - "fieldtype": "Currency", - "label": "Grand Total", - "read_only": 1 - }, - { - "fieldname": "grand_total_in_words", - "fieldtype": "Data", - "label": "In Words", - "length": 240, - "read_only": 1 - }, - { - "collapsible": 1, - "fieldname": "edit_printing_settings", - "fieldtype": "Section Break", - "label": "Printing Settings" - }, - { - "allow_on_submit": 1, - "fieldname": "letter_head", - "fieldtype": "Link", - "label": "Letter Head", - "options": "Letter Head", - "print_hide": 1 - }, - { - "fieldname": "column_break_32", - "fieldtype": "Column Break" - }, - { - "allow_on_submit": 1, - "fieldname": "select_print_heading", - "fieldtype": "Link", - "label": "Print Heading", - "no_copy": 1, - "options": "Print Heading", - "print_hide": 1, - "report_hide": 1 - }, - { - "collapsible": 1, - "fieldname": "account", - "fieldtype": "Section Break", - "label": "Accounting" - }, - { - "fieldname": "receivable_account", - "fieldtype": "Link", - "label": "Receivable Account", - "options": "Account" - }, - { - "fieldname": "income_account", - "fieldtype": "Link", - "label": "Income Account", - "options": "Account" - }, - { - "fieldname": "column_break_39", - "fieldtype": "Column Break" - }, - { - "fieldname": "cost_center", - "fieldtype": "Link", - "label": "Cost Center", - "options": "Cost Center" - }, - { - "fieldname": "company", - "fieldtype": "Link", - "label": "Institution", - "options": "Company" - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Fee Schedule", - "print_hide": 1, - "read_only": 1 - }, - { - "collapsible": 1, - "depends_on": "error_log", - "fieldname": "section_break_31", - "fieldtype": "Section Break", - "label": "Error Log" - }, - { - "fieldname": "error_log", - "fieldtype": "Read Only", - "label": "Error Log" - }, - { - "fieldname": "accounting_dimensions_section", - "fieldtype": "Section Break", - "label": "Accounting Dimensions" - }, - { - "fieldname": "dimension_col_break", - "fieldtype": "Column Break" - }, - { - "default": "Today", - "fieldname": "posting_date", - "fieldtype": "Date", - "label": "Posting Date", - "reqd": 1 - } - ], - "is_submittable": 1, - "links": [], - "modified": "2020-07-18 05:11:49.905457", - "modified_by": "Administrator", - "module": "Education", - "name": "Fee Schedule", - "owner": "Administrator", - "permissions": [ - { - "amend": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "import": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts User", - "share": 1, - "submit": 1, - "write": 1 - }, - { - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts Manager", - "share": 1, - "submit": 1, - "write": 1 - } - ], - "restrict_to_domain": "Education", - "sort_field": "modified", - "sort_order": "DESC" -} \ No newline at end of file diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.py b/erpnext/education/doctype/fee_schedule/fee_schedule.py deleted file mode 100644 index 9ae5582f21..0000000000 --- a/erpnext/education/doctype/fee_schedule/fee_schedule.py +++ /dev/null @@ -1,173 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.model.mapper import get_mapped_doc -from frappe.utils import cint, cstr, flt, money_in_words -from frappe.utils.background_jobs import enqueue - -import erpnext - - -class FeeSchedule(Document): - def onload(self): - info = self.get_dashboard_info() - self.set_onload("dashboard_info", info) - - def get_dashboard_info(self): - info = { - "total_paid": 0, - "total_unpaid": 0, - "currency": erpnext.get_company_currency(self.company), - } - - fees_amount = frappe.db.sql( - """select sum(grand_total), sum(outstanding_amount) from tabFees - where fee_schedule=%s and docstatus=1""", - (self.name), - ) - - if fees_amount: - info["total_paid"] = flt(fees_amount[0][0]) - flt(fees_amount[0][1]) - info["total_unpaid"] = flt(fees_amount[0][1]) - - return info - - def validate(self): - self.calculate_total_and_program() - - def calculate_total_and_program(self): - no_of_students = 0 - for d in self.student_groups: - # if not d.total_students: - d.total_students = get_total_students( - d.student_group, self.academic_year, self.academic_term, self.student_category - ) - no_of_students += cint(d.total_students) - - # validate the program of fee structure and student groups - student_group_program = frappe.db.get_value("Student Group", d.student_group, "program") - if self.program and student_group_program and self.program != student_group_program: - frappe.msgprint( - _("Program in the Fee Structure and Student Group {0} are different.").format(d.student_group) - ) - self.grand_total = no_of_students * self.total_amount - self.grand_total_in_words = money_in_words(self.grand_total) - - @frappe.whitelist() - def create_fees(self): - self.db_set("fee_creation_status", "In Process") - frappe.publish_realtime( - "fee_schedule_progress", {"progress": "0", "reload": 1}, user=frappe.session.user - ) - - total_records = sum([int(d.total_students) for d in self.student_groups]) - if total_records > 10: - frappe.msgprint( - _( - """Fee records will be created in the background. - In case of any error the error message will be updated in the Schedule.""" - ) - ) - enqueue( - generate_fee, queue="default", timeout=6000, event="generate_fee", fee_schedule=self.name - ) - else: - generate_fee(self.name) - - -def generate_fee(fee_schedule): - doc = frappe.get_doc("Fee Schedule", fee_schedule) - error = False - total_records = sum([int(d.total_students) for d in doc.student_groups]) - created_records = 0 - - if not total_records: - frappe.throw(_("Please setup Students under Student Groups")) - - for d in doc.student_groups: - students = get_students( - d.student_group, doc.academic_year, doc.academic_term, doc.student_category - ) - for student in students: - try: - fees_doc = get_mapped_doc( - "Fee Schedule", - fee_schedule, - {"Fee Schedule": {"doctype": "Fees", "field_map": {"name": "Fee Schedule"}}}, - ) - fees_doc.posting_date = doc.posting_date - fees_doc.student = student.student - fees_doc.student_name = student.student_name - fees_doc.program = student.program - fees_doc.student_batch = student.student_batch_name - fees_doc.send_payment_request = doc.send_email - fees_doc.save() - fees_doc.submit() - created_records += 1 - frappe.publish_realtime( - "fee_schedule_progress", - {"progress": str(int(created_records * 100 / total_records))}, - user=frappe.session.user, - ) - - except Exception as e: - error = True - err_msg = frappe.local.message_log and "\n\n".join(frappe.local.message_log) or cstr(e) - - if error: - frappe.db.rollback() - frappe.db.set_value("Fee Schedule", fee_schedule, "fee_creation_status", "Failed") - frappe.db.set_value("Fee Schedule", fee_schedule, "error_log", err_msg) - - else: - frappe.db.set_value("Fee Schedule", fee_schedule, "fee_creation_status", "Successful") - frappe.db.set_value("Fee Schedule", fee_schedule, "error_log", None) - - frappe.publish_realtime( - "fee_schedule_progress", {"progress": "100", "reload": 1}, user=frappe.session.user - ) - - -def get_students(student_group, academic_year, academic_term=None, student_category=None): - conditions = "" - if student_category: - conditions = " and pe.student_category={}".format(frappe.db.escape(student_category)) - if academic_term: - conditions = " and pe.academic_term={}".format(frappe.db.escape(academic_term)) - - students = frappe.db.sql( - """ - select pe.student, pe.student_name, pe.program, pe.student_batch_name - from `tabStudent Group Student` sgs, `tabProgram Enrollment` pe - where - pe.student = sgs.student and pe.academic_year = %s - and sgs.parent = %s and sgs.active = 1 - {conditions} - """.format( - conditions=conditions - ), - (academic_year, student_group), - as_dict=1, - ) - return students - - -@frappe.whitelist() -def get_total_students(student_group, academic_year, academic_term=None, student_category=None): - total_students = get_students(student_group, academic_year, academic_term, student_category) - return len(total_students) - - -@frappe.whitelist() -def get_fee_structure(source_name, target_doc=None): - fee_request = get_mapped_doc( - "Fee Structure", - source_name, - {"Fee Structure": {"doctype": "Fee Schedule"}}, - ignore_permissions=True, - ) - return fee_request diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule_dashboard.py b/erpnext/education/doctype/fee_schedule/fee_schedule_dashboard.py deleted file mode 100644 index 4b99d27f29..0000000000 --- a/erpnext/education/doctype/fee_schedule/fee_schedule_dashboard.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - - -def get_data(): - return {"fieldname": "fee_schedule", "transactions": [{"items": ["Fees"]}]} diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule_list.js b/erpnext/education/doctype/fee_schedule/fee_schedule_list.js deleted file mode 100644 index 3039c51d78..0000000000 --- a/erpnext/education/doctype/fee_schedule/fee_schedule_list.js +++ /dev/null @@ -1,14 +0,0 @@ -frappe.listview_settings['Fee Schedule'] = { - add_fields: ["fee_creation_status", "due_date", "grand_total"], - get_indicator: function(doc) { - if (doc.fee_creation_status=="Successful") { - return [__("Fee Created"), "blue", "fee_creation_status,=,Successful"]; - } else if(doc.fee_creation_status == "In Process") { - return [__("Creating Fees"), "orange", "fee_creation_status,=,In Process"]; - } else if(doc.fee_creation_status == "Failed") { - return [__("Fee Creation Failed"), "red", "fee_creation_status,=,Failed"]; - } else { - return [__("Fee Creation Pending"), "green", "fee_creation_status,=,"]; - } - } -}; diff --git a/erpnext/education/doctype/fee_schedule/test_fee_schedule.py b/erpnext/education/doctype/fee_schedule/test_fee_schedule.py deleted file mode 100644 index c291aed310..0000000000 --- a/erpnext/education/doctype/fee_schedule/test_fee_schedule.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestFeeSchedule(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/fee_schedule_program/__init__.py b/erpnext/education/doctype/fee_schedule_program/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/fee_schedule_program/fee_schedule_program.json b/erpnext/education/doctype/fee_schedule_program/fee_schedule_program.json deleted file mode 100644 index f644dc21fb..0000000000 --- a/erpnext/education/doctype/fee_schedule_program/fee_schedule_program.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2017-03-23 17:46:55.712169", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "program", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Program", - "length": 0, - "no_copy": 0, - "options": "Program", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student_batch", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Student Batch", - "length": 0, - "no_copy": 0, - "options": "Student Batch Name", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "total_students", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Total Students", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-11-04 03:37:57.763134", - "modified_by": "Administrator", - "module": "Education", - "name": "Fee Schedule Program", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/fee_schedule_program/fee_schedule_program.py b/erpnext/education/doctype/fee_schedule_program/fee_schedule_program.py deleted file mode 100644 index ad7af3a3ab..0000000000 --- a/erpnext/education/doctype/fee_schedule_program/fee_schedule_program.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class FeeScheduleProgram(Document): - pass diff --git a/erpnext/education/doctype/fee_schedule_student_group/__init__.py b/erpnext/education/doctype/fee_schedule_student_group/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/fee_schedule_student_group/fee_schedule_student_group.json b/erpnext/education/doctype/fee_schedule_student_group/fee_schedule_student_group.json deleted file mode 100644 index d4e0acbce0..0000000000 --- a/erpnext/education/doctype/fee_schedule_student_group/fee_schedule_student_group.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2017-03-23 17:55:52.476822", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student_group", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Student Group", - "length": 0, - "no_copy": 0, - "options": "Student Group", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "total_students", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Total Students", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-11-04 03:38:06.535706", - "modified_by": "Administrator", - "module": "Education", - "name": "Fee Schedule Student Group", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/fee_schedule_student_group/fee_schedule_student_group.py b/erpnext/education/doctype/fee_schedule_student_group/fee_schedule_student_group.py deleted file mode 100644 index 24e5404177..0000000000 --- a/erpnext/education/doctype/fee_schedule_student_group/fee_schedule_student_group.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class FeeScheduleStudentGroup(Document): - pass diff --git a/erpnext/education/doctype/fee_structure/__init__.py b/erpnext/education/doctype/fee_structure/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/fee_structure/fee_structure.js b/erpnext/education/doctype/fee_structure/fee_structure.js deleted file mode 100644 index d9ab99f818..0000000000 --- a/erpnext/education/doctype/fee_structure/fee_structure.js +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.provide("erpnext.accounts.dimensions"); - -frappe.ui.form.on('Fee Structure', { - setup: function(frm) { - frm.add_fetch('company', 'default_receivable_account', 'receivable_account'); - frm.add_fetch('company', 'default_income_account', 'income_account'); - frm.add_fetch('company', 'cost_center', 'cost_center'); - }, - - company: function(frm) { - erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); - }, - - onload: function(frm) { - frm.set_query('academic_term', function() { - return { - 'filters': { - 'academic_year': frm.doc.academic_year - } - }; - }); - - frm.set_query('receivable_account', function(doc) { - return { - filters: { - 'account_type': 'Receivable', - 'is_group': 0, - 'company': doc.company - } - }; - }); - frm.set_query('income_account', function(doc) { - return { - filters: { - 'account_type': 'Income Account', - 'is_group': 0, - 'company': doc.company - } - }; - }); - - erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); - }, - - refresh: function(frm) { - if (frm.doc.docstatus === 1) { - frm.add_custom_button(__('Create Fee Schedule'), function() { - frm.events.make_fee_schedule(frm); - }).addClass('btn-primary'); - } - }, - - make_fee_schedule: function(frm) { - frappe.model.open_mapped_doc({ - method: 'erpnext.education.doctype.fee_structure.fee_structure.make_fee_schedule', - frm: frm - }); - } -}); - -frappe.ui.form.on('Fee Component', { - amount: function(frm) { - var total_amount = 0; - for (var i=0;i 0) { - frm.add_custom_button(__('Accounting Ledger'), function() { - frappe.route_options = { - voucher_no: frm.doc.name, - from_date: frm.doc.posting_date, - to_date: moment(frm.doc.modified).format('YYYY-MM-DD'), - company: frm.doc.company, - group_by: '', - show_cancelled_entries: frm.doc.docstatus === 2 - }; - frappe.set_route("query-report", "General Ledger"); - }, __("View")); - frm.add_custom_button(__("Payments"), function() { - frappe.set_route("List", "Payment Entry", {"Payment Entry Reference.reference_name": frm.doc.name}); - }, __("View")); - } - if(frm.doc.docstatus===1 && frm.doc.outstanding_amount>0) { - frm.add_custom_button(__("Payment Request"), function() { - frm.events.make_payment_request(frm); - }, __('Create')); - frm.page.set_inner_btn_group_as_primary(__('Create')); - } - if(frm.doc.docstatus===1 && frm.doc.outstanding_amount!=0) { - frm.add_custom_button(__("Payment"), function() { - frm.events.make_payment_entry(frm); - }, __('Create')); - frm.page.set_inner_btn_group_as_primary(__('Create')); - } - }, - - student: function(frm) { - if (frm.doc.student) { - frappe.call({ - method:"erpnext.education.api.get_current_enrollment", - args: { - "student": frm.doc.student, - "academic_year": frm.doc.academic_year - }, - callback: function(r) { - if(r){ - $.each(r.message, function(i, d) { - frm.set_value(i,d); - }); - } - } - }); - } - }, - - make_payment_request: function(frm) { - if (!frm.doc.student_email) { - frappe.msgprint(__("Please set the Email ID for the Student to send the Payment Request")); - } else { - frappe.call({ - method:"erpnext.accounts.doctype.payment_request.payment_request.make_payment_request", - args: { - "dt": frm.doc.doctype, - "dn": frm.doc.name, - "party_type": "Student", - "party": frm.doc.student, - "recipient_id": frm.doc.student_email - }, - callback: function(r) { - if(!r.exc){ - var doc = frappe.model.sync(r.message); - frappe.set_route("Form", doc[0].doctype, doc[0].name); - } - } - }); - } - }, - - make_payment_entry: function(frm) { - return frappe.call({ - method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry", - args: { - "dt": frm.doc.doctype, - "dn": frm.doc.name - }, - callback: function(r) { - var doc = frappe.model.sync(r.message); - frappe.set_route("Form", doc[0].doctype, doc[0].name); - } - }); - }, - - set_posting_time: function(frm) { - frm.refresh(); - }, - - academic_term: function() { - frappe.ui.form.trigger("Fees", "program"); - }, - - fee_structure: function(frm) { - frm.set_value("components" ,""); - if (frm.doc.fee_structure) { - frappe.call({ - method: "erpnext.education.api.get_fee_components", - args: { - "fee_structure": frm.doc.fee_structure - }, - callback: function(r) { - if (r.message) { - $.each(r.message, function(i, d) { - var row = frappe.model.add_child(frm.doc, "Fee Component", "components"); - row.fees_category = d.fees_category; - row.description = d.description; - row.amount = d.amount; - }); - } - refresh_field("components"); - frm.trigger("calculate_total_amount"); - } - }); - } - }, - - calculate_total_amount: function(frm) { - var grand_total = 0; - for(var i=0;i 0: - self.indicator_color = "orange" - self.indicator_title = _("Unpaid") - else: - self.indicator_color = "green" - self.indicator_title = _("Paid") - - def validate(self): - self.calculate_total() - self.set_missing_accounts_and_fields() - - def set_missing_accounts_and_fields(self): - if not self.company: - self.company = frappe.defaults.get_defaults().company - if not self.currency: - self.currency = erpnext.get_company_currency(self.company) - if not (self.receivable_account and self.income_account and self.cost_center): - accounts_details = frappe.get_all( - "Company", - fields=["default_receivable_account", "default_income_account", "cost_center"], - filters={"name": self.company}, - )[0] - if not self.receivable_account: - self.receivable_account = accounts_details.default_receivable_account - if not self.income_account: - self.income_account = accounts_details.default_income_account - if not self.cost_center: - self.cost_center = accounts_details.cost_center - if not self.student_email: - self.student_email = self.get_student_emails() - - def get_student_emails(self): - student_emails = frappe.db.sql_list( - """ - select g.email_address - from `tabGuardian` g, `tabStudent Guardian` sg - where g.name = sg.guardian and sg.parent = %s and sg.parenttype = 'Student' - and ifnull(g.email_address, '')!='' - """, - self.student, - ) - - student_email_id = frappe.db.get_value("Student", self.student, "student_email_id") - if student_email_id: - student_emails.append(student_email_id) - if student_emails: - return ", ".join(list(set(student_emails))) - else: - return None - - def calculate_total(self): - """Calculates total amount.""" - self.grand_total = 0 - for d in self.components: - self.grand_total += d.amount - self.outstanding_amount = self.grand_total - self.grand_total_in_words = money_in_words(self.grand_total) - - def on_submit(self): - - self.make_gl_entries() - - if self.send_payment_request and self.student_email: - pr = make_payment_request( - party_type="Student", - party=self.student, - dt="Fees", - dn=self.name, - recipient_id=self.student_email, - submit_doc=True, - use_dummy_message=True, - ) - frappe.msgprint(_("Payment request {0} created").format(getlink("Payment Request", pr.name))) - - def on_cancel(self): - self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry") - make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name) - # frappe.db.set(self, 'status', 'Cancelled') - - def make_gl_entries(self): - if not self.grand_total: - return - student_gl_entries = self.get_gl_dict( - { - "account": self.receivable_account, - "party_type": "Student", - "party": self.student, - "against": self.income_account, - "debit": self.grand_total, - "debit_in_account_currency": self.grand_total, - "against_voucher": self.name, - "against_voucher_type": self.doctype, - }, - item=self, - ) - - fee_gl_entry = self.get_gl_dict( - { - "account": self.income_account, - "against": self.student, - "credit": self.grand_total, - "credit_in_account_currency": self.grand_total, - "cost_center": self.cost_center, - }, - item=self, - ) - - from erpnext.accounts.general_ledger import make_gl_entries - - make_gl_entries( - [student_gl_entries, fee_gl_entry], - cancel=(self.docstatus == 2), - update_outstanding="Yes", - merge_entries=False, - ) - - -def get_fee_list(doctype, txt, filters, limit_start, limit_page_length=20, order_by="modified"): - user = frappe.session.user - student = frappe.db.sql("select name from `tabStudent` where student_email_id= %s", user) - if student: - return frappe.db.sql( - """ - select name, program, due_date, grand_total - outstanding_amount as paid_amount, - outstanding_amount, grand_total, currency - from `tabFees` - where student= %s and docstatus=1 - order by due_date asc limit {0} , {1}""".format( - limit_start, limit_page_length - ), - student, - as_dict=True, - ) - - -def get_list_context(context=None): - return { - "show_sidebar": True, - "show_search": True, - "no_breadcrumbs": True, - "title": _("Fees"), - "get_list": get_fee_list, - "row_template": "templates/includes/fee/fee_row.html", - } diff --git a/erpnext/education/doctype/fees/fees_list.js b/erpnext/education/doctype/fees/fees_list.js deleted file mode 100644 index ee8e1e382e..0000000000 --- a/erpnext/education/doctype/fees/fees_list.js +++ /dev/null @@ -1,12 +0,0 @@ -frappe.listview_settings['Fees'] = { - add_fields: ["grand_total", "outstanding_amount", "due_date"], - get_indicator: function(doc) { - if(flt(doc.outstanding_amount)==0) { - return [__("Paid"), "green", "outstanding_amount,=,0"]; - } else if (flt(doc.outstanding_amount) > 0 && doc.due_date >= frappe.datetime.get_today()) { - return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>,Today"]; - } else if (flt(doc.outstanding_amount) > 0 && doc.due_date < frappe.datetime.get_today()) { - return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<=,Today"]; - } - } -}; diff --git a/erpnext/education/doctype/fees/test_fees.py b/erpnext/education/doctype/fees/test_fees.py deleted file mode 100644 index f0f7e67d2b..0000000000 --- a/erpnext/education/doctype/fees/test_fees.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and Contributors -# See license.txt - -import unittest - -import frappe -from frappe.utils import nowdate -from frappe.utils.make_random import get_random - -from erpnext.education.doctype.program.test_program import make_program_and_linked_courses - -test_dependencies = ["Company"] - - -class TestFees(unittest.TestCase): - def test_fees(self): - student = get_random("Student") - program = make_program_and_linked_courses( - "_Test Program 1", ["_Test Course 1", "_Test Course 2"] - ) - fee = frappe.new_doc("Fees") - fee.posting_date = nowdate() - fee.due_date = nowdate() - fee.student = student - fee.receivable_account = "_Test Receivable - _TC" - fee.income_account = "Sales - _TC" - fee.cost_center = "_Test Cost Center - _TC" - fee.company = "_Test Company" - fee.program = program.name - - fee.extend( - "components", - [ - {"fees_category": "Tuition Fee", "amount": 40000}, - {"fees_category": "Transportation Fee", "amount": 10000}, - ], - ) - fee.save() - fee.submit() - - gl_entries = frappe.db.sql( - """ - select account, posting_date, party_type, party, cost_center, fiscal_year, voucher_type, - voucher_no, against_voucher_type, against_voucher, cost_center, company, credit, debit - from `tabGL Entry` where voucher_type=%s and voucher_no=%s""", - ("Fees", fee.name), - as_dict=True, - ) - - if gl_entries[0].account == "_Test Receivable - _TC": - self.assertEqual(gl_entries[0].debit, 50000) - self.assertEqual(gl_entries[0].credit, 0) - self.assertEqual(gl_entries[1].debit, 0) - self.assertEqual(gl_entries[1].credit, 50000) - else: - self.assertEqual(gl_entries[0].credit, 50000) - self.assertEqual(gl_entries[0].debit, 0) - self.assertEqual(gl_entries[1].credit, 0) - self.assertEqual(gl_entries[1].debit, 50000) diff --git a/erpnext/education/doctype/grading_scale/__init__.py b/erpnext/education/doctype/grading_scale/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/grading_scale/grading_scale.js b/erpnext/education/doctype/grading_scale/grading_scale.js deleted file mode 100644 index 622388c0b1..0000000000 --- a/erpnext/education/doctype/grading_scale/grading_scale.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Grading Scale', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/grading_scale/grading_scale.json b/erpnext/education/doctype/grading_scale/grading_scale.json deleted file mode 100644 index fb1e2c7f4e..0000000000 --- a/erpnext/education/doctype/grading_scale/grading_scale.json +++ /dev/null @@ -1,226 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 1, - "autoname": "field:grading_scale_name", - "beta": 0, - "creation": "2016-08-26 03:06:53.922972", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "grading_scale_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Grading Scale Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 1 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "grading_intervals_section", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Grading Scale Intervals", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "intervals", - "fieldtype": "Table", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Intervals", - "length": 0, - "no_copy": 0, - "options": "Grading Scale Interval", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amended_from", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Amended From", - "length": 0, - "no_copy": 1, - "options": "Grading Scale", - "permlevel": 0, - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "description", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Description", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 1, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-08-30 00:34:03.368432", - "modified_by": "Administrator", - "module": "Education", - "name": "Grading Scale", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 1, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/grading_scale/grading_scale.py b/erpnext/education/doctype/grading_scale/grading_scale.py deleted file mode 100644 index c4bd1589b2..0000000000 --- a/erpnext/education/doctype/grading_scale/grading_scale.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.utils import cint - - -class GradingScale(Document): - def validate(self): - thresholds = [] - for d in self.intervals: - if d.threshold in thresholds: - frappe.throw(_("Treshold {0}% appears more than once").format(d.threshold)) - else: - thresholds.append(cint(d.threshold)) - if 0 not in thresholds: - frappe.throw(_("Please define grade for Threshold 0%")) diff --git a/erpnext/education/doctype/grading_scale/grading_scale_dashboard.py b/erpnext/education/doctype/grading_scale/grading_scale_dashboard.py deleted file mode 100644 index 6995666d52..0000000000 --- a/erpnext/education/doctype/grading_scale/grading_scale_dashboard.py +++ /dev/null @@ -1,12 +0,0 @@ -from frappe import _ - - -def get_data(): - return { - "fieldname": "grading_scale", - "non_standard_fieldnames": {"Course": "default_grading_scale"}, - "transactions": [ - {"label": _("Course"), "items": ["Course"]}, - {"label": _("Assessment"), "items": ["Assessment Plan", "Assessment Result"]}, - ], - } diff --git a/erpnext/education/doctype/grading_scale/test_grading_scale.py b/erpnext/education/doctype/grading_scale/test_grading_scale.py deleted file mode 100644 index 09a092cc2a..0000000000 --- a/erpnext/education/doctype/grading_scale/test_grading_scale.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Grading Scale') - - -class TestGradingScale(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/grading_scale/test_records.json b/erpnext/education/doctype/grading_scale/test_records.json deleted file mode 100644 index 72b69547ac..0000000000 --- a/erpnext/education/doctype/grading_scale/test_records.json +++ /dev/null @@ -1,19 +0,0 @@ -[ - { - "grading_scale_name": "_Test Grading Scale", - "intervals": [ - { - "grade_code": "A", - "threshold": 75 - }, - { - "grade_code": "B", - "threshold": 50 - }, - { - "grade_code": "C", - "threshold": 0 - } - ] - } -] \ No newline at end of file diff --git a/erpnext/education/doctype/grading_scale_interval/__init__.py b/erpnext/education/doctype/grading_scale_interval/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/grading_scale_interval/grading_scale_interval.json b/erpnext/education/doctype/grading_scale_interval/grading_scale_interval.json deleted file mode 100644 index 5574e1da54..0000000000 --- a/erpnext/education/doctype/grading_scale_interval/grading_scale_interval.json +++ /dev/null @@ -1,133 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-08-26 03:11:09.591049", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "grade_code", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Grade Code", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "0", - "fieldname": "threshold", - "fieldtype": "Percent", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Threshold", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "1", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "grade_description", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Grade Description", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2017-11-10 19:08:48.083084", - "modified_by": "Administrator", - "module": "Education", - "name": "Grading Scale Interval", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/grading_scale_interval/grading_scale_interval.py b/erpnext/education/doctype/grading_scale_interval/grading_scale_interval.py deleted file mode 100644 index b4101bdcc2..0000000000 --- a/erpnext/education/doctype/grading_scale_interval/grading_scale_interval.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class GradingScaleInterval(Document): - pass diff --git a/erpnext/education/doctype/guardian/__init__.py b/erpnext/education/doctype/guardian/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/guardian/guardian.js b/erpnext/education/doctype/guardian/guardian.js deleted file mode 100644 index b7c2f0af31..0000000000 --- a/erpnext/education/doctype/guardian/guardian.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Guardian', { - refresh: function(frm) { - if(!frm.doc.user && !frm.is_new()) { - frm.add_custom_button(__("Invite as User"), function() { - return frappe.call({ - method: "erpnext.education.doctype.guardian.guardian.invite_guardian", - args: { - guardian: frm.doc.name - }, - callback: function(r) { - frm.set_value("user", r.message); - } - }); - }); - } - } -}); diff --git a/erpnext/education/doctype/guardian/guardian.json b/erpnext/education/doctype/guardian/guardian.json deleted file mode 100644 index 7b8168ed41..0000000000 --- a/erpnext/education/doctype/guardian/guardian.json +++ /dev/null @@ -1,580 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "EDU-GRD-.YYYY.-.#####", - "beta": 0, - "creation": "2016-07-21 15:32:51.163292", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "guardian_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Guardian Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "email_address", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Email Address", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "mobile_number", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Mobile Number", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "alternate_number", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Alternate Number", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "date_of_birth", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Date of Birth", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "user", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "User Id", - "length": 0, - "no_copy": 0, - "options": "User", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_3", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "education", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Education", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "occupation", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Occupation", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "designation", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Designation", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "work_address", - "fieldtype": "Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Work Address", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "image", - "fieldtype": "Attach Image", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Image", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_13", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Guardian Of ", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "students", - "fieldtype": "Table", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Students", - "length": 0, - "no_copy": 0, - "options": "Guardian Student", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_8", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Guardian Interests", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "interests", - "fieldtype": "Table", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Interests", - "length": 0, - "no_copy": 0, - "options": "Guardian Interest", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_field": "image", - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-08-21 16:15:54.050317", - "modified_by": "Administrator", - "module": "Education", - "name": "Guardian", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "guardian_name", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/guardian/guardian.py b/erpnext/education/doctype/guardian/guardian.py deleted file mode 100644 index a456e08d2f..0000000000 --- a/erpnext/education/doctype/guardian/guardian.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.utils.csvutils import getlink - - -class Guardian(Document): - def __setup__(self): - self.onload() - - def onload(self): - """Load Students for quick view""" - self.load_students() - - def load_students(self): - """Load `students` from the database""" - self.students = [] - students = frappe.get_all("Student Guardian", filters={"guardian": self.name}, fields=["parent"]) - for student in students: - self.append( - "students", - { - "student": student.parent, - "student_name": frappe.db.get_value("Student", student.parent, "title"), - }, - ) - - def validate(self): - self.students = [] - - -@frappe.whitelist() -def invite_guardian(guardian): - guardian_doc = frappe.get_doc("Guardian", guardian) - if not guardian_doc.email_address: - frappe.throw(_("Please set Email Address")) - else: - guardian_as_user = frappe.get_value("User", dict(email=guardian_doc.email_address)) - if guardian_as_user: - frappe.msgprint(_("User {0} already exists").format(getlink("User", guardian_as_user))) - return guardian_as_user - else: - user = frappe.get_doc( - { - "doctype": "User", - "first_name": guardian_doc.guardian_name, - "email": guardian_doc.email_address, - "user_type": "Website User", - "send_welcome_email": 1, - } - ).insert(ignore_permissions=True) - frappe.msgprint(_("User {0} created").format(getlink("User", user.name))) - return user.name diff --git a/erpnext/education/doctype/guardian/test_guardian.py b/erpnext/education/doctype/guardian/test_guardian.py deleted file mode 100644 index de3638c309..0000000000 --- a/erpnext/education/doctype/guardian/test_guardian.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Guardian') - - -class TestGuardian(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/guardian_interest/__init__.py b/erpnext/education/doctype/guardian_interest/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/guardian_interest/guardian_interest.json b/erpnext/education/doctype/guardian_interest/guardian_interest.json deleted file mode 100644 index 1995c551db..0000000000 --- a/erpnext/education/doctype/guardian_interest/guardian_interest.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-07-25 07:19:55.113871", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "interest", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Interest", - "length": 0, - "no_copy": 0, - "options": "Interest", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2017-11-10 19:10:22.333454", - "modified_by": "Administrator", - "module": "Education", - "name": "Guardian Interest", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/guardian_interest/guardian_interest.py b/erpnext/education/doctype/guardian_interest/guardian_interest.py deleted file mode 100644 index 6cd1e55d83..0000000000 --- a/erpnext/education/doctype/guardian_interest/guardian_interest.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class GuardianInterest(Document): - pass diff --git a/erpnext/education/doctype/guardian_student/__init__.py b/erpnext/education/doctype/guardian_student/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/guardian_student/guardian_student.json b/erpnext/education/doctype/guardian_student/guardian_student.json deleted file mode 100644 index 2519a54af8..0000000000 --- a/erpnext/education/doctype/guardian_student/guardian_student.json +++ /dev/null @@ -1,132 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2017-01-31 11:53:21.580099", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Student", - "length": 0, - "no_copy": 0, - "options": "Student", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_2", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Student Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2017-11-10 19:10:15.786362", - "modified_by": "Administrator", - "module": "Education", - "name": "Guardian Student", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/guardian_student/guardian_student.py b/erpnext/education/doctype/guardian_student/guardian_student.py deleted file mode 100644 index 4c29575bee..0000000000 --- a/erpnext/education/doctype/guardian_student/guardian_student.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class GuardianStudent(Document): - pass diff --git a/erpnext/education/doctype/instructor/__init__.py b/erpnext/education/doctype/instructor/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/instructor/instructor.js b/erpnext/education/doctype/instructor/instructor.js deleted file mode 100644 index 034b0aaf5d..0000000000 --- a/erpnext/education/doctype/instructor/instructor.js +++ /dev/null @@ -1,64 +0,0 @@ -cur_frm.add_fetch("employee", "department", "department"); -cur_frm.add_fetch("employee", "image", "image"); - -frappe.ui.form.on("Instructor", { - employee: function(frm) { - if (!frm.doc.employee) return; - frappe.db.get_value("Employee", {name: frm.doc.employee}, "company", (d) => { - frm.set_query("department", function() { - return { - "filters": { - "company": d.company, - } - }; - }); - frm.set_query("department", "instructor_log", function() { - return { - "filters": { - "company": d.company, - } - }; - }); - }); - }, - refresh: function(frm) { - if (!frm.doc.__islocal) { - frm.add_custom_button(__("As Examiner"), function() { - frappe.new_doc("Assessment Plan", { - examiner: frm.doc.name - }); - }, __("Assessment Plan")); - frm.add_custom_button(__("As Supervisor"), function() { - frappe.new_doc("Assessment Plan", { - supervisor: frm.doc.name - }); - }, __("Assessment Plan")); - } - frm.set_query("employee", function(doc) { - return { - "filters": { - "department": doc.department, - } - }; - }); - - frm.set_query("academic_term", "instructor_log", function(_doc, cdt, cdn) { - let d = locals[cdt][cdn]; - return { - filters: { - "academic_year": d.academic_year - } - }; - }); - - frm.set_query("course", "instructor_log", function(_doc, cdt, cdn) { - let d = locals[cdt][cdn]; - return { - query: "erpnext.education.doctype.program_enrollment.program_enrollment.get_program_courses", - filters: { - "program": d.program - } - }; - }); - } -}); diff --git a/erpnext/education/doctype/instructor/instructor.json b/erpnext/education/doctype/instructor/instructor.json deleted file mode 100644 index a417391711..0000000000 --- a/erpnext/education/doctype/instructor/instructor.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "actions": [], - "allow_import": 1, - "autoname": "naming_series:", - "creation": "2015-11-04 15:56:30.004034", - "doctype": "DocType", - "document_type": "Other", - "engine": "InnoDB", - "field_order": [ - "instructor_name", - "employee", - "gender", - "column_break_5", - "status", - "naming_series", - "department", - "image", - "log_details", - "instructor_log" - ], - "fields": [ - { - "fieldname": "instructor_name", - "fieldtype": "Data", - "in_global_search": 1, - "label": "Instructor Name", - "reqd": 1 - }, - { - "fieldname": "employee", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Employee", - "options": "Employee" - }, - { - "fieldname": "column_break_5", - "fieldtype": "Column Break" - }, - { - "fieldname": "naming_series", - "fieldtype": "Select", - "label": "Naming Series", - "options": "EDU-INS-.YYYY.-", - "set_only_once": 1 - }, - { - "fetch_from": "employee.department", - "fieldname": "department", - "fieldtype": "Link", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Department", - "options": "Department" - }, - { - "fieldname": "image", - "fieldtype": "Attach Image", - "hidden": 1, - "label": "Image" - }, - { - "fieldname": "log_details", - "fieldtype": "Section Break", - "label": "Instructor Log" - }, - { - "fieldname": "instructor_log", - "fieldtype": "Table", - "label": "Instructor Log", - "options": "Instructor Log" - }, - { - "default": "Active", - "fieldname": "status", - "fieldtype": "Select", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Status", - "options": "Active\nLeft" - }, - { - "fetch_from": "employee.gender", - "fieldname": "gender", - "fieldtype": "Link", - "label": "Gender", - "options": "Gender", - "read_only_depends_on": "employee" - } - ], - "image_field": "image", - "links": [], - "modified": "2020-07-23 18:33:57.904398", - "modified_by": "Administrator", - "module": "Education", - "name": "Instructor", - "owner": "Administrator", - "permissions": [ - { - "email": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor" - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Education Manager", - "set_user_permissions": 1, - "share": 1, - "write": 1 - } - ], - "restrict_to_domain": "Education", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "instructor_name" -} \ No newline at end of file diff --git a/erpnext/education/doctype/instructor/instructor.py b/erpnext/education/doctype/instructor/instructor.py deleted file mode 100644 index 24e0607e2d..0000000000 --- a/erpnext/education/doctype/instructor/instructor.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.model.naming import set_name_by_naming_series - - -class Instructor(Document): - def autoname(self): - naming_method = frappe.db.get_value("Education Settings", None, "instructor_created_by") - if not naming_method: - frappe.throw(_("Please setup Instructor Naming System in Education > Education Settings")) - else: - if naming_method == "Naming Series": - set_name_by_naming_series(self) - elif naming_method == "Employee Number": - if not self.employee: - frappe.throw(_("Please select Employee")) - self.name = self.employee - elif naming_method == "Full Name": - self.name = self.instructor_name - - def validate(self): - self.validate_duplicate_employee() - - def validate_duplicate_employee(self): - if self.employee and frappe.db.get_value( - "Instructor", {"employee": self.employee, "name": ["!=", self.name]}, "name" - ): - frappe.throw(_("Employee ID is linked with another instructor")) - - -def get_timeline_data(doctype, name): - """Return timeline for course schedule""" - return dict( - frappe.db.sql( - """ - SELECT unix_timestamp(`schedule_date`), count(*) - FROM `tabCourse Schedule` - WHERE - instructor=%s and - `schedule_date` > date_sub(curdate(), interval 1 year) - GROUP BY schedule_date - """, - name, - ) - ) diff --git a/erpnext/education/doctype/instructor/instructor_dashboard.py b/erpnext/education/doctype/instructor/instructor_dashboard.py deleted file mode 100644 index ead10ca7f8..0000000000 --- a/erpnext/education/doctype/instructor/instructor_dashboard.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - -from frappe import _ - - -def get_data(): - return { - "heatmap": True, - "heatmap_message": _("This is based on the course schedules of this Instructor"), - "fieldname": "instructor", - "non_standard_fieldnames": {"Assessment Plan": "supervisor"}, - "transactions": [ - {"label": _("Course and Assessment"), "items": ["Course Schedule", "Assessment Plan"]}, - {"label": _("Students"), "items": ["Student Group"]}, - ], - } diff --git a/erpnext/education/doctype/instructor/test_instructor.py b/erpnext/education/doctype/instructor/test_instructor.py deleted file mode 100644 index ee1e81dd30..0000000000 --- a/erpnext/education/doctype/instructor/test_instructor.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Instructor') - - -class TestInstructor(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/instructor/test_records.json b/erpnext/education/doctype/instructor/test_records.json deleted file mode 100644 index 220d84eb96..0000000000 --- a/erpnext/education/doctype/instructor/test_records.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "naming_series": "_T-Instructor-", - "employee": "_T-Employee-00001", - "instructor_name": "_Test Instructor" - }, - { - "naming_series": "_T-Instructor-", - "employee": "_T-Employee-00002", - "instructor_name": "_Test Instructor 2" - } -] diff --git a/erpnext/education/doctype/instructor_log/__init__.py b/erpnext/education/doctype/instructor_log/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/instructor_log/instructor_log.json b/erpnext/education/doctype/instructor_log/instructor_log.json deleted file mode 100644 index 5b9e1f9b97..0000000000 --- a/erpnext/education/doctype/instructor_log/instructor_log.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "actions": [], - "creation": "2017-12-27 08:55:52.680284", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "academic_year", - "academic_term", - "department", - "column_break_3", - "program", - "course", - "student_group", - "section_break_8", - "other_details" - ], - "fields": [ - { - "fieldname": "academic_year", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Academic Year", - "options": "Academic Year", - "reqd": 1 - }, - { - "fieldname": "academic_term", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Academic Term", - "options": "Academic Term" - }, - { - "fieldname": "department", - "fieldtype": "Link", - "label": "Department", - "options": "Department" - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fieldname": "program", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Program", - "options": "Program", - "reqd": 1 - }, - { - "fieldname": "course", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Course", - "options": "Course" - }, - { - "fieldname": "student_group", - "fieldtype": "Link", - "label": "Student Group", - "options": "Student Group" - }, - { - "fieldname": "section_break_8", - "fieldtype": "Section Break" - }, - { - "fieldname": "other_details", - "fieldtype": "Small Text", - "label": "Other details" - } - ], - "istable": 1, - "links": [], - "modified": "2020-10-23 15:15:50.759657", - "modified_by": "Administrator", - "module": "Education", - "name": "Instructor Log", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "restrict_to_domain": "Education", - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/education/doctype/instructor_log/instructor_log.py b/erpnext/education/doctype/instructor_log/instructor_log.py deleted file mode 100644 index 12d11ba005..0000000000 --- a/erpnext/education/doctype/instructor_log/instructor_log.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class InstructorLog(Document): - pass diff --git a/erpnext/education/doctype/options/__init__.py b/erpnext/education/doctype/options/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/options/options.json b/erpnext/education/doctype/options/options.json deleted file mode 100644 index 59deab7837..0000000000 --- a/erpnext/education/doctype/options/options.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-10-15 14:05:28.601274", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "option", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Option", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "is_correct", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Is Correct", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-10-15 14:16:18.303156", - "modified_by": "Administrator", - "module": "Education", - "name": "Options", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/options/options.py b/erpnext/education/doctype/options/options.py deleted file mode 100644 index 968a772900..0000000000 --- a/erpnext/education/doctype/options/options.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class Options(Document): - pass diff --git a/erpnext/education/doctype/program/__init__.py b/erpnext/education/doctype/program/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/program/program.js b/erpnext/education/doctype/program/program.js deleted file mode 100644 index 2d89351504..0000000000 --- a/erpnext/education/doctype/program/program.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2015, Frappe Technologies and contributors -// For license information, please see license.txt - -cur_frm.add_fetch('fee_structure', 'total_amount', 'amount'); - -frappe.ui.form.on("Program", "refresh", function(frm) { - -}); diff --git a/erpnext/education/doctype/program/program.json b/erpnext/education/doctype/program/program.json deleted file mode 100644 index 2dfe50b2f0..0000000000 --- a/erpnext/education/doctype/program/program.json +++ /dev/null @@ -1,177 +0,0 @@ -{ - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:program_name", - "creation": "2015-09-07 12:54:03.609282", - "doctype": "DocType", - "engine": "InnoDB", - "field_order": [ - "program_name", - "department", - "column_break_3", - "program_abbreviation", - "section_break_courses", - "courses", - "section_break_5", - "is_published", - "allow_self_enroll", - "is_featured", - "column_break_11", - "intro_video", - "hero_image", - "description" - ], - "fields": [ - { - "fieldname": "program_name", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Program Name", - "reqd": 1, - "unique": 1 - }, - { - "fieldname": "department", - "fieldtype": "Link", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Department", - "options": "Department" - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fieldname": "program_abbreviation", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Program Abbreviation" - }, - { - "fieldname": "section_break_5", - "fieldtype": "Section Break", - "label": "Portal Settings" - }, - { - "fieldname": "courses", - "fieldtype": "Table", - "label": "Courses", - "options": "Program Course" - }, - { - "depends_on": "is_published", - "fieldname": "description", - "fieldtype": "Small Text", - "label": "Description" - }, - { - "depends_on": "is_published", - "fieldname": "intro_video", - "fieldtype": "Data", - "label": "Intro Video" - }, - { - "fieldname": "hero_image", - "fieldtype": "Attach Image", - "hidden": 1, - "label": "Hero Image" - }, - { - "default": "0", - "fieldname": "is_published", - "fieldtype": "Check", - "label": "Is Published" - }, - { - "default": "0", - "depends_on": "eval: doc.is_published == 1", - "fieldname": "is_featured", - "fieldtype": "Check", - "label": "Is Featured" - }, - { - "default": "0", - "depends_on": "eval: doc.is_published == 1", - "fieldname": "allow_self_enroll", - "fieldtype": "Check", - "label": "Allow Self Enroll" - }, - { - "fieldname": "section_break_courses", - "fieldtype": "Section Break", - "label": "Courses" - }, - { - "fieldname": "column_break_11", - "fieldtype": "Column Break" - } - ], - "image_field": "hero_image", - "modified": "2019-06-12 12:31:14.999346", - "modified_by": "Administrator", - "module": "Education", - "name": "Program", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "share": 1, - "write": 1 - }, - { - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Guest", - "share": 1 - }, - { - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Student", - "share": 1 - } - ], - "restrict_to_domain": "Education", - "search_fields": "program_name", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC" -} \ No newline at end of file diff --git a/erpnext/education/doctype/program/program.py b/erpnext/education/doctype/program/program.py deleted file mode 100644 index 5250f8c05e..0000000000 --- a/erpnext/education/doctype/program/program.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -import frappe -from frappe.model.document import Document - - -class Program(Document): - def get_course_list(self): - program_course_list = self.courses - course_list = [ - frappe.get_doc("Course", program_course.course) for program_course in program_course_list - ] - return course_list diff --git a/erpnext/education/doctype/program/program_dashboard.py b/erpnext/education/doctype/program/program_dashboard.py deleted file mode 100644 index 21820618bb..0000000000 --- a/erpnext/education/doctype/program/program_dashboard.py +++ /dev/null @@ -1,13 +0,0 @@ -from frappe import _ - - -def get_data(): - return { - "fieldname": "program", - "transactions": [ - {"label": _("Admission and Enrollment"), "items": ["Student Applicant", "Program Enrollment"]}, - {"label": _("Student Activity"), "items": ["Student Group", "Student Log"]}, - {"label": _("Fee"), "items": ["Fees", "Fee Structure", "Fee Schedule"]}, - {"label": _("Assessment"), "items": ["Assessment Plan", "Assessment Result"]}, - ], - } diff --git a/erpnext/education/doctype/program/test_program.py b/erpnext/education/doctype/program/test_program.py deleted file mode 100644 index c3dbad2d16..0000000000 --- a/erpnext/education/doctype/program/test_program.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and Contributors -# See license.txt - -import unittest - -import frappe - -from erpnext.education.doctype.course.test_course import make_course, make_course_and_linked_topic -from erpnext.education.doctype.topic.test_topic import make_topic_and_linked_content - -test_data = { - "program_name": "_Test Program", - "description": "_Test Program", - "course": [ - { - "course_name": "_Test Course 1", - "topic": [ - { - "topic_name": "_Test Topic 1-1", - "content": [ - {"type": "Article", "name": "_Test Article 1-1"}, - {"type": "Article", "name": "_Test Article 1-2"}, - ], - }, - { - "topic_name": "_Test Topic 1-2", - "content": [ - {"type": "Article", "name": "_Test Article 1-3"}, - {"type": "Article", "name": "_Test Article 1-4"}, - ], - }, - ], - } - ], -} - - -class TestProgram(unittest.TestCase): - def setUp(self): - make_program_and_linked_courses("_Test Program 1", ["_Test Course 1", "_Test Course 2"]) - - def test_get_course_list(self): - program = frappe.get_doc("Program", "_Test Program 1") - course = program.get_course_list() - self.assertEqual(course[0].name, "_Test Course 1") - self.assertEqual(course[1].name, "_Test Course 2") - frappe.db.rollback() - - def tearDown(self): - for dt in ["Program", "Course", "Topic", "Article"]: - for entry in frappe.get_all(dt): - frappe.delete_doc(dt, entry.program) - - -def make_program(name): - program = frappe.get_doc( - { - "doctype": "Program", - "program_name": name, - "program_code": name, - "description": "_test description", - "is_published": True, - "is_featured": True, - } - ).insert() - return program.name - - -def make_program_and_linked_courses(program_name, course_name_list): - try: - program = frappe.get_doc("Program", program_name) - except frappe.DoesNotExistError: - make_program(program_name) - program = frappe.get_doc("Program", program_name) - course_list = [make_course(course_name) for course_name in course_name_list] - for course in course_list: - program.append("courses", {"course": course, "required": 1}) - program.save() - return program - - -def setup_program(): - topic_list = [course["topic"] for course in test_data["course"]] - for topic in topic_list[0]: - make_topic_and_linked_content(topic["topic_name"], topic["content"]) - - all_courses_list = [ - {"course": course["course_name"], "topic": [topic["topic_name"] for topic in course["topic"]]} - for course in test_data["course"] - ] # returns [{'course': 'Applied Math', 'topic': ['Trignometry', 'Geometry']}] - for course in all_courses_list: - make_course_and_linked_topic(course["course"], course["topic"]) - - course_list = [course["course_name"] for course in test_data["course"]] - program = make_program_and_linked_courses(test_data["program_name"], course_list) - return program diff --git a/erpnext/education/doctype/program/test_records.json b/erpnext/education/doctype/program/test_records.json deleted file mode 100644 index 4013695896..0000000000 --- a/erpnext/education/doctype/program/test_records.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "program_name": "_TP1", - "description": "Test Description", - "program_abbreviation": "TP1" - }, - { - "program_name": "_TP2", - "description": "Test Description", - "program_abbreviation": "TP2" - } -] \ No newline at end of file diff --git a/erpnext/education/doctype/program_course/__init__.py b/erpnext/education/doctype/program_course/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/program_course/program_course.json b/erpnext/education/doctype/program_course/program_course.json deleted file mode 100644 index dc6b3fcef8..0000000000 --- a/erpnext/education/doctype/program_course/program_course.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "actions": [], - "creation": "2015-09-07 14:37:01.886859", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "course", - "course_name", - "required" - ], - "fields": [ - { - "fieldname": "course", - "fieldtype": "Link", - "in_global_search": 1, - "in_list_view": 1, - "label": "Course", - "options": "Course", - "reqd": 1 - }, - { - "fetch_from": "course.course_name", - "fieldname": "course_name", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Course Name", - "read_only": 1 - }, - { - "default": "1", - "fieldname": "required", - "fieldtype": "Check", - "in_list_view": 1, - "label": "Mandatory" - } - ], - "istable": 1, - "links": [], - "modified": "2020-09-15 18:14:22.816795", - "modified_by": "Administrator", - "module": "Education", - "name": "Program Course", - "owner": "Administrator", - "permissions": [], - "restrict_to_domain": "Education", - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/education/doctype/program_course/program_course.py b/erpnext/education/doctype/program_course/program_course.py deleted file mode 100644 index dec392c42c..0000000000 --- a/erpnext/education/doctype/program_course/program_course.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class ProgramCourse(Document): - pass diff --git a/erpnext/education/doctype/program_enrollment/__init__.py b/erpnext/education/doctype/program_enrollment/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment.js b/erpnext/education/doctype/program_enrollment/program_enrollment.js deleted file mode 100644 index e92d063602..0000000000 --- a/erpnext/education/doctype/program_enrollment/program_enrollment.js +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2016, Frappe and contributors -// For license information, please see license.txt - - -frappe.ui.form.on('Program Enrollment', { - setup: function(frm) { - frm.add_fetch('fee_structure', 'total_amount', 'amount'); - }, - - onload: function(frm) { - frm.set_query('academic_term', function() { - return { - 'filters':{ - 'academic_year': frm.doc.academic_year - } - }; - }); - - frm.set_query('academic_term', 'fees', function() { - return { - 'filters':{ - 'academic_year': frm.doc.academic_year - } - }; - }); - - frm.fields_dict['fees'].grid.get_field('fee_structure').get_query = function(doc, cdt, cdn) { - var d = locals[cdt][cdn]; - return { - filters: {'academic_term': d.academic_term} - } - }; - - if (frm.doc.program) { - frm.set_query('course', 'courses', function() { - return { - query: 'erpnext.education.doctype.program_enrollment.program_enrollment.get_program_courses', - filters: { - 'program': frm.doc.program - } - } - }); - } - - frm.set_query('student', function() { - return{ - query: 'erpnext.education.doctype.program_enrollment.program_enrollment.get_students', - filters: { - 'academic_year': frm.doc.academic_year, - 'academic_term': frm.doc.academic_term - } - } - }); - }, - - program: function(frm) { - frm.events.get_courses(frm); - if (frm.doc.program) { - frappe.call({ - method: 'erpnext.education.api.get_fee_schedule', - args: { - 'program': frm.doc.program, - 'student_category': frm.doc.student_category - }, - callback: function(r) { - if (r.message) { - frm.set_value('fees' ,r.message); - frm.events.get_courses(frm); - } - } - }); - } - }, - - student_category: function() { - frappe.ui.form.trigger('Program Enrollment', 'program'); - }, - - get_courses: function(frm) { - frm.set_value('courses',[]); - frappe.call({ - method: 'get_courses', - doc:frm.doc, - callback: function(r) { - if (r.message) { - frm.set_value('courses', r.message); - } - } - }) - } -}); - -frappe.ui.form.on('Program Enrollment Course', { - courses_add: function(frm){ - frm.fields_dict['courses'].grid.get_field('course').get_query = function(doc) { - var course_list = []; - if(!doc.__islocal) course_list.push(doc.name); - $.each(doc.courses, function(_idx, val) { - if (val.course) course_list.push(val.course); - }); - return { filters: [['Course', 'name', 'not in', course_list]] }; - }; - } -}); diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment.json b/erpnext/education/doctype/program_enrollment/program_enrollment.json deleted file mode 100644 index 4a00fd0454..0000000000 --- a/erpnext/education/doctype/program_enrollment/program_enrollment.json +++ /dev/null @@ -1,218 +0,0 @@ -{ - "actions": [], - "allow_import": 1, - "autoname": "EDU-ENR-.YYYY.-.#####", - "creation": "2015-12-02 12:58:32.916080", - "doctype": "DocType", - "document_type": "Document", - "engine": "InnoDB", - "field_order": [ - "student", - "student_name", - "student_category", - "student_batch_name", - "school_house", - "column_break_4", - "program", - "academic_year", - "academic_term", - "enrollment_date", - "boarding_student", - "enrolled_courses", - "courses", - "transportation", - "mode_of_transportation", - "column_break_13", - "vehicle_no", - "section_break_7", - "fees", - "amended_from", - "image" - ], - "fields": [ - { - "fieldname": "student", - "fieldtype": "Link", - "in_global_search": 1, - "label": "Student", - "options": "Student", - "reqd": 1 - }, - { - "fetch_from": "student.title", - "fieldname": "student_name", - "fieldtype": "Read Only", - "in_global_search": 1, - "label": "Student Name", - "read_only": 1 - }, - { - "fieldname": "student_category", - "fieldtype": "Link", - "label": "Student Category", - "options": "Student Category" - }, - { - "allow_on_submit": 1, - "fieldname": "student_batch_name", - "fieldtype": "Link", - "in_global_search": 1, - "label": "Student Batch", - "options": "Student Batch Name" - }, - { - "allow_on_submit": 1, - "fieldname": "school_house", - "fieldtype": "Link", - "label": "School House", - "options": "School House" - }, - { - "fieldname": "column_break_4", - "fieldtype": "Column Break" - }, - { - "fieldname": "program", - "fieldtype": "Link", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Program", - "options": "Program", - "reqd": 1 - }, - { - "fieldname": "academic_year", - "fieldtype": "Link", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Academic Year", - "options": "Academic Year", - "reqd": 1 - }, - { - "fieldname": "academic_term", - "fieldtype": "Link", - "label": "Academic Term", - "options": "Academic Term" - }, - { - "default": "Today", - "fieldname": "enrollment_date", - "fieldtype": "Date", - "label": "Enrollment Date", - "reqd": 1 - }, - { - "default": "0", - "description": "Check this if the Student is residing at the Institute's Hostel.", - "fieldname": "boarding_student", - "fieldtype": "Check", - "label": "Boarding Student" - }, - { - "collapsible": 1, - "collapsible_depends_on": "vehicle_no", - "fieldname": "transportation", - "fieldtype": "Section Break", - "label": "Transportation" - }, - { - "allow_on_submit": 1, - "fieldname": "mode_of_transportation", - "fieldtype": "Select", - "label": "Mode of Transportation", - "options": "\nWalking\nInstitute's Bus\nPublic Transport\nSelf-Driving Vehicle\nPick/Drop by Guardian" - }, - { - "fieldname": "column_break_13", - "fieldtype": "Column Break" - }, - { - "allow_on_submit": 1, - "fieldname": "vehicle_no", - "fieldtype": "Data", - "label": "Vehicle/Bus Number" - }, - { - "fieldname": "enrolled_courses", - "fieldtype": "Section Break", - "label": "Enrolled courses" - }, - { - "allow_on_submit": 1, - "fieldname": "courses", - "fieldtype": "Table", - "label": "Courses", - "options": "Program Enrollment Course" - }, - { - "collapsible": 1, - "fieldname": "section_break_7", - "fieldtype": "Section Break", - "label": "Fees" - }, - { - "fieldname": "fees", - "fieldtype": "Table", - "label": "Fees", - "options": "Program Fee" - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Program Enrollment", - "print_hide": 1, - "read_only": 1 - }, - { - "fieldname": "image", - "fieldtype": "Attach Image", - "hidden": 1, - "label": "Image" - } - ], - "image_field": "image", - "is_submittable": 1, - "links": [], - "modified": "2020-09-15 18:12:11.988565", - "modified_by": "Administrator", - "module": "Education", - "name": "Program Enrollment", - "owner": "Administrator", - "permissions": [ - { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "submit": 1, - "write": 1 - }, - { - "create": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "LMS User", - "share": 1, - "submit": 1, - "write": 1 - } - ], - "restrict_to_domain": "Education", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "student_name" -} \ No newline at end of file diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment.py b/erpnext/education/doctype/program_enrollment/program_enrollment.py deleted file mode 100644 index 69d281b938..0000000000 --- a/erpnext/education/doctype/program_enrollment/program_enrollment.py +++ /dev/null @@ -1,220 +0,0 @@ -# Copyright (c) 2015, Frappe and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _, msgprint -from frappe.desk.reportview import get_match_cond -from frappe.model.document import Document -from frappe.query_builder.functions import Min -from frappe.utils import comma_and, get_link_to_form, getdate - - -class ProgramEnrollment(Document): - def validate(self): - self.validate_duplication() - self.validate_academic_year() - if self.academic_term: - self.validate_academic_term() - if not self.student_name: - self.student_name = frappe.db.get_value("Student", self.student, "title") - if not self.courses: - self.extend("courses", self.get_courses()) - - def on_submit(self): - self.update_student_joining_date() - self.make_fee_records() - self.create_course_enrollments() - - def validate_academic_year(self): - start_date, end_date = frappe.db.get_value( - "Academic Year", self.academic_year, ["year_start_date", "year_end_date"] - ) - if self.enrollment_date: - if start_date and getdate(self.enrollment_date) < getdate(start_date): - frappe.throw( - _("Enrollment Date cannot be before the Start Date of the Academic Year {0}").format( - get_link_to_form("Academic Year", self.academic_year) - ) - ) - - if end_date and getdate(self.enrollment_date) > getdate(end_date): - frappe.throw( - _("Enrollment Date cannot be after the End Date of the Academic Term {0}").format( - get_link_to_form("Academic Year", self.academic_year) - ) - ) - - def validate_academic_term(self): - start_date, end_date = frappe.db.get_value( - "Academic Term", self.academic_term, ["term_start_date", "term_end_date"] - ) - if self.enrollment_date: - if start_date and getdate(self.enrollment_date) < getdate(start_date): - frappe.throw( - _("Enrollment Date cannot be before the Start Date of the Academic Term {0}").format( - get_link_to_form("Academic Term", self.academic_term) - ) - ) - - if end_date and getdate(self.enrollment_date) > getdate(end_date): - frappe.throw( - _("Enrollment Date cannot be after the End Date of the Academic Term {0}").format( - get_link_to_form("Academic Term", self.academic_term) - ) - ) - - def validate_duplication(self): - enrollment = frappe.get_all( - "Program Enrollment", - filters={ - "student": self.student, - "program": self.program, - "academic_year": self.academic_year, - "academic_term": self.academic_term, - "docstatus": ("<", 2), - "name": ("!=", self.name), - }, - ) - if enrollment: - frappe.throw(_("Student is already enrolled.")) - - def update_student_joining_date(self): - table = frappe.qb.DocType("Program Enrollment") - date = ( - frappe.qb.from_(table) - .select(Min(table.enrollment_date).as_("enrollment_date")) - .where(table.student == self.student) - ).run(as_dict=True) - - if date: - frappe.db.set_value("Student", self.student, "joining_date", date[0].enrollment_date) - - def make_fee_records(self): - from erpnext.education.api import get_fee_components - - fee_list = [] - for d in self.fees: - fee_components = get_fee_components(d.fee_structure) - if fee_components: - fees = frappe.new_doc("Fees") - fees.update( - { - "student": self.student, - "academic_year": self.academic_year, - "academic_term": d.academic_term, - "fee_structure": d.fee_structure, - "program": self.program, - "due_date": d.due_date, - "student_name": self.student_name, - "program_enrollment": self.name, - "components": fee_components, - } - ) - - fees.save() - fees.submit() - fee_list.append(fees.name) - if fee_list: - fee_list = [ - """%s""" % (fee, fee) for fee in fee_list - ] - msgprint(_("Fee Records Created - {0}").format(comma_and(fee_list))) - - @frappe.whitelist() - def get_courses(self): - return frappe.db.sql( - """select course from `tabProgram Course` where parent = %s and required = 1""", - (self.program), - as_dict=1, - ) - - def create_course_enrollments(self): - student = frappe.get_doc("Student", self.student) - course_list = [course.course for course in self.courses] - for course_name in course_list: - student.enroll_in_course( - course_name=course_name, program_enrollment=self.name, enrollment_date=self.enrollment_date - ) - - def get_all_course_enrollments(self): - course_enrollment_names = frappe.get_list( - "Course Enrollment", filters={"program_enrollment": self.name} - ) - return [ - frappe.get_doc("Course Enrollment", course_enrollment.name) - for course_enrollment in course_enrollment_names - ] - - def get_quiz_progress(self): - student = frappe.get_doc("Student", self.student) - quiz_progress = frappe._dict() - progress_list = [] - for course_enrollment in self.get_all_course_enrollments(): - course_progress = course_enrollment.get_progress(student) - for progress_item in course_progress: - if progress_item["content_type"] == "Quiz": - progress_item["course"] = course_enrollment.course - progress_list.append(progress_item) - if not progress_list: - return None - quiz_progress.quiz_attempt = progress_list - quiz_progress.name = self.program - quiz_progress.program = self.program - return quiz_progress - - -@frappe.whitelist() -@frappe.validate_and_sanitize_search_inputs -def get_program_courses(doctype, txt, searchfield, start, page_len, filters): - if not filters.get("program"): - frappe.msgprint(_("Please select a Program first.")) - return [] - - return frappe.db.sql( - """select course, course_name from `tabProgram Course` - where parent = %(program)s and course like %(txt)s {match_cond} - order by - if(locate(%(_txt)s, course), locate(%(_txt)s, course), 99999), - idx desc, - `tabProgram Course`.course asc - limit {start}, {page_len}""".format( - match_cond=get_match_cond(doctype), start=start, page_len=page_len - ), - {"txt": "%{0}%".format(txt), "_txt": txt.replace("%", ""), "program": filters["program"]}, - ) - - -@frappe.whitelist() -@frappe.validate_and_sanitize_search_inputs -def get_students(doctype, txt, searchfield, start, page_len, filters): - if not filters.get("academic_term"): - filters["academic_term"] = frappe.defaults.get_defaults().academic_term - - if not filters.get("academic_year"): - filters["academic_year"] = frappe.defaults.get_defaults().academic_year - - enrolled_students = frappe.get_list( - "Program Enrollment", - filters={ - "academic_term": filters.get("academic_term"), - "academic_year": filters.get("academic_year"), - }, - fields=["student"], - ) - - students = [d.student for d in enrolled_students] if enrolled_students else [""] - - return frappe.db.sql( - """select - name, title from tabStudent - where - name not in (%s) - and - `%s` LIKE %s - order by - idx desc, name - limit %s, %s""" - % (", ".join(["%s"] * len(students)), searchfield, "%s", "%s", "%s"), - tuple(students + ["%%%s%%" % txt, start, page_len]), - ) diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment_dashboard.py b/erpnext/education/doctype/program_enrollment/program_enrollment_dashboard.py deleted file mode 100644 index c308961d8c..0000000000 --- a/erpnext/education/doctype/program_enrollment/program_enrollment_dashboard.py +++ /dev/null @@ -1,9 +0,0 @@ -from frappe import _ - - -def get_data(): - return { - "fieldname": "program_enrollment", - "transactions": [{"label": _("Course and Fee"), "items": ["Course Enrollment", "Fees"]}], - "reports": [{"label": _("Report"), "items": ["Student and Guardian Contact Details"]}], - } diff --git a/erpnext/education/doctype/program_enrollment/test_program_enrollment.py b/erpnext/education/doctype/program_enrollment/test_program_enrollment.py deleted file mode 100644 index 4d43175fef..0000000000 --- a/erpnext/education/doctype/program_enrollment/test_program_enrollment.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2015, Frappe and Contributors -# See license.txt - -import unittest - -import frappe - -from erpnext.education.doctype.program.test_program import make_program_and_linked_courses -from erpnext.education.doctype.student.test_student import create_student, get_student - - -class TestProgramEnrollment(unittest.TestCase): - def setUp(self): - create_student( - { - "first_name": "_Test Name", - "last_name": "_Test Last Name", - "email": "_test_student@example.com", - } - ) - make_program_and_linked_courses("_Test Program 1", ["_Test Course 1", "_Test Course 2"]) - - def test_create_course_enrollments(self): - student = get_student("_test_student@example.com") - enrollment = student.enroll_in_program("_Test Program 1") - course_enrollments = student.get_all_course_enrollments() - self.assertTrue("_Test Course 1" in course_enrollments.keys()) - self.assertTrue("_Test Course 2" in course_enrollments.keys()) - frappe.db.rollback() - - def tearDown(self): - for entry in frappe.db.get_all("Course Enrollment"): - frappe.delete_doc("Course Enrollment", entry.name) - - for entry in frappe.db.get_all("Program Enrollment"): - doc = frappe.get_doc("Program Enrollment", entry.name) - doc.cancel() - doc.delete() diff --git a/erpnext/education/doctype/program_enrollment_course/__init__.py b/erpnext/education/doctype/program_enrollment_course/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/program_enrollment_course/program_enrollment_course.json b/erpnext/education/doctype/program_enrollment_course/program_enrollment_course.json deleted file mode 100644 index 502a40165a..0000000000 --- a/erpnext/education/doctype/program_enrollment_course/program_enrollment_course.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2017-04-10 19:28:19.616308", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "course", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Course", - "length": 0, - "no_copy": 0, - "options": "Course", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "course.course_name", - "fieldname": "course_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Course Name", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-05-16 22:42:39.136276", - "modified_by": "Administrator", - "module": "Education", - "name": "Program Enrollment Course", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/program_enrollment_course/program_enrollment_course.py b/erpnext/education/doctype/program_enrollment_course/program_enrollment_course.py deleted file mode 100644 index 8b2d82c5ee..0000000000 --- a/erpnext/education/doctype/program_enrollment_course/program_enrollment_course.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class ProgramEnrollmentCourse(Document): - pass diff --git a/erpnext/education/doctype/program_enrollment_fee/__init__.py b/erpnext/education/doctype/program_enrollment_fee/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/program_enrollment_fee/program_enrollment_fee.json b/erpnext/education/doctype/program_enrollment_fee/program_enrollment_fee.json deleted file mode 100644 index 0af28155e2..0000000000 --- a/erpnext/education/doctype/program_enrollment_fee/program_enrollment_fee.json +++ /dev/null @@ -1,192 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-05-19 05:52:56.322125", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "academic_term", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Academic Term", - "length": 0, - "no_copy": 0, - "options": "Academic Term", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "fee_structure", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Fee Structure", - "length": 0, - "no_copy": 0, - "options": "Fee Structure", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_3", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "due_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Due Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Amount", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2017-11-10 19:11:07.516632", - "modified_by": "Administrator", - "module": "Education", - "name": "Program Enrollment Fee", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/program_enrollment_fee/program_enrollment_fee.py b/erpnext/education/doctype/program_enrollment_fee/program_enrollment_fee.py deleted file mode 100644 index 17d410f7b2..0000000000 --- a/erpnext/education/doctype/program_enrollment_fee/program_enrollment_fee.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class ProgramEnrollmentFee(Document): - pass diff --git a/erpnext/education/doctype/program_enrollment_tool/__init__.py b/erpnext/education/doctype/program_enrollment_tool/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.js b/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.js deleted file mode 100644 index 06d7598194..0000000000 --- a/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.js +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2016, Frappe and contributors -// For license information, please see license.txt - -frappe.ui.form.on("Program Enrollment Tool", { - setup: function(frm) { - frm.add_fetch("student", "title", "student_name"); - frm.add_fetch("student_applicant", "title", "student_name"); - if(frm.doc.__onload && frm.doc.__onload.academic_term_reqd) { - frm.toggle_reqd("academic_term", true); - } - }, - - "refresh": function(frm) { - frm.disable_save(); - frm.fields_dict.enroll_students.$input.addClass(' btn btn-primary'); - frappe.realtime.on("program_enrollment_tool", function(data) { - frappe.hide_msgprint(true); - frappe.show_progress(__("Enrolling students"), data.progress[0], data.progress[1]); - }); - }, - - get_students_from: function(frm) { - if (frm.doc.get_students_from == "Student Applicant") { - frm.dashboard.add_comment(__('Only the Student Applicant with the status "Approved" will be selected in the table below.')); - } - }, - - "get_students": function(frm) { - frm.set_value("students",[]); - frappe.call({ - method: "get_students", - doc:frm.doc, - callback: function(r) { - if(r.message) { - frm.set_value("students", r.message); - } - } - }); - }, - - "enroll_students": function(frm) { - frappe.call({ - method: "enroll_students", - doc:frm.doc, - callback: function(r) { - frm.set_value("students", []); - frappe.hide_msgprint(true); - } - }); - } -}); diff --git a/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.json b/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.json deleted file mode 100644 index 35ad98d120..0000000000 --- a/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.json +++ /dev/null @@ -1,553 +0,0 @@ -{ - "allow_copy": 1, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-06-10 03:01:05.178956", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 0, - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "get_students_from", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Get Students From", - "length": 0, - "no_copy": 0, - "options": "\nStudent Applicant\nProgram Enrollment", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "program", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Program", - "length": 0, - "no_copy": 0, - "options": "Program", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.get_students_from==\"Program Enrollment\"", - "fieldname": "student_batch", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Student Batch", - "length": 0, - "no_copy": 0, - "options": "Student Batch Name", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_3", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "academic_year", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Academic Year", - "length": 0, - "no_copy": 0, - "options": "Academic Year", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "academic_term", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Academic Term", - "length": 0, - "no_copy": 0, - "options": "Academic Term", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_5", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "get_students", - "fieldtype": "Button", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Get Students", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "students", - "fieldtype": "Table", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Students", - "length": 0, - "no_copy": 0, - "options": "Program Enrollment Tool Student", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_7", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Enrollment Details", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.get_students_from==\"Program Enrollment\"", - "fieldname": "new_program", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "New Program", - "length": 0, - "no_copy": 0, - "options": "Program", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "new_student_batch", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "New Student Batch", - "length": 0, - "no_copy": 0, - "options": "Student Batch Name", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "enroll_students", - "fieldtype": "Button", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Enroll Students", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_12", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.get_students_from==\"Program Enrollment\"", - "fieldname": "new_academic_year", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "New Academic Year", - "length": 0, - "no_copy": 0, - "options": "Academic Year", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.get_students_from==\"Program Enrollment\"", - "fieldname": "new_academic_term", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "New Academic Term", - "length": 0, - "no_copy": 0, - "options": "Academic Term", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 1, - "hide_toolbar": 1, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 1, - "istable": 0, - "max_attachments": 0, - "modified": "2018-07-26 04:44:13.232146", - "modified_by": "Administrator", - "module": "Education", - "name": "Program Enrollment Tool", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 0, - "role": "Education Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.py b/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.py deleted file mode 100644 index 9e72876f19..0000000000 --- a/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.py +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright (c) 2015, Frappe and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.utils import cint - -from erpnext.education.api import enroll_student - - -class ProgramEnrollmentTool(Document): - def onload(self): - academic_term_reqd = cint(frappe.db.get_single_value("Education Settings", "academic_term_reqd")) - self.set_onload("academic_term_reqd", academic_term_reqd) - - @frappe.whitelist() - def get_students(self): - students = [] - if not self.get_students_from: - frappe.throw(_("Mandatory field - Get Students From")) - elif not self.program: - frappe.throw(_("Mandatory field - Program")) - elif not self.academic_year: - frappe.throw(_("Mandatory field - Academic Year")) - else: - condition = "and academic_term=%(academic_term)s" if self.academic_term else " " - if self.get_students_from == "Student Applicant": - students = frappe.db.sql( - """select name as student_applicant, title as student_name from `tabStudent Applicant` - where application_status="Approved" and program=%(program)s and academic_year=%(academic_year)s {0}""".format( - condition - ), - self.as_dict(), - as_dict=1, - ) - elif self.get_students_from == "Program Enrollment": - condition2 = "and student_batch_name=%(student_batch)s" if self.student_batch else " " - students = frappe.db.sql( - """select student, student_name, student_batch_name, student_category from `tabProgram Enrollment` - where program=%(program)s and academic_year=%(academic_year)s {0} {1} and docstatus != 2""".format( - condition, condition2 - ), - self.as_dict(), - as_dict=1, - ) - - student_list = [d.student for d in students] - if student_list: - inactive_students = frappe.db.sql( - """ - select name as student, title as student_name from `tabStudent` where name in (%s) and enabled = 0""" - % ", ".join(["%s"] * len(student_list)), - tuple(student_list), - as_dict=1, - ) - - for student in students: - if student.student in [d.student for d in inactive_students]: - students.remove(student) - - if students: - return students - else: - frappe.throw(_("No students Found")) - - @frappe.whitelist() - def enroll_students(self): - total = len(self.students) - for i, stud in enumerate(self.students): - frappe.publish_realtime( - "program_enrollment_tool", dict(progress=[i + 1, total]), user=frappe.session.user - ) - if stud.student: - prog_enrollment = frappe.new_doc("Program Enrollment") - prog_enrollment.student = stud.student - prog_enrollment.student_name = stud.student_name - prog_enrollment.student_category = stud.student_category - prog_enrollment.program = self.new_program - prog_enrollment.academic_year = self.new_academic_year - prog_enrollment.academic_term = self.new_academic_term - prog_enrollment.student_batch_name = ( - stud.student_batch_name if stud.student_batch_name else self.new_student_batch - ) - prog_enrollment.save() - elif stud.student_applicant: - prog_enrollment = enroll_student(stud.student_applicant) - prog_enrollment.academic_year = self.academic_year - prog_enrollment.academic_term = self.academic_term - prog_enrollment.student_batch_name = ( - stud.student_batch_name if stud.student_batch_name else self.new_student_batch - ) - prog_enrollment.save() - frappe.msgprint(_("{0} Students have been enrolled").format(total)) diff --git a/erpnext/education/doctype/program_enrollment_tool/test_program_enrollment_tool.py b/erpnext/education/doctype/program_enrollment_tool/test_program_enrollment_tool.py deleted file mode 100644 index e806792eec..0000000000 --- a/erpnext/education/doctype/program_enrollment_tool/test_program_enrollment_tool.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestProgramEnrollmentTool(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/program_enrollment_tool_student/__init__.py b/erpnext/education/doctype/program_enrollment_tool_student/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/program_enrollment_tool_student/program_enrollment_tool_student.json b/erpnext/education/doctype/program_enrollment_tool_student/program_enrollment_tool_student.json deleted file mode 100644 index 1d7497387f..0000000000 --- a/erpnext/education/doctype/program_enrollment_tool_student/program_enrollment_tool_student.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "actions": [], - "creation": "2016-06-10 03:29:02.539914", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "student_applicant", - "student", - "student_name", - "column_break_3", - "student_batch_name", - "student_category" - ], - "fields": [ - { - "fieldname": "student_applicant", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Student Applicant", - "options": "Student Applicant" - }, - { - "fieldname": "student", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Student", - "options": "Student" - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fieldname": "student_name", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Student Name", - "read_only": 1 - }, - { - "fieldname": "student_batch_name", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Student Batch Name", - "options": "Student Batch Name" - }, - { - "fieldname": "student_category", - "fieldtype": "Link", - "label": "Student Category", - "options": "Student Category", - "read_only": 1 - } - ], - "istable": 1, - "links": [], - "modified": "2021-07-29 18:19:54.471594", - "modified_by": "Administrator", - "module": "Education", - "name": "Program Enrollment Tool Student", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "restrict_to_domain": "Education", - "sort_field": "modified", - "sort_order": "DESC" -} \ No newline at end of file diff --git a/erpnext/education/doctype/program_enrollment_tool_student/program_enrollment_tool_student.py b/erpnext/education/doctype/program_enrollment_tool_student/program_enrollment_tool_student.py deleted file mode 100644 index b37e5d343e..0000000000 --- a/erpnext/education/doctype/program_enrollment_tool_student/program_enrollment_tool_student.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class ProgramEnrollmentToolStudent(Document): - pass diff --git a/erpnext/education/doctype/program_fee/__init__.py b/erpnext/education/doctype/program_fee/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/program_fee/program_fee.json b/erpnext/education/doctype/program_fee/program_fee.json deleted file mode 100644 index d45e4bd240..0000000000 --- a/erpnext/education/doctype/program_fee/program_fee.json +++ /dev/null @@ -1,224 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-05-19 05:52:56.322125", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "academic_term", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Academic Term", - "length": 0, - "no_copy": 0, - "options": "Academic Term", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "fee_structure", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Fee Structure", - "length": 0, - "no_copy": 0, - "options": "Fee Structure", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student_category", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Student Category", - "length": 0, - "no_copy": 0, - "options": "Student Category", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_3", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "due_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Due Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Amount", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2017-11-10 19:07:10.426335", - "modified_by": "Administrator", - "module": "Education", - "name": "Program Fee", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/program_fee/program_fee.py b/erpnext/education/doctype/program_fee/program_fee.py deleted file mode 100644 index e9a0be102c..0000000000 --- a/erpnext/education/doctype/program_fee/program_fee.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class ProgramFee(Document): - pass diff --git a/erpnext/education/doctype/question/__init__.py b/erpnext/education/doctype/question/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/question/question.js b/erpnext/education/doctype/question/question.js deleted file mode 100644 index 01b3091b58..0000000000 --- a/erpnext/education/doctype/question/question.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Question', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/question/question.json b/erpnext/education/doctype/question/question.json deleted file mode 100644 index e396760616..0000000000 --- a/erpnext/education/doctype/question/question.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "allow_import": 1, - "autoname": "format:QUESTION-{#####}", - "creation": "2018-10-01 15:58:00.696815", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "question", - "options", - "question_type" - ], - "fields": [ - { - "fieldname": "question", - "fieldtype": "Text Editor", - "in_list_view": 1, - "label": "Question", - "reqd": 1 - }, - { - "fieldname": "options", - "fieldtype": "Table", - "label": "Options", - "options": "Options", - "reqd": 1 - }, - { - "fieldname": "question_type", - "fieldtype": "Select", - "in_standard_filter": 1, - "label": "Type", - "options": "\nSingle Correct Answer\nMultiple Correct Answer", - "read_only": 1 - } - ], - "modified": "2020-09-24 18:39:21.880974", - "modified_by": "Administrator", - "module": "Education", - "name": "Question", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "share": 1, - "write": 1 - }, - { - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "LMS User", - "share": 1 - } - ], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC" -} diff --git a/erpnext/education/doctype/question/question.py b/erpnext/education/doctype/question/question.py deleted file mode 100644 index 99910b3c90..0000000000 --- a/erpnext/education/doctype/question/question.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document - - -class Question(Document): - def validate(self): - self.check_at_least_one_option() - self.check_minimum_one_correct_answer() - self.set_question_type() - - def check_at_least_one_option(self): - if len(self.options) <= 1: - frappe.throw(_("A question must have more than one options")) - else: - pass - - def check_minimum_one_correct_answer(self): - correct_options = [option.is_correct for option in self.options] - if bool(sum(correct_options)): - pass - else: - frappe.throw(_("A qustion must have at least one correct options")) - - def set_question_type(self): - correct_options = [option for option in self.options if option.is_correct] - if len(correct_options) > 1: - self.question_type = "Multiple Correct Answer" - else: - self.question_type = "Single Correct Answer" - - def get_answer(self): - options = self.options - answers = [item.name for item in options if item.is_correct == True] - if len(answers) == 0: - frappe.throw(_("No correct answer is set for {0}").format(self.name)) - return None - elif len(answers) == 1: - return answers[0] - else: - return answers diff --git a/erpnext/education/doctype/question/test_question.py b/erpnext/education/doctype/question/test_question.py deleted file mode 100644 index 7506d84a09..0000000000 --- a/erpnext/education/doctype/question/test_question.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestQuestion(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/quiz/__init__.py b/erpnext/education/doctype/quiz/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/quiz/quiz.js b/erpnext/education/doctype/quiz/quiz.js deleted file mode 100644 index 320869be31..0000000000 --- a/erpnext/education/doctype/quiz/quiz.js +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Quiz', { - refresh: function(frm) { - if (!frm.doc.__islocal) { - frm.add_custom_button(__('Add to Topics'), function() { - frm.trigger('add_quiz_to_topics'); - }, __('Action')); - } - }, - - validate: function(frm){ - frm.events.check_duplicate_question(frm.doc.question); - }, - - check_duplicate_question: function(questions_data){ - var questions = []; - questions_data.forEach(function(q){ - questions.push(q.question_link); - }); - var questions_set = new Set(questions); - if (questions.length != questions_set.size) { - frappe.throw(__('The question cannot be duplicate')); - } - }, - - add_quiz_to_topics: function(frm) { - get_topics_without_quiz(frm.doc.name).then(r => { - if (r.message.length) { - frappe.prompt([ - { - fieldname: 'topics', - label: __('Topics'), - fieldtype: 'MultiSelectPills', - get_data: function() { - return r.message; - } - } - ], - function(data) { - frappe.call({ - method: 'erpnext.education.doctype.topic.topic.add_content_to_topics', - args: { - 'content_type': 'Quiz', - 'content': frm.doc.name, - 'topics': data.topics, - }, - callback: function(r) { - if (!r.exc) { - frm.reload_doc(); - } - }, - freeze: true, - freeze_message: __('...Adding Quiz to Topics') - }); - }, __('Add Quiz to Topics'), __('Add')); - } else { - frappe.msgprint(__('This quiz is already added to the existing topics')); - } - }); - } -}); - -let get_topics_without_quiz = function(quiz) { - return frappe.call({ - type: 'GET', - method: 'erpnext.education.doctype.quiz.quiz.get_topics_without_quiz', - args: {'quiz': quiz} - }); -}; diff --git a/erpnext/education/doctype/quiz/quiz.json b/erpnext/education/doctype/quiz/quiz.json deleted file mode 100644 index 16d7d7e4bf..0000000000 --- a/erpnext/education/doctype/quiz/quiz.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "actions": [], - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:title", - "creation": "2018-10-17 05:52:50.149904", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "title", - "question", - "quiz_configuration_section", - "passing_score", - "max_attempts", - "grading_basis", - "column_break_7", - "is_time_bound", - "duration" - ], - "fields": [ - { - "fieldname": "title", - "fieldtype": "Data", - "label": "Title", - "reqd": 1, - "unique": 1 - }, - { - "fieldname": "question", - "fieldtype": "Table", - "label": "Question", - "options": "Quiz Question", - "reqd": 1 - }, - { - "fieldname": "quiz_configuration_section", - "fieldtype": "Section Break", - "label": "Quiz Configuration" - }, - { - "default": "75", - "description": "Score out of 100", - "fieldname": "passing_score", - "fieldtype": "Float", - "in_list_view": 1, - "label": "Passing Score", - "reqd": 1 - }, - { - "default": "1", - "description": "Enter 0 to waive limit", - "fieldname": "max_attempts", - "fieldtype": "Int", - "in_list_view": 1, - "label": "Max Attempts", - "reqd": 1 - }, - { - "default": "Latest Highest Score", - "fieldname": "grading_basis", - "fieldtype": "Select", - "label": "Grading Basis", - "options": "Latest Highest Score\nLatest Attempt" - }, - { - "default": "0", - "fieldname": "is_time_bound", - "fieldtype": "Check", - "label": "Is Time-Bound" - }, - { - "depends_on": "is_time_bound", - "fieldname": "duration", - "fieldtype": "Duration", - "label": "Duration" - }, - { - "fieldname": "column_break_7", - "fieldtype": "Column Break" - } - ], - "links": [], - "modified": "2020-12-24 15:41:35.043262", - "modified_by": "Administrator", - "module": "Education", - "name": "Quiz", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "write": 1 - }, - { - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "LMS User", - "share": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "share": 1, - "write": 1 - } - ], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/education/doctype/quiz/quiz.py b/erpnext/education/doctype/quiz/quiz.py deleted file mode 100644 index 7a9cdf3d9a..0000000000 --- a/erpnext/education/doctype/quiz/quiz.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document - - -class Quiz(Document): - def validate(self): - if self.passing_score > 100: - frappe.throw(_("Passing Score value should be between 0 and 100")) - - def allowed_attempt(self, enrollment, quiz_name): - if self.max_attempts == 0: - return True - - try: - if ( - len(frappe.get_all("Quiz Activity", {"enrollment": enrollment.name, "quiz": quiz_name})) - >= self.max_attempts - ): - frappe.msgprint(_("Maximum attempts for this quiz reached!")) - return False - else: - return True - except Exception as e: - return False - - def evaluate(self, response_dict, quiz_name): - questions = [frappe.get_doc("Question", question.question_link) for question in self.question] - answers = {q.name: q.get_answer() for q in questions} - result = {} - for key in answers: - try: - if isinstance(response_dict[key], list): - is_correct = compare_list_elementwise(response_dict[key], answers[key]) - else: - is_correct = response_dict[key] == answers[key] - except Exception as e: - is_correct = False - result[key] = is_correct - score = (sum(result.values()) * 100) / len(answers) - if score >= self.passing_score: - status = "Pass" - else: - status = "Fail" - return result, score, status - - def get_questions(self): - return [frappe.get_doc("Question", question.question_link) for question in self.question] - - -def compare_list_elementwise(*args): - try: - if all(len(args[0]) == len(_arg) for _arg in args[1:]): - return all(all([element in (item) for element in args[0]]) for item in args[1:]) - else: - return False - except TypeError: - frappe.throw(_("Compare List function takes on list arguments")) - - -@frappe.whitelist() -def get_topics_without_quiz(quiz): - data = [] - for entry in frappe.db.get_all("Topic"): - topic = frappe.get_doc("Topic", entry.name) - topic_contents = [tc.content for tc in topic.topic_content] - if not topic_contents or quiz not in topic_contents: - data.append(topic.name) - return data diff --git a/erpnext/education/doctype/quiz/test_quiz.py b/erpnext/education/doctype/quiz/test_quiz.py deleted file mode 100644 index a69a0c1d58..0000000000 --- a/erpnext/education/doctype/quiz/test_quiz.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestQuiz(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/quiz_activity/__init__.py b/erpnext/education/doctype/quiz_activity/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/quiz_activity/quiz_activity.js b/erpnext/education/doctype/quiz_activity/quiz_activity.js deleted file mode 100644 index f6ba12ca4d..0000000000 --- a/erpnext/education/doctype/quiz_activity/quiz_activity.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Quiz Activity', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/quiz_activity/quiz_activity.json b/erpnext/education/doctype/quiz_activity/quiz_activity.json deleted file mode 100644 index 742c88754a..0000000000 --- a/erpnext/education/doctype/quiz_activity/quiz_activity.json +++ /dev/null @@ -1,163 +0,0 @@ -{ - "actions": [], - "autoname": "format:EDU-QA-{YYYY}-{#####}", - "beta": 1, - "creation": "2018-10-15 15:48:40.482821", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "enrollment", - "student", - "column_break_3", - "course", - "section_break_5", - "quiz", - "column_break_7", - "status", - "section_break_9", - "result", - "section_break_11", - "activity_date", - "score", - "column_break_14", - "time_taken" - ], - "fields": [ - { - "fieldname": "enrollment", - "fieldtype": "Link", - "label": "Enrollment", - "options": "Course Enrollment", - "set_only_once": 1 - }, - { - "fetch_from": "enrollment.student", - "fieldname": "student", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Student", - "options": "Student", - "read_only": 1 - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fetch_from": "enrollment.course", - "fieldname": "course", - "fieldtype": "Link", - "label": "Course", - "options": "Course", - "read_only": 1, - "set_only_once": 1 - }, - { - "fieldname": "section_break_5", - "fieldtype": "Section Break" - }, - { - "fieldname": "quiz", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Quiz", - "options": "Quiz", - "set_only_once": 1 - }, - { - "fieldname": "column_break_7", - "fieldtype": "Column Break" - }, - { - "fieldname": "status", - "fieldtype": "Select", - "label": "Status", - "options": "\nPass\nFail", - "read_only": 1 - }, - { - "fieldname": "section_break_9", - "fieldtype": "Section Break" - }, - { - "fieldname": "result", - "fieldtype": "Table", - "label": "Result", - "options": "Quiz Result", - "set_only_once": 1 - }, - { - "fieldname": "activity_date", - "fieldtype": "Data", - "label": "Activity Date", - "set_only_once": 1 - }, - { - "fieldname": "score", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Score", - "set_only_once": 1 - }, - { - "fieldname": "time_taken", - "fieldtype": "Duration", - "label": "Time Taken", - "set_only_once": 1 - }, - { - "fieldname": "section_break_11", - "fieldtype": "Section Break" - }, - { - "fieldname": "column_break_14", - "fieldtype": "Column Break" - } - ], - "links": [], - "modified": "2020-12-24 15:41:20.085380", - "modified_by": "Administrator", - "module": "Education", - "name": "Quiz Activity", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "LMS User", - "share": 1, - "write": 1 - }, - { - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "share": 1 - } - ], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/education/doctype/quiz_activity/quiz_activity.py b/erpnext/education/doctype/quiz_activity/quiz_activity.py deleted file mode 100644 index a67f82fe07..0000000000 --- a/erpnext/education/doctype/quiz_activity/quiz_activity.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class QuizActivity(Document): - pass diff --git a/erpnext/education/doctype/quiz_activity/test_quiz_activity.py b/erpnext/education/doctype/quiz_activity/test_quiz_activity.py deleted file mode 100644 index 1040c1a869..0000000000 --- a/erpnext/education/doctype/quiz_activity/test_quiz_activity.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestQuizActivity(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/quiz_question/__init__.py b/erpnext/education/doctype/quiz_question/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/quiz_question/quiz_question.json b/erpnext/education/doctype/quiz_question/quiz_question.json deleted file mode 100644 index aab07a3e6b..0000000000 --- a/erpnext/education/doctype/quiz_question/quiz_question.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "allow_rename": 1, - "creation": "2018-10-17 06:13:00.098883", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "question_link", - "question" - ], - "fields": [ - { - "fieldname": "question_link", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Question Link", - "options": "Question", - "reqd": 1 - }, - { - "fetch_from": "question_link.question", - "fieldname": "question", - "fieldtype": "Text Editor", - "in_list_view": 1, - "label": "Question", - "read_only": 1 - } - ], - "istable": 1, - "modified": "2020-09-24 12:24:02.312577", - "modified_by": "Administrator", - "module": "Education", - "name": "Quiz Question", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} diff --git a/erpnext/education/doctype/quiz_question/quiz_question.py b/erpnext/education/doctype/quiz_question/quiz_question.py deleted file mode 100644 index 91641ebb30..0000000000 --- a/erpnext/education/doctype/quiz_question/quiz_question.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class QuizQuestion(Document): - pass diff --git a/erpnext/education/doctype/quiz_result/__init__.py b/erpnext/education/doctype/quiz_result/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/quiz_result/quiz_result.js b/erpnext/education/doctype/quiz_result/quiz_result.js deleted file mode 100644 index a018749e69..0000000000 --- a/erpnext/education/doctype/quiz_result/quiz_result.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Quiz Result', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/quiz_result/quiz_result.json b/erpnext/education/doctype/quiz_result/quiz_result.json deleted file mode 100644 index 67c7e2d449..0000000000 --- a/erpnext/education/doctype/quiz_result/quiz_result.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "creation": "2018-10-15 15:52:25.766374", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "question", - "selected_option", - "quiz_result" - ], - "fields": [ - { - "fieldname": "question", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Question", - "options": "Question", - "read_only": 1, - "reqd": 1, - "set_only_once": 1 - }, - { - "fieldname": "selected_option", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Selected Option", - "read_only": 1, - "set_only_once": 1 - }, - { - "fieldname": "quiz_result", - "fieldtype": "Select", - "in_list_view": 1, - "label": "Result", - "options": "\nCorrect\nWrong", - "read_only": 1, - "reqd": 1, - "set_only_once": 1 - } - ], - "istable": 1, - "modified": "2019-06-03 12:52:32.267392", - "modified_by": "Administrator", - "module": "Education", - "name": "Quiz Result", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/education/doctype/quiz_result/quiz_result.py b/erpnext/education/doctype/quiz_result/quiz_result.py deleted file mode 100644 index 615281bad2..0000000000 --- a/erpnext/education/doctype/quiz_result/quiz_result.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class QuizResult(Document): - pass diff --git a/erpnext/education/doctype/quiz_result/test_quiz_result.py b/erpnext/education/doctype/quiz_result/test_quiz_result.py deleted file mode 100644 index 12098a77ff..0000000000 --- a/erpnext/education/doctype/quiz_result/test_quiz_result.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestQuizResult(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/room/__init__.py b/erpnext/education/doctype/room/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/room/room.js b/erpnext/education/doctype/room/room.js deleted file mode 100644 index 1263b60ced..0000000000 --- a/erpnext/education/doctype/room/room.js +++ /dev/null @@ -1,2 +0,0 @@ -frappe.ui.form.on("Room", { -}); diff --git a/erpnext/education/doctype/room/room.json b/erpnext/education/doctype/room/room.json deleted file mode 100644 index 888a0fa097..0000000000 --- a/erpnext/education/doctype/room/room.json +++ /dev/null @@ -1,161 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 0, - "autoname": "HTL-ROOM-.YYYY.-.#####", - "beta": 0, - "creation": "2015-09-09 16:20:14.613061", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 0, - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "room_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Room Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "room_number", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Room Number", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "seating_capacity", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Seating Capacity", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "menu_index": 0, - "modified": "2018-08-21 16:15:46.096492", - "modified_by": "Administrator", - "module": "Education", - "name": "Room", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "room_name", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/room/room.py b/erpnext/education/doctype/room/room.py deleted file mode 100644 index a2a89805a8..0000000000 --- a/erpnext/education/doctype/room/room.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class Room(Document): - pass diff --git a/erpnext/education/doctype/room/room_dashboard.py b/erpnext/education/doctype/room/room_dashboard.py deleted file mode 100644 index dfc295cc44..0000000000 --- a/erpnext/education/doctype/room/room_dashboard.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - -from frappe import _ - - -def get_data(): - return { - "fieldname": "room", - "transactions": [ - {"label": _("Course"), "items": ["Course Schedule"]}, - {"label": _("Assessment"), "items": ["Assessment Plan"]}, - ], - } diff --git a/erpnext/education/doctype/room/test_records.json b/erpnext/education/doctype/room/test_records.json deleted file mode 100644 index 6edf076808..0000000000 --- a/erpnext/education/doctype/room/test_records.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "room_name": "_Test Room", - "room_number": "1001", - "seating_capacity": 100 - }, - { - "room_name": "_Test Room 1", - "room_number": "1002", - "seating_capacity": 100 - }, - { - "room_name": "_Test Room 2", - "room_number": "1003", - "seating_capacity": 100 - } -] \ No newline at end of file diff --git a/erpnext/education/doctype/room/test_room.py b/erpnext/education/doctype/room/test_room.py deleted file mode 100644 index ea0baf2137..0000000000 --- a/erpnext/education/doctype/room/test_room.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Room') - - -class TestRoom(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/school_house/__init__.py b/erpnext/education/doctype/school_house/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/school_house/school_house.js b/erpnext/education/doctype/school_house/school_house.js deleted file mode 100644 index cf1dcd4c3c..0000000000 --- a/erpnext/education/doctype/school_house/school_house.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('School House', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/school_house/school_house.json b/erpnext/education/doctype/school_house/school_house.json deleted file mode 100644 index 8a653a9730..0000000000 --- a/erpnext/education/doctype/school_house/school_house.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "field:house_name", - "beta": 0, - "creation": "2017-03-27 15:19:54.672995", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "house_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "House Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2017-11-10 19:05:06.419022", - "modified_by": "Administrator", - "module": "Education", - "name": "School House", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/school_house/school_house.py b/erpnext/education/doctype/school_house/school_house.py deleted file mode 100644 index 52e0508758..0000000000 --- a/erpnext/education/doctype/school_house/school_house.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class SchoolHouse(Document): - pass diff --git a/erpnext/education/doctype/school_house/test_school_house.py b/erpnext/education/doctype/school_house/test_school_house.py deleted file mode 100644 index 7fe12d7436..0000000000 --- a/erpnext/education/doctype/school_house/test_school_house.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestSchoolHouse(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/student/__init__.py b/erpnext/education/doctype/student/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student/student.js b/erpnext/education/doctype/student/student.js deleted file mode 100644 index aead556dc9..0000000000 --- a/erpnext/education/doctype/student/student.js +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Student', { - setup: function(frm) { - frm.add_fetch('guardian', 'guardian_name', 'guardian_name'); - frm.add_fetch('student', 'title', 'full_name'); - frm.add_fetch('student', 'gender', 'gender'); - frm.add_fetch('student', 'date_of_birth', 'date_of_birth'); - - frm.set_query('student', 'siblings', function(doc) { - return { - 'filters': { - 'name': ['!=', doc.name] - } - }; - }) - }, - refresh: function(frm) { - if(!frm.is_new()) { - - // custom buttons - frm.add_custom_button(__('Accounting Ledger'), function() { - frappe.set_route('query-report', 'General Ledger', - {party_type:'Student', party:frm.doc.name}); - }); - } - - frappe.db.get_value('Education Settings', {name: 'Education Settings'}, 'user_creation_skip', (r) => { - if (cint(r.user_creation_skip) !== 1) { - frm.set_df_property('student_email_id', 'reqd', 1); - } - }); - } -}); - -frappe.ui.form.on('Student Guardian', { - guardians_add: function(frm){ - frm.fields_dict['guardians'].grid.get_field('guardian').get_query = function(doc){ - let guardian_list = []; - if(!doc.__islocal) guardian_list.push(doc.guardian); - $.each(doc.guardians, function(idx, val){ - if (val.guardian) guardian_list.push(val.guardian); - }); - return { filters: [['Guardian', 'name', 'not in', guardian_list]] }; - }; - } -}); - - -frappe.ui.form.on('Student Sibling', { - siblings_add: function(frm){ - frm.fields_dict['siblings'].grid.get_field('student').get_query = function(doc){ - let sibling_list = [frm.doc.name]; - $.each(doc.siblings, function(idx, val){ - if (val.student && val.studying_in_same_institute == 'YES') { - sibling_list.push(val.student); - } - }); - return { filters: [['Student', 'name', 'not in', sibling_list]] }; - }; - } -}); diff --git a/erpnext/education/doctype/student/student.json b/erpnext/education/doctype/student/student.json deleted file mode 100644 index 8ba9a7fa11..0000000000 --- a/erpnext/education/doctype/student/student.json +++ /dev/null @@ -1,304 +0,0 @@ -{ - "actions": [], - "allow_import": 1, - "allow_rename": 1, - "autoname": "naming_series:", - "creation": "2015-09-07 13:00:55.938280", - "doctype": "DocType", - "document_type": "Document", - "engine": "InnoDB", - "field_order": [ - "section_break_1", - "enabled", - "section_break_3", - "first_name", - "middle_name", - "last_name", - "user", - "column_break_4", - "naming_series", - "student_email_id", - "student_mobile_number", - "joining_date", - "image", - "section_break_7", - "date_of_birth", - "blood_group", - "column_break_3", - "gender", - "nationality", - "student_applicant", - "section_break_22", - "address_line_1", - "address_line_2", - "pincode", - "column_break_20", - "city", - "state", - "section_break_18", - "guardians", - "section_break_20", - "siblings", - "exit", - "date_of_leaving", - "leaving_certificate_number", - "column_break_31", - "reason_for_leaving", - "title" - ], - "fields": [ - { - "fieldname": "section_break_1", - "fieldtype": "Section Break" - }, - { - "default": "1", - "fieldname": "enabled", - "fieldtype": "Check", - "label": "Enabled" - }, - { - "fieldname": "section_break_3", - "fieldtype": "Section Break" - }, - { - "fieldname": "first_name", - "fieldtype": "Data", - "in_global_search": 1, - "label": "First Name", - "reqd": 1 - }, - { - "fieldname": "middle_name", - "fieldtype": "Data", - "label": "Middle Name" - }, - { - "fieldname": "last_name", - "fieldtype": "Data", - "in_global_search": 1, - "label": "Last Name" - }, - { - "fieldname": "user", - "fieldtype": "Link", - "label": "User ID", - "options": "User" - }, - { - "fieldname": "column_break_4", - "fieldtype": "Column Break" - }, - { - "fieldname": "naming_series", - "fieldtype": "Select", - "label": "Naming Series", - "no_copy": 1, - "options": "EDU-STU-.YYYY.-", - "set_only_once": 1 - }, - { - "fieldname": "student_email_id", - "fieldtype": "Data", - "in_global_search": 1, - "label": "Student Email Address", - "unique": 1 - }, - { - "fieldname": "student_mobile_number", - "fieldtype": "Data", - "in_global_search": 1, - "label": "Student Mobile Number" - }, - { - "default": "Today", - "fieldname": "joining_date", - "fieldtype": "Date", - "in_list_view": 1, - "label": "Joining Date" - }, - { - "fieldname": "image", - "fieldtype": "Attach Image", - "hidden": 1, - "label": "Image", - "width": "10" - }, - { - "fieldname": "section_break_7", - "fieldtype": "Section Break", - "label": "Personal Details" - }, - { - "fieldname": "date_of_birth", - "fieldtype": "Date", - "label": "Date of Birth" - }, - { - "fieldname": "blood_group", - "fieldtype": "Select", - "label": "Blood Group", - "options": "\nA+\nA-\nB+\nB-\nO+\nO-\nAB+\nAB-" - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fieldname": "gender", - "fieldtype": "Link", - "label": "Gender", - "options": "Gender" - }, - { - "fieldname": "nationality", - "fieldtype": "Data", - "label": "Nationality" - }, - { - "fieldname": "student_applicant", - "fieldtype": "Link", - "label": "Student Applicant", - "options": "Student Applicant", - "read_only": 1 - }, - { - "fieldname": "section_break_22", - "fieldtype": "Section Break", - "label": "Home Address" - }, - { - "fieldname": "address_line_1", - "fieldtype": "Data", - "label": "Address Line 1" - }, - { - "fieldname": "address_line_2", - "fieldtype": "Data", - "label": "Address Line 2" - }, - { - "fieldname": "pincode", - "fieldtype": "Data", - "label": "Pincode" - }, - { - "fieldname": "column_break_20", - "fieldtype": "Column Break" - }, - { - "fieldname": "city", - "fieldtype": "Data", - "label": "City" - }, - { - "fieldname": "state", - "fieldtype": "Data", - "label": "State" - }, - { - "fieldname": "section_break_18", - "fieldtype": "Section Break", - "label": "Guardian Details" - }, - { - "fieldname": "guardians", - "fieldtype": "Table", - "label": "Guardians", - "options": "Student Guardian" - }, - { - "collapsible": 1, - "fieldname": "section_break_20", - "fieldtype": "Section Break", - "label": "Sibling Details", - "options": "Country" - }, - { - "fieldname": "siblings", - "fieldtype": "Table", - "label": "Siblings", - "options": "Student Sibling" - }, - { - "collapsible": 1, - "fieldname": "exit", - "fieldtype": "Section Break", - "label": "Exit" - }, - { - "fieldname": "date_of_leaving", - "fieldtype": "Date", - "label": "Date of Leaving" - }, - { - "fieldname": "leaving_certificate_number", - "fieldtype": "Data", - "label": "Leaving Certificate Number" - }, - { - "fieldname": "column_break_31", - "fieldtype": "Column Break" - }, - { - "fieldname": "reason_for_leaving", - "fieldtype": "Text", - "label": "Reason For Leaving" - }, - { - "fieldname": "title", - "fieldtype": "Data", - "hidden": 1, - "label": "Title" - } - ], - "image_field": "image", - "links": [], - "modified": "2020-09-07 19:28:08.914568", - "modified_by": "Administrator", - "module": "Education", - "name": "Student", - "owner": "Administrator", - "permissions": [ - { - "read": 1, - "role": "Instructor" - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "import": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "write": 1 - }, - { - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Student", - "share": 1 - }, - { - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "LMS User", - "share": 1 - } - ], - "restrict_to_domain": "Education", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "title" -} \ No newline at end of file diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py deleted file mode 100644 index 712d742dee..0000000000 --- a/erpnext/education/doctype/student/student.py +++ /dev/null @@ -1,223 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.desk.form.linked_with import get_linked_doctypes -from frappe.model.document import Document -from frappe.utils import getdate, today - -from erpnext.education.utils import check_content_completion, check_quiz_completion - - -class Student(Document): - def validate(self): - self.title = " ".join(filter(None, [self.first_name, self.middle_name, self.last_name])) - self.validate_dates() - - if self.student_applicant: - self.check_unique() - self.update_applicant_status() - - if frappe.get_value("Student", self.name, "title") != self.title: - self.update_student_name_in_linked_doctype() - - def validate_dates(self): - for sibling in self.siblings: - if sibling.date_of_birth and getdate(sibling.date_of_birth) > getdate(): - frappe.throw( - _("Row {0}:Sibling Date of Birth cannot be greater than today.").format(sibling.idx) - ) - - if self.date_of_birth and getdate(self.date_of_birth) >= getdate(today()): - frappe.throw(_("Date of Birth cannot be greater than today.")) - - if self.date_of_birth and getdate(self.date_of_birth) >= getdate(self.joining_date): - frappe.throw(_("Date of Birth cannot be greater than Joining Date.")) - - if ( - self.joining_date - and self.date_of_leaving - and getdate(self.joining_date) > getdate(self.date_of_leaving) - ): - frappe.throw(_("Joining Date can not be greater than Leaving Date")) - - def update_student_name_in_linked_doctype(self): - linked_doctypes = get_linked_doctypes("Student") - for d in linked_doctypes: - meta = frappe.get_meta(d) - if not meta.issingle: - if "student_name" in [f.fieldname for f in meta.fields]: - frappe.db.sql( - """UPDATE `tab{0}` set student_name = %s where {1} = %s""".format( - d, linked_doctypes[d]["fieldname"][0] - ), - (self.title, self.name), - ) - - if "child_doctype" in linked_doctypes[d].keys() and "student_name" in [ - f.fieldname for f in frappe.get_meta(linked_doctypes[d]["child_doctype"]).fields - ]: - frappe.db.sql( - """UPDATE `tab{0}` set student_name = %s where {1} = %s""".format( - linked_doctypes[d]["child_doctype"], linked_doctypes[d]["fieldname"][0] - ), - (self.title, self.name), - ) - - def check_unique(self): - """Validates if the Student Applicant is Unique""" - student = frappe.db.sql( - "select name from `tabStudent` where student_applicant=%s and name!=%s", - (self.student_applicant, self.name), - ) - if student: - frappe.throw( - _("Student {0} exist against student applicant {1}").format( - student[0][0], self.student_applicant - ) - ) - - def after_insert(self): - if not frappe.get_single("Education Settings").get("user_creation_skip"): - self.create_student_user() - - def create_student_user(self): - """Create a website user for student creation if not already exists""" - if not frappe.db.exists("User", self.student_email_id): - student_user = frappe.get_doc( - { - "doctype": "User", - "first_name": self.first_name, - "last_name": self.last_name, - "email": self.student_email_id, - "gender": self.gender, - "send_welcome_email": 1, - "user_type": "Website User", - } - ) - student_user.flags.ignore_permissions = True - student_user.add_roles("Student") - student_user.save() - - def update_applicant_status(self): - """Updates Student Applicant status to Admitted""" - if self.student_applicant: - frappe.db.set_value( - "Student Applicant", self.student_applicant, "application_status", "Admitted" - ) - - def get_all_course_enrollments(self): - """Returns a list of course enrollments linked with the current student""" - course_enrollments = frappe.get_all( - "Course Enrollment", filters={"student": self.name}, fields=["course", "name"] - ) - if not course_enrollments: - return None - else: - enrollments = {item["course"]: item["name"] for item in course_enrollments} - return enrollments - - def get_program_enrollments(self): - """Returns a list of course enrollments linked with the current student""" - program_enrollments = frappe.get_all( - "Program Enrollment", filters={"student": self.name}, fields=["program"] - ) - if not program_enrollments: - return None - else: - enrollments = [item["program"] for item in program_enrollments] - return enrollments - - def get_topic_progress(self, course_enrollment_name, topic): - """ - Get Progress Dictionary of a student for a particular topic - :param self: Student Object - :param course_enrollment_name: Name of the Course Enrollment - :param topic: Topic DocType Object - """ - contents = topic.get_contents() - progress = [] - if contents: - for content in contents: - if content.doctype in ("Article", "Video"): - status = check_content_completion(content.name, content.doctype, course_enrollment_name) - progress.append( - {"content": content.name, "content_type": content.doctype, "is_complete": status} - ) - elif content.doctype == "Quiz": - status, score, result, time_taken = check_quiz_completion(content, course_enrollment_name) - progress.append( - { - "content": content.name, - "content_type": content.doctype, - "is_complete": status, - "score": score, - "result": result, - } - ) - return progress - - def enroll_in_program(self, program_name): - try: - enrollment = frappe.get_doc( - { - "doctype": "Program Enrollment", - "student": self.name, - "academic_year": frappe.get_last_doc("Academic Year").name, - "program": program_name, - "enrollment_date": frappe.utils.datetime.datetime.now(), - } - ) - enrollment.save(ignore_permissions=True) - except frappe.exceptions.ValidationError: - enrollment_name = frappe.get_list( - "Program Enrollment", filters={"student": self.name, "Program": program_name} - )[0].name - return frappe.get_doc("Program Enrollment", enrollment_name) - else: - enrollment.submit() - return enrollment - - def enroll_in_course(self, course_name, program_enrollment, enrollment_date=None): - if enrollment_date is None: - enrollment_date = frappe.utils.datetime.datetime.now() - try: - enrollment = frappe.get_doc( - { - "doctype": "Course Enrollment", - "student": self.name, - "course": course_name, - "program_enrollment": program_enrollment, - "enrollment_date": enrollment_date, - } - ) - enrollment.save(ignore_permissions=True) - except frappe.exceptions.ValidationError: - enrollment_name = frappe.get_list( - "Course Enrollment", - filters={ - "student": self.name, - "course": course_name, - "program_enrollment": program_enrollment, - }, - )[0].name - return frappe.get_doc("Course Enrollment", enrollment_name) - else: - return enrollment - - -def get_timeline_data(doctype, name): - """Return timeline for attendance""" - return dict( - frappe.db.sql( - """select unix_timestamp(`date`), count(*) - from `tabStudent Attendance` where - student=%s - and `date` > date_sub(curdate(), interval 1 year) - and docstatus = 1 and status = 'Present' - group by date""", - name, - ) - ) diff --git a/erpnext/education/doctype/student/student_dashboard.py b/erpnext/education/doctype/student/student_dashboard.py deleted file mode 100644 index bcc8521738..0000000000 --- a/erpnext/education/doctype/student/student_dashboard.py +++ /dev/null @@ -1,24 +0,0 @@ -from frappe import _ - - -def get_data(): - return { - "heatmap": True, - "heatmap_message": _("This is based on the attendance of this Student"), - "fieldname": "student", - "non_standard_fieldnames": {"Bank Account": "party"}, - "transactions": [ - {"label": _("Admission"), "items": ["Program Enrollment", "Course Enrollment"]}, - { - "label": _("Student Activity"), - "items": [ - "Student Log", - "Student Group", - ], - }, - {"label": _("Assessment"), "items": ["Assessment Result"]}, - {"label": _("Student LMS Activity"), "items": ["Course Activity", "Quiz Activity"]}, - {"label": _("Attendance"), "items": ["Student Attendance", "Student Leave Application"]}, - {"label": _("Fee"), "items": ["Fees", "Bank Account"]}, - ], - } diff --git a/erpnext/education/doctype/student/student_list.js b/erpnext/education/doctype/student/student_list.js deleted file mode 100644 index c1bce24d15..0000000000 --- a/erpnext/education/doctype/student/student_list.js +++ /dev/null @@ -1,3 +0,0 @@ -frappe.listview_settings['Student'] = { - add_fields: [ "image"] -} diff --git a/erpnext/education/doctype/student/test_records.json b/erpnext/education/doctype/student/test_records.json deleted file mode 100644 index 8ad3afa6a8..0000000000 --- a/erpnext/education/doctype/student/test_records.json +++ /dev/null @@ -1,35 +0,0 @@ -[ - { - "first_name": "_Test", - "middle_name": "Student", - "last_name": "Name", - "program": "TC101", - "date_of_birth": "2000-01-01", - "gender": "Male", - "student_email_id": "_test_student@example.com", - "blood_group": "A+" - - }, - { - "first_name": "_Test", - "middle_name": "Student", - "last_name": "Name 1", - "program": "TC101", - "date_of_birth": "2000-01-01", - "gender": "Male", - "student_email_id": "_test_student_1@example.com", - "blood_group": "A+" - - }, - { - "first_name": "_Test", - "middle_name": "Student", - "last_name": "Name 2", - "program": "TC101", - "date_of_birth": "2000-01-01", - "gender": "Female", - "student_email_id": "_test_student_2@example.com", - "blood_group": "A+" - - } -] \ No newline at end of file diff --git a/erpnext/education/doctype/student/test_student.py b/erpnext/education/doctype/student/test_student.py deleted file mode 100644 index 89449b0299..0000000000 --- a/erpnext/education/doctype/student/test_student.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and Contributors -# See license.txt - -import unittest - -import frappe - -from erpnext.education.doctype.program.test_program import make_program_and_linked_courses - -test_records = frappe.get_test_records("Student") - - -class TestStudent(unittest.TestCase): - def setUp(self): - create_student( - { - "first_name": "_Test Name", - "last_name": "_Test Last Name", - "email": "_test_student@example.com", - } - ) - make_program_and_linked_courses("_Test Program 1", ["_Test Course 1", "_Test Course 2"]) - - def test_create_student_user(self): - self.assertTrue(bool(frappe.db.exists("User", "_test_student@example.com"))) - frappe.db.rollback() - - def test_enroll_in_program(self): - student = get_student("_test_student@example.com") - enrollment = student.enroll_in_program("_Test Program 1") - test_enrollment = frappe.get_all( - "Program Enrollment", filters={"student": student.name, "Program": "_Test Program 1"} - ) - self.assertTrue(len(test_enrollment)) - self.assertEqual(test_enrollment[0]["name"], enrollment.name) - frappe.db.rollback() - - def test_get_program_enrollments(self): - student = get_student("_test_student@example.com") - enrollment = student.enroll_in_program("_Test Program 1") - program_enrollments = student.get_program_enrollments() - self.assertTrue("_Test Program 1" in program_enrollments) - frappe.db.rollback() - - def test_get_all_course_enrollments(self): - student = get_student("_test_student@example.com") - enrollment = student.enroll_in_program("_Test Program 1") - course_enrollments = student.get_all_course_enrollments() - self.assertTrue("_Test Course 1" in course_enrollments.keys()) - self.assertTrue("_Test Course 2" in course_enrollments.keys()) - frappe.db.rollback() - - def tearDown(self): - for entry in frappe.db.get_all("Course Enrollment"): - frappe.delete_doc("Course Enrollment", entry.name) - - for entry in frappe.db.get_all("Program Enrollment"): - doc = frappe.get_doc("Program Enrollment", entry.name) - doc.cancel() - doc.delete() - - -def create_student(student_dict): - student = get_student(student_dict["email"]) - if not student: - student = frappe.get_doc( - { - "doctype": "Student", - "first_name": student_dict["first_name"], - "last_name": student_dict["last_name"], - "student_email_id": student_dict["email"], - } - ).insert() - return student - - -def get_student(email): - try: - student_id = frappe.get_all("Student", {"student_email_id": email}, ["name"])[0].name - return frappe.get_doc("Student", student_id) - except IndexError: - return None diff --git a/erpnext/education/doctype/student_admission/__init__.py b/erpnext/education/doctype/student_admission/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_admission/student_admission.js b/erpnext/education/doctype/student_admission/student_admission.js deleted file mode 100644 index 2b6296726c..0000000000 --- a/erpnext/education/doctype/student_admission/student_admission.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Student Admission', { - program: function(frm) { - if (frm.doc.academic_year && frm.doc.program) { - frm.doc.route = frappe.model.scrub(frm.doc.program) + "-" + frappe.model.scrub(frm.doc.academic_year) - frm.refresh_field("route"); - } - }, - - academic_year: function(frm) { - frm.trigger("program"); - }, - - admission_end_date: function(frm) { - if(frm.doc.admission_end_date && frm.doc.admission_end_date <= frm.doc.admission_start_date){ - frm.set_value("admission_end_date", ""); - frappe.throw(__("Admission End Date should be greater than Admission Start Date.")); - } - } -}); diff --git a/erpnext/education/doctype/student_admission/student_admission.json b/erpnext/education/doctype/student_admission/student_admission.json deleted file mode 100644 index 75f21625b0..0000000000 --- a/erpnext/education/doctype/student_admission/student_admission.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "actions": [], - "allow_guest_to_view": 1, - "allow_rename": 1, - "creation": "2016-09-13 03:05:27.154713", - "doctype": "DocType", - "document_type": "Document", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "title", - "route", - "column_break_3", - "academic_year", - "admission_start_date", - "admission_end_date", - "published", - "enable_admission_application", - "section_break_5", - "program_details", - "introduction" - ], - "fields": [ - { - "fieldname": "title", - "fieldtype": "Data", - "label": "Title" - }, - { - "fieldname": "route", - "fieldtype": "Data", - "label": "Route", - "no_copy": 1, - "unique": 1 - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fieldname": "academic_year", - "fieldtype": "Link", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Academic Year", - "no_copy": 1, - "options": "Academic Year", - "reqd": 1 - }, - { - "fieldname": "admission_start_date", - "fieldtype": "Date", - "label": "Admission Start Date", - "mandatory_depends_on": "enable_admission_application", - "no_copy": 1 - }, - { - "fieldname": "admission_end_date", - "fieldtype": "Date", - "label": "Admission End Date", - "mandatory_depends_on": "enable_admission_application", - "no_copy": 1 - }, - { - "default": "0", - "fieldname": "published", - "fieldtype": "Check", - "label": "Publish on website" - }, - { - "fieldname": "section_break_5", - "fieldtype": "Section Break", - "label": "Eligibility and Details" - }, - { - "fieldname": "program_details", - "fieldtype": "Table", - "label": "Eligibility and Details", - "options": "Student Admission Program" - }, - { - "fieldname": "introduction", - "fieldtype": "Text Editor", - "label": "Introduction" - }, - { - "default": "0", - "depends_on": "published", - "fieldname": "enable_admission_application", - "fieldtype": "Check", - "label": "Enable Admission Application" - } - ], - "has_web_view": 1, - "is_published_field": "published", - "links": [], - "modified": "2020-09-18 00:14:54.615321", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Admission", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "write": 1 - } - ], - "restrict_to_domain": "Education", - "route": "admissions", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "title" -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_admission/student_admission.py b/erpnext/education/doctype/student_admission/student_admission.py deleted file mode 100644 index 6c775f0dff..0000000000 --- a/erpnext/education/doctype/student_admission/student_admission.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.utils import nowdate -from frappe.website.website_generator import WebsiteGenerator - - -class StudentAdmission(WebsiteGenerator): - def autoname(self): - if not self.title: - self.title = self.get_title() - self.name = self.title - - def validate(self): - if not self.route: # pylint: disable=E0203 - self.route = "admissions/" + "-".join(self.title.split(" ")) - - if self.enable_admission_application and not self.program_details: - frappe.throw(_("Please add programs to enable admission application.")) - - def get_context(self, context): - context.no_cache = 1 - context.show_sidebar = True - context.title = self.title - context.parents = [ - {"name": "admissions", "title": _("All Student Admissions"), "route": "admissions"} - ] - - def get_title(self): - return _("Admissions for {0}").format(self.academic_year) - - -def get_list_context(context=None): - context.update( - { - "show_sidebar": True, - "title": _("Student Admissions"), - "get_list": get_admission_list, - "row_template": "education/doctype/student_admission/templates/student_admission_row.html", - } - ) - - -def get_admission_list( - doctype, txt, filters, limit_start, limit_page_length=20, order_by="modified" -): - return frappe.db.sql( - """select name, title, academic_year, modified, admission_start_date, route, - admission_end_date from `tabStudent Admission` where published=1 and admission_end_date >= %s - order by admission_end_date asc limit {0}, {1} - """.format( - limit_start, limit_page_length - ), - [nowdate()], - as_dict=1, - ) diff --git a/erpnext/education/doctype/student_admission/templates/student_admission.html b/erpnext/education/doctype/student_admission/templates/student_admission.html deleted file mode 100644 index f9ddac086b..0000000000 --- a/erpnext/education/doctype/student_admission/templates/student_admission.html +++ /dev/null @@ -1,77 +0,0 @@ - -{% extends "templates/web.html" %} - -{% block breadcrumbs %} - {% include "templates/includes/breadcrumbs.html" %} -{% endblock %} - -{% block header %} -

{{ title }}

-{% endblock %} - -{% block page_content %} - {% set today = frappe.utils.getdate(frappe.utils.nowdate()) %} -
-
- Application will be closed soon - {% elif frappe.utils.getdate(doc.admission_end_date) > today >= frappe.utils.getdate(doc.admission_start_date)%} - green"> Application open - {% elif frappe.utils.getdate(doc.admission_start_date) > today %} - blue"> Application will open - {% else %} - gray - {% endif %} - -
-
- {{ _("Start on") }}: {{ frappe.format_date(admission_start_date) }}
- {{ _("End on") }}: {{ frappe.format_date(admission_end_date) }} -
-

- - {%- if introduction -%} -
{{ introduction }}
- {% endif %} - - {% if program_details %} -
-
-

Eligibility and Other Details:

- - - - - - - - - {%- if doc.enable_admission_application and frappe.utils.getdate(doc.admission_start_date) <= today -%} - - {% endif %} - - - - {% for row in program_details %} - - - - - - - {%- if doc.enable_admission_application and frappe.utils.getdate(doc.admission_start_date) <= today -%} - - {% endif %} - - {% endfor %} - -
Program/Std.DescriptionMinumum AgeMaximum AgeApplication Fee
{{ row.program }}
{{ row.description if row.description else '' }}
{{ row.min_age }}{{ row.max_age }}{{ row.application_fee }} - - {{ _("Apply Now") }} - -
-
- {% endif %} - -{% endblock %} diff --git a/erpnext/education/doctype/student_admission/templates/student_admission_row.html b/erpnext/education/doctype/student_admission/templates/student_admission_row.html deleted file mode 100644 index dc4587bc94..0000000000 --- a/erpnext/education/doctype/student_admission/templates/student_admission_row.html +++ /dev/null @@ -1,44 +0,0 @@ - diff --git a/erpnext/education/doctype/student_admission/test_student_admission.py b/erpnext/education/doctype/student_admission/test_student_admission.py deleted file mode 100644 index 82c720a305..0000000000 --- a/erpnext/education/doctype/student_admission/test_student_admission.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Student Admission') - - -class TestStudentAdmission(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/student_admission_program/__init__.py b/erpnext/education/doctype/student_admission_program/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_admission_program/student_admission_program.json b/erpnext/education/doctype/student_admission_program/student_admission_program.json deleted file mode 100644 index d14b9a4d91..0000000000 --- a/erpnext/education/doctype/student_admission_program/student_admission_program.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "actions": [], - "creation": "2017-09-15 12:59:43.207923", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "program", - "min_age", - "max_age", - "description", - "column_break_4", - "application_fee", - "applicant_naming_series" - ], - "fields": [ - { - "fieldname": "program", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Program", - "options": "Program" - }, - { - "fieldname": "column_break_4", - "fieldtype": "Column Break" - }, - { - "fieldname": "application_fee", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Application Fee" - }, - { - "fieldname": "applicant_naming_series", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Naming Series (for Student Applicant)" - }, - { - "fieldname": "min_age", - "fieldtype": "Int", - "in_list_view": 1, - "label": "Minimum Age" - }, - { - "fieldname": "max_age", - "fieldtype": "Int", - "in_list_view": 1, - "label": "Maximum Age" - }, - { - "fetch_from": "program.description", - "fetch_if_empty": 1, - "fieldname": "description", - "fieldtype": "Small Text", - "label": "Description" - } - ], - "istable": 1, - "links": [], - "modified": "2020-10-05 13:03:42.005985", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Admission Program", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "restrict_to_domain": "Education", - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_admission_program/student_admission_program.py b/erpnext/education/doctype/student_admission_program/student_admission_program.py deleted file mode 100644 index eba2239148..0000000000 --- a/erpnext/education/doctype/student_admission_program/student_admission_program.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class StudentAdmissionProgram(Document): - pass diff --git a/erpnext/education/doctype/student_applicant/__init__.py b/erpnext/education/doctype/student_applicant/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_applicant/student_applicant.js b/erpnext/education/doctype/student_applicant/student_applicant.js deleted file mode 100644 index 7b41a72174..0000000000 --- a/erpnext/education/doctype/student_applicant/student_applicant.js +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on("Student Applicant", { - setup: function(frm) { - frm.add_fetch("guardian", "guardian_name", "guardian_name"); - }, - - refresh: function(frm) { - if (frm.doc.application_status==="Applied" && frm.doc.docstatus===1 ) { - frm.add_custom_button(__("Approve"), function() { - frm.set_value("application_status", "Approved"); - frm.save_or_update(); - - }, 'Actions'); - - frm.add_custom_button(__("Reject"), function() { - frm.set_value("application_status", "Rejected"); - frm.save_or_update(); - }, 'Actions'); - } - - if (frm.doc.application_status === "Approved" && frm.doc.docstatus === 1) { - frm.add_custom_button(__("Enroll"), function() { - frm.events.enroll(frm) - }).addClass("btn-primary"); - - frm.add_custom_button(__("Reject"), function() { - frm.set_value("application_status", "Rejected"); - frm.save_or_update(); - }, 'Actions'); - } - - frappe.realtime.on("enroll_student_progress", function(data) { - if(data.progress) { - frappe.hide_msgprint(true); - frappe.show_progress(__("Enrolling student"), data.progress[0],data.progress[1]); - } - }); - - frappe.db.get_value("Education Settings", {name: "Education Settings"}, "user_creation_skip", (r) => { - if (cint(r.user_creation_skip) !== 1) { - frm.set_df_property("student_email_id", "reqd", 1); - } - }); - }, - - enroll: function(frm) { - frappe.model.open_mapped_doc({ - method: "erpnext.education.api.enroll_student", - frm: frm - }) - } -}); - -frappe.ui.form.on('Student Sibling', { - setup: function(frm) { - frm.add_fetch("student", "title", "full_name"); - frm.add_fetch("student", "gender", "gender"); - frm.add_fetch("student", "date_of_birth", "date_of_birth"); - } -}); diff --git a/erpnext/education/doctype/student_applicant/student_applicant.json b/erpnext/education/doctype/student_applicant/student_applicant.json deleted file mode 100644 index 95f9224a73..0000000000 --- a/erpnext/education/doctype/student_applicant/student_applicant.json +++ /dev/null @@ -1,300 +0,0 @@ -{ - "actions": [], - "allow_import": 1, - "autoname": "naming_series:", - "creation": "2015-09-11 11:50:09.740807", - "doctype": "DocType", - "document_type": "Document", - "engine": "InnoDB", - "field_order": [ - "first_name", - "middle_name", - "last_name", - "program", - "student_category", - "lms_only", - "paid", - "column_break_8", - "naming_series", - "application_status", - "application_date", - "academic_year", - "academic_term", - "student_admission", - "image", - "section_break_4", - "date_of_birth", - "gender", - "blood_group", - "column_break_12", - "student_email_id", - "student_mobile_number", - "nationality", - "home_address", - "address_line_1", - "address_line_2", - "pincode", - "column_break_23", - "city", - "state", - "section_break_20", - "guardians", - "section_break_21", - "siblings", - "section_break_23", - "title", - "amended_from" - ], - "fields": [ - { - "fieldname": "first_name", - "fieldtype": "Data", - "in_global_search": 1, - "label": "First Name", - "reqd": 1 - }, - { - "fieldname": "middle_name", - "fieldtype": "Data", - "label": "Middle Name" - }, - { - "fieldname": "last_name", - "fieldtype": "Data", - "in_global_search": 1, - "label": "Last Name" - }, - { - "fieldname": "program", - "fieldtype": "Link", - "in_filter": 1, - "in_global_search": 1, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Program", - "options": "Program", - "reqd": 1 - }, - { - "default": "0", - "fieldname": "lms_only", - "fieldtype": "Check", - "label": "LMS Only" - }, - { - "default": "0", - "fieldname": "paid", - "fieldtype": "Check", - "label": "Paid" - }, - { - "fieldname": "column_break_8", - "fieldtype": "Column Break" - }, - { - "fieldname": "naming_series", - "fieldtype": "Select", - "label": "Naming Series", - "no_copy": 1, - "options": "EDU-APP-.YYYY.-", - "set_only_once": 1 - }, - { - "allow_on_submit": 1, - "depends_on": "eval:doc.docstatus != 0", - "fieldname": "application_status", - "fieldtype": "Select", - "in_filter": 1, - "label": "Application Status", - "no_copy": 1, - "options": "Applied\nApproved\nRejected\nAdmitted" - }, - { - "default": "Today", - "fieldname": "application_date", - "fieldtype": "Date", - "label": "Application Date" - }, - { - "fieldname": "academic_year", - "fieldtype": "Link", - "label": "Academic Year", - "options": "Academic Year" - }, - { - "fieldname": "academic_term", - "fieldtype": "Link", - "label": "Academic Term", - "options": "Academic Term" - }, - { - "fieldname": "student_admission", - "fieldtype": "Link", - "label": "Student Admission", - "options": "Student Admission" - }, - { - "fieldname": "image", - "fieldtype": "Attach Image", - "hidden": 1, - "label": "Image" - }, - { - "fieldname": "section_break_4", - "fieldtype": "Section Break", - "label": "Personal Details" - }, - { - "fieldname": "date_of_birth", - "fieldtype": "Date", - "label": "Date of Birth" - }, - { - "fieldname": "gender", - "fieldtype": "Select", - "label": "Gender", - "options": "\nMale\nFemale" - }, - { - "fieldname": "blood_group", - "fieldtype": "Select", - "label": "Blood Group", - "options": "\nA+\nA-\nB+\nB-\nO+\nO-\nAB+\nAB-" - }, - { - "fieldname": "column_break_12", - "fieldtype": "Column Break" - }, - { - "fieldname": "student_email_id", - "fieldtype": "Data", - "label": "Student Email Address", - "options": "Email", - "unique": 1 - }, - { - "fieldname": "student_mobile_number", - "fieldtype": "Data", - "label": "Student Mobile Number" - }, - { - "fieldname": "nationality", - "fieldtype": "Data", - "label": "Nationality" - }, - { - "fieldname": "home_address", - "fieldtype": "Section Break", - "label": "Home Address" - }, - { - "fieldname": "address_line_1", - "fieldtype": "Data", - "label": "Address Line 1" - }, - { - "fieldname": "address_line_2", - "fieldtype": "Data", - "label": "Address Line 2" - }, - { - "fieldname": "pincode", - "fieldtype": "Data", - "label": "Pincode" - }, - { - "fieldname": "column_break_23", - "fieldtype": "Column Break" - }, - { - "fieldname": "city", - "fieldtype": "Data", - "label": "City" - }, - { - "fieldname": "state", - "fieldtype": "Data", - "label": "State" - }, - { - "collapsible": 1, - "fieldname": "section_break_20", - "fieldtype": "Section Break", - "label": "Guardian Details" - }, - { - "fieldname": "guardians", - "fieldtype": "Table", - "label": "Guardians", - "options": "Student Guardian" - }, - { - "collapsible": 1, - "fieldname": "section_break_21", - "fieldtype": "Section Break", - "label": "Sibling Details" - }, - { - "fieldname": "siblings", - "fieldtype": "Table", - "label": "Siblings", - "options": "Student Sibling" - }, - { - "fieldname": "section_break_23", - "fieldtype": "Section Break" - }, - { - "fieldname": "title", - "fieldtype": "Data", - "hidden": 1, - "label": "Title" - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Student Applicant", - "print_hide": 1, - "read_only": 1 - }, - { - "fieldname": "student_category", - "fieldtype": "Link", - "label": "Student Category", - "options": "Student Category" - } - ], - "image_field": "image", - "is_submittable": 1, - "links": [], - "modified": "2021-03-01 23:00:25.119241", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Applicant", - "owner": "Administrator", - "permissions": [ - { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "import": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "submit": 1, - "write": 1 - } - ], - "restrict_to_domain": "Education", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "title" -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_applicant/student_applicant.py b/erpnext/education/doctype/student_applicant/student_applicant.py deleted file mode 100644 index f04ebb0b0c..0000000000 --- a/erpnext/education/doctype/student_applicant/student_applicant.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.utils import add_years, date_diff, getdate, nowdate - - -class StudentApplicant(Document): - def autoname(self): - from frappe.model.naming import set_name_by_naming_series - - if self.student_admission: - naming_series = None - if self.program: - # set the naming series from the student admission if provided. - student_admission = get_student_admission_data(self.student_admission, self.program) - if student_admission: - naming_series = student_admission.get("applicant_naming_series") - else: - naming_series = None - else: - frappe.throw(_("Select the program first")) - - if naming_series: - self.naming_series = naming_series - - set_name_by_naming_series(self) - - def validate(self): - self.validate_dates() - self.title = " ".join(filter(None, [self.first_name, self.middle_name, self.last_name])) - - if self.student_admission and self.program and self.date_of_birth: - self.validation_from_student_admission() - - def validate_dates(self): - if self.date_of_birth and getdate(self.date_of_birth) >= getdate(): - frappe.throw(_("Date of Birth cannot be greater than today.")) - - def on_update_after_submit(self): - student = frappe.get_list("Student", filters={"student_applicant": self.name}) - if student: - frappe.throw( - _("Cannot change status as student {0} is linked with student application {1}").format( - student[0].name, self.name - ) - ) - - def on_submit(self): - if self.paid and not self.student_admission: - frappe.throw( - _("Please select Student Admission which is mandatory for the paid student applicant") - ) - - def validation_from_student_admission(self): - - student_admission = get_student_admission_data(self.student_admission, self.program) - - if ( - student_admission - and student_admission.min_age - and date_diff(nowdate(), add_years(getdate(self.date_of_birth), student_admission.min_age)) < 0 - ): - frappe.throw(_("Not eligible for the admission in this program as per Date Of Birth")) - - if ( - student_admission - and student_admission.max_age - and date_diff(nowdate(), add_years(getdate(self.date_of_birth), student_admission.max_age)) > 0 - ): - frappe.throw(_("Not eligible for the admission in this program as per Date Of Birth")) - - def on_payment_authorized(self, *args, **kwargs): - self.db_set("paid", 1) - - -def get_student_admission_data(student_admission, program): - - student_admission = frappe.db.sql( - """select sa.admission_start_date, sa.admission_end_date, - sap.program, sap.min_age, sap.max_age, sap.applicant_naming_series - from `tabStudent Admission` sa, `tabStudent Admission Program` sap - where sa.name = sap.parent and sa.name = %s and sap.program = %s""", - (student_admission, program), - as_dict=1, - ) - - if student_admission: - return student_admission[0] - else: - return None diff --git a/erpnext/education/doctype/student_applicant/student_applicant_list.js b/erpnext/education/doctype/student_applicant/student_applicant_list.js deleted file mode 100644 index c39d46ec63..0000000000 --- a/erpnext/education/doctype/student_applicant/student_applicant_list.js +++ /dev/null @@ -1,21 +0,0 @@ -frappe.listview_settings['Student Applicant'] = { - add_fields: [ "application_status", 'paid'], - has_indicator_for_draft: 1, - get_indicator: function(doc) { - if (doc.paid) { - return [__("Paid"), "green", "paid,=,Yes"]; - } - else if (doc.application_status=="Applied") { - return [__("Applied"), "orange", "application_status,=,Applied"]; - } - else if (doc.application_status=="Approved") { - return [__("Approved"), "green", "application_status,=,Approved"]; - } - else if (doc.application_status=="Rejected") { - return [__("Rejected"), "red", "application_status,=,Rejected"]; - } - else if (doc.application_status=="Admitted") { - return [__("Admitted"), "blue", "application_status,=,Admitted"]; - } - } -}; diff --git a/erpnext/education/doctype/student_applicant/test_student_applicant.py b/erpnext/education/doctype/student_applicant/test_student_applicant.py deleted file mode 100644 index bd0e360db7..0000000000 --- a/erpnext/education/doctype/student_applicant/test_student_applicant.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Student Applicant') - - -class TestStudentApplicant(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/student_attendance/__init__.py b/erpnext/education/doctype/student_attendance/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_attendance/student_attendance.js b/erpnext/education/doctype/student_attendance/student_attendance.js deleted file mode 100644 index 2bbecb911f..0000000000 --- a/erpnext/education/doctype/student_attendance/student_attendance.js +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -cur_frm.add_fetch("course_schedule", "schedule_date", "date"); -cur_frm.add_fetch("course_schedule", "student_group", "student_group") diff --git a/erpnext/education/doctype/student_attendance/student_attendance.json b/erpnext/education/doctype/student_attendance/student_attendance.json deleted file mode 100644 index e6e46d1c1b..0000000000 --- a/erpnext/education/doctype/student_attendance/student_attendance.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "actions": [], - "allow_import": 1, - "autoname": "naming_series:", - "creation": "2015-11-05 15:20:23.045996", - "doctype": "DocType", - "document_type": "Document", - "engine": "InnoDB", - "field_order": [ - "naming_series", - "student", - "student_name", - "student_mobile_number", - "course_schedule", - "student_group", - "column_break_3", - "date", - "status", - "leave_application", - "amended_from" - ], - "fields": [ - { - "fieldname": "student", - "fieldtype": "Link", - "in_global_search": 1, - "in_standard_filter": 1, - "label": "Student", - "options": "Student", - "reqd": 1, - "search_index": 1 - }, - { - "fieldname": "course_schedule", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Course Schedule", - "options": "Course Schedule" - }, - { - "fieldname": "date", - "fieldtype": "Date", - "label": "Date", - "reqd": 1, - "search_index": 1 - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fetch_from": "student.title", - "fieldname": "student_name", - "fieldtype": "Read Only", - "in_global_search": 1, - "label": "Student Name" - }, - { - "fieldname": "student_group", - "fieldtype": "Link", - "in_global_search": 1, - "in_standard_filter": 1, - "label": "Student Group", - "options": "Student Group" - }, - { - "default": "Present", - "fieldname": "status", - "fieldtype": "Select", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Status", - "options": "Present\nAbsent", - "reqd": 1 - }, - { - "fieldname": "leave_application", - "fieldtype": "Link", - "label": "Leave Application", - "options": "Student Leave Application", - "read_only": 1 - }, - { - "fieldname": "naming_series", - "fieldtype": "Select", - "label": "Series", - "options": "EDU-ATT-.YYYY.-" - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Student Attendance", - "print_hide": 1, - "read_only": 1 - }, - { - "fetch_from": "student.student_mobile_number", - "fieldname": "student_mobile_number", - "fieldtype": "Read Only", - "label": "Student Mobile Number", - "options": "Phone" - } - ], - "index_web_pages_for_search": 1, - "is_submittable": 1, - "links": [], - "modified": "2021-03-24 00:02:11.005895", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Attendance", - "owner": "Administrator", - "permissions": [ - { - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "submit": 1, - "write": 1 - } - ], - "restrict_to_domain": "Education", - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "student_name" -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_attendance/student_attendance.py b/erpnext/education/doctype/student_attendance/student_attendance.py deleted file mode 100644 index 20f8fb7d77..0000000000 --- a/erpnext/education/doctype/student_attendance/student_attendance.py +++ /dev/null @@ -1,132 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.utils import formatdate, get_link_to_form, getdate - -from erpnext import get_default_company -from erpnext.education.api import get_student_group_students -from erpnext.hr.doctype.holiday_list.holiday_list import is_holiday - - -class StudentAttendance(Document): - def validate(self): - self.validate_mandatory() - self.validate_date() - self.set_date() - self.set_student_group() - self.validate_student() - self.validate_duplication() - self.validate_is_holiday() - - def set_date(self): - if self.course_schedule: - self.date = frappe.db.get_value("Course Schedule", self.course_schedule, "schedule_date") - - def validate_mandatory(self): - if not (self.student_group or self.course_schedule): - frappe.throw( - _("{0} or {1} is mandatory").format( - frappe.bold("Student Group"), frappe.bold("Course Schedule") - ), - title=_("Mandatory Fields"), - ) - - def validate_date(self): - if not self.leave_application and getdate(self.date) > getdate(): - frappe.throw(_("Attendance cannot be marked for future dates.")) - - if self.student_group: - academic_year = frappe.db.get_value("Student Group", self.student_group, "academic_year") - if academic_year: - year_start_date, year_end_date = frappe.db.get_value( - "Academic Year", academic_year, ["year_start_date", "year_end_date"] - ) - if year_start_date and year_end_date: - if getdate(self.date) < getdate(year_start_date) or getdate(self.date) > getdate( - year_end_date - ): - frappe.throw( - _("Attendance cannot be marked outside of Academic Year {0}").format(academic_year) - ) - - def set_student_group(self): - if self.course_schedule: - self.student_group = frappe.db.get_value( - "Course Schedule", self.course_schedule, "student_group" - ) - - def validate_student(self): - if self.course_schedule: - student_group = frappe.db.get_value("Course Schedule", self.course_schedule, "student_group") - else: - student_group = self.student_group - student_group_students = [d.student for d in get_student_group_students(student_group)] - if student_group and self.student not in student_group_students: - student_group_doc = get_link_to_form("Student Group", student_group) - frappe.throw( - _("Student {0}: {1} does not belong to Student Group {2}").format( - frappe.bold(self.student), self.student_name, frappe.bold(student_group_doc) - ) - ) - - def validate_duplication(self): - """Check if the Attendance Record is Unique""" - attendance_record = None - if self.course_schedule: - attendance_record = frappe.db.exists( - "Student Attendance", - { - "student": self.student, - "course_schedule": self.course_schedule, - "docstatus": ("!=", 2), - "name": ("!=", self.name), - }, - ) - else: - attendance_record = frappe.db.exists( - "Student Attendance", - { - "student": self.student, - "student_group": self.student_group, - "date": self.date, - "docstatus": ("!=", 2), - "name": ("!=", self.name), - "course_schedule": "", - }, - ) - - if attendance_record: - record = get_link_to_form("Student Attendance", attendance_record) - frappe.throw( - _("Student Attendance record {0} already exists against the Student {1}").format( - record, frappe.bold(self.student) - ), - title=_("Duplicate Entry"), - ) - - def validate_is_holiday(self): - holiday_list = get_holiday_list() - if is_holiday(holiday_list, self.date): - frappe.throw( - _("Attendance cannot be marked for {0} as it is a holiday.").format( - frappe.bold(formatdate(self.date)) - ) - ) - - -def get_holiday_list(company=None): - if not company: - company = get_default_company() or frappe.get_all("Company")[0].name - - holiday_list = frappe.get_cached_value("Company", company, "default_holiday_list") - if not holiday_list: - frappe.throw( - _("Please set a default Holiday List for Company {0}").format( - frappe.bold(get_default_company()) - ) - ) - return holiday_list diff --git a/erpnext/education/doctype/student_attendance/student_attendance_dashboard.py b/erpnext/education/doctype/student_attendance/student_attendance_dashboard.py deleted file mode 100644 index 34132af69e..0000000000 --- a/erpnext/education/doctype/student_attendance/student_attendance_dashboard.py +++ /dev/null @@ -1,12 +0,0 @@ -from frappe import _ - - -def get_data(): - return { - "reports": [ - { - "label": _("Reports"), - "items": ["Student Monthly Attendance Sheet", "Student Batch-Wise Attendance"], - } - ] - } diff --git a/erpnext/education/doctype/student_attendance/student_attendance_list.js b/erpnext/education/doctype/student_attendance/student_attendance_list.js deleted file mode 100644 index e89b76c8d5..0000000000 --- a/erpnext/education/doctype/student_attendance/student_attendance_list.js +++ /dev/null @@ -1,11 +0,0 @@ -frappe.listview_settings['Student Attendance'] = { - add_fields: [ "status"], - get_indicator: function(doc) { - if (doc.status=="Absent") { - return [__("Absent"), "orange", "status,=,Absent"]; - } - else if (doc.status=="Present") { - return [__("Present"), "green", "status,=,Present"]; - } - } -}; diff --git a/erpnext/education/doctype/student_attendance/test_student_attendance.py b/erpnext/education/doctype/student_attendance/test_student_attendance.py deleted file mode 100644 index e5b1841e1d..0000000000 --- a/erpnext/education/doctype/student_attendance/test_student_attendance.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Student Attendance') - - -class TestStudentAttendance(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/student_attendance_tool/__init__.py b/erpnext/education/doctype/student_attendance_tool/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_attendance_tool/student_attendance_tool.js b/erpnext/education/doctype/student_attendance_tool/student_attendance_tool.js deleted file mode 100644 index 4526585175..0000000000 --- a/erpnext/education/doctype/student_attendance_tool/student_attendance_tool.js +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt -frappe.provide("education"); - -frappe.ui.form.on('Student Attendance Tool', { - setup: (frm) => { - frm.students_area = $('
') - .appendTo(frm.fields_dict.students_html.wrapper); - }, - onload: function(frm) { - frm.set_query("student_group", function() { - return { - "filters": { - "group_based_on": frm.doc.group_based_on, - "disabled": 0 - } - }; - }); - }, - - refresh: function(frm) { - if (frappe.route_options) { - frm.set_value("based_on", frappe.route_options.based_on); - frm.set_value("student_group", frappe.route_options.student_group); - frm.set_value("course_schedule", frappe.route_options.course_schedule); - frappe.route_options = null; - } - frm.disable_save(); - }, - - based_on: function(frm) { - if (frm.doc.based_on == "Student Group") { - frm.set_value("course_schedule", ""); - } else { - frm.set_value("student_group", ""); - } - }, - - student_group: function(frm) { - if ((frm.doc.student_group && frm.doc.date) || frm.doc.course_schedule) { - frm.students_area.find('.student-attendance-checks').html(`
Fetching...
`); - var method = "erpnext.education.doctype.student_attendance_tool.student_attendance_tool.get_student_attendance_records"; - - frappe.call({ - method: method, - args: { - based_on: frm.doc.based_on, - student_group: frm.doc.student_group, - date: frm.doc.date, - course_schedule: frm.doc.course_schedule - }, - callback: function(r) { - frm.events.get_students(frm, r.message); - } - }) - } - }, - - date: function(frm) { - if (frm.doc.date > frappe.datetime.get_today()) - frappe.throw(__("Cannot mark attendance for future dates.")); - frm.trigger("student_group"); - }, - - course_schedule: function(frm) { - frm.trigger("student_group"); - }, - - get_students: function(frm, students) { - students = students || []; - frm.students_editor = new education.StudentsEditor(frm, frm.students_area, students); - } -}); - - -education.StudentsEditor = class StudentsEditor { - constructor(frm, wrapper, students) { - this.wrapper = wrapper; - this.frm = frm; - if(students.length > 0) { - this.make(frm, students); - } else { - this.show_empty_state(); - } - } - make(frm, students) { - var me = this; - - $(this.wrapper).empty(); - var student_toolbar = $('

\ - \ - \ -

').appendTo($(this.wrapper)); - - student_toolbar.find(".btn-add") - .html(__('Check all')) - .on("click", function() { - $(me.wrapper).find('input[type="checkbox"]').each(function(i, check) { - if (!$(check).prop("disabled")) { - check.checked = true; - } - }); - }); - - student_toolbar.find(".btn-remove") - .html(__('Uncheck all')) - .on("click", function() { - $(me.wrapper).find('input[type="checkbox"]').each(function(i, check) { - if (!$(check).prop("disabled")) { - check.checked = false; - } - }); - }); - - student_toolbar.find(".btn-mark-att") - .html(__('Mark Attendance')) - .on("click", function() { - $(me.wrapper.find(".btn-mark-att")).attr("disabled", true); - var studs = []; - $(me.wrapper.find('input[type="checkbox"]')).each(function(i, check) { - var $check = $(check); - studs.push({ - student: $check.data().student, - student_name: $check.data().studentName, - group_roll_number: $check.data().group_roll_number, - disabled: $check.prop("disabled"), - checked: $check.is(":checked") - }); - }); - - var students_present = studs.filter(function(stud) { - return !stud.disabled && stud.checked; - }); - - var students_absent = studs.filter(function(stud) { - return !stud.disabled && !stud.checked; - }); - - frappe.confirm(__("Do you want to update attendance?
Present: {0}
Absent: {1}", - [students_present.length, students_absent.length]), - function() { //ifyes - if(!frappe.request.ajax_count) { - frappe.call({ - method: "erpnext.education.api.mark_attendance", - freeze: true, - freeze_message: __("Marking attendance"), - args: { - "students_present": students_present, - "students_absent": students_absent, - "student_group": frm.doc.student_group, - "course_schedule": frm.doc.course_schedule, - "date": frm.doc.date - }, - callback: function(r) { - $(me.wrapper.find(".btn-mark-att")).attr("disabled", false); - frm.trigger("student_group"); - } - }); - } - }, - function() { //ifno - $(me.wrapper.find(".btn-mark-att")).attr("disabled", false); - } - ); - }); - - // make html grid of students - let student_html = ''; - for (let student of students) { - student_html += `
-
- -
-
`; - } - - $(`
${student_html}
`).appendTo(me.wrapper); - } - - show_empty_state() { - $(this.wrapper).html( - `
- ${__("No Students in")} ${this.frm.doc.student_group} -
` - ); - } -}; diff --git a/erpnext/education/doctype/student_attendance_tool/student_attendance_tool.json b/erpnext/education/doctype/student_attendance_tool/student_attendance_tool.json deleted file mode 100644 index ee8f4842a3..0000000000 --- a/erpnext/education/doctype/student_attendance_tool/student_attendance_tool.json +++ /dev/null @@ -1,118 +0,0 @@ -{ - "actions": [], - "allow_copy": 1, - "creation": "2016-11-16 17:12:46.437539", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "based_on", - "group_based_on", - "column_break_2", - "student_group", - "academic_year", - "academic_term", - "course_schedule", - "date", - "attendance", - "students_html" - ], - "fields": [ - { - "fieldname": "based_on", - "fieldtype": "Select", - "label": "Based On", - "options": "Student Group\nCourse Schedule" - }, - { - "default": "Batch", - "depends_on": "eval:doc.based_on == \"Student Group\"", - "fieldname": "group_based_on", - "fieldtype": "Select", - "label": "Group Based On", - "options": "Batch\nCourse\nActivity" - }, - { - "fieldname": "column_break_2", - "fieldtype": "Column Break" - }, - { - "depends_on": "eval:doc.based_on ==\"Student Group\"", - "fieldname": "student_group", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Student Group", - "options": "Student Group", - "reqd": 1 - }, - { - "depends_on": "eval:doc.based_on ==\"Course Schedule\"", - "fieldname": "course_schedule", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Course Schedule", - "options": "Course Schedule", - "reqd": 1 - }, - { - "depends_on": "eval:doc.based_on ==\"Student Group\"", - "fieldname": "date", - "fieldtype": "Date", - "in_list_view": 1, - "label": "Date", - "reqd": 1 - }, - { - "depends_on": "eval: (doc.course_schedule \n|| (doc.student_group && doc.date))", - "fieldname": "attendance", - "fieldtype": "Section Break", - "label": "Attendance" - }, - { - "fieldname": "students_html", - "fieldtype": "HTML", - "label": "Students HTML" - }, - { - "fetch_from": "student_group.academic_year", - "fieldname": "academic_year", - "fieldtype": "Link", - "label": "Academic Year", - "options": "Academic Year", - "read_only": 1 - }, - { - "fetch_from": "student_group.academic_term", - "fieldname": "academic_term", - "fieldtype": "Link", - "label": "Academic Term", - "options": "Academic Term", - "read_only": 1 - } - ], - "hide_toolbar": 1, - "issingle": 1, - "links": [], - "modified": "2020-10-23 17:52:28.078971", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Attendance Tool", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "read": 1, - "role": "Instructor", - "write": 1 - }, - { - "create": 1, - "read": 1, - "role": "Academics User", - "write": 1 - } - ], - "restrict_to_domain": "Education", - "sort_field": "modified", - "sort_order": "DESC" -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_attendance_tool/student_attendance_tool.py b/erpnext/education/doctype/student_attendance_tool/student_attendance_tool.py deleted file mode 100644 index c626a0f288..0000000000 --- a/erpnext/education/doctype/student_attendance_tool/student_attendance_tool.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe.model.document import Document - - -class StudentAttendanceTool(Document): - pass - - -@frappe.whitelist() -def get_student_attendance_records(based_on, date=None, student_group=None, course_schedule=None): - student_list = [] - student_attendance_list = [] - - if based_on == "Course Schedule": - student_group = frappe.db.get_value("Course Schedule", course_schedule, "student_group") - if student_group: - student_list = frappe.get_all( - "Student Group Student", - fields=["student", "student_name", "group_roll_number"], - filters={"parent": student_group, "active": 1}, - order_by="group_roll_number", - ) - - if not student_list: - student_list = frappe.get_all( - "Student Group Student", - fields=["student", "student_name", "group_roll_number"], - filters={"parent": student_group, "active": 1}, - order_by="group_roll_number", - ) - - StudentAttendance = frappe.qb.DocType("Student Attendance") - - if course_schedule: - student_attendance_list = ( - frappe.qb.from_(StudentAttendance) - .select(StudentAttendance.student, StudentAttendance.status) - .where((StudentAttendance.course_schedule == course_schedule)) - ).run(as_dict=True) - else: - student_attendance_list = ( - frappe.qb.from_(StudentAttendance) - .select(StudentAttendance.student, StudentAttendance.status) - .where( - (StudentAttendance.student_group == student_group) - & (StudentAttendance.date == date) - & ((StudentAttendance.course_schedule == "") | (StudentAttendance.course_schedule.isnull())) - ) - ).run(as_dict=True) - - for attendance in student_attendance_list: - for student in student_list: - if student.student == attendance.student: - student.status = attendance.status - - return student_list diff --git a/erpnext/education/doctype/student_attendance_tool/test_student_attendance_tool.py b/erpnext/education/doctype/student_attendance_tool/test_student_attendance_tool.py deleted file mode 100644 index c15036fe03..0000000000 --- a/erpnext/education/doctype/student_attendance_tool/test_student_attendance_tool.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestStudentAttendanceTool(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/student_batch_name/__init__.py b/erpnext/education/doctype/student_batch_name/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_batch_name/student_batch_name.js b/erpnext/education/doctype/student_batch_name/student_batch_name.js deleted file mode 100644 index 7ed3021fb4..0000000000 --- a/erpnext/education/doctype/student_batch_name/student_batch_name.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Student Batch Name', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/student_batch_name/student_batch_name.json b/erpnext/education/doctype/student_batch_name/student_batch_name.json deleted file mode 100644 index abb6436010..0000000000 --- a/erpnext/education/doctype/student_batch_name/student_batch_name.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "field:batch_name", - "beta": 0, - "creation": "2016-11-17 18:45:57.965091", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "batch_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Batch Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2017-11-10 19:08:17.980349", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Batch Name", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_batch_name/student_batch_name.py b/erpnext/education/doctype/student_batch_name/student_batch_name.py deleted file mode 100644 index ae59291dcf..0000000000 --- a/erpnext/education/doctype/student_batch_name/student_batch_name.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class StudentBatchName(Document): - pass diff --git a/erpnext/education/doctype/student_batch_name/test_records.json b/erpnext/education/doctype/student_batch_name/test_records.json deleted file mode 100644 index bf365c638a..0000000000 --- a/erpnext/education/doctype/student_batch_name/test_records.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "batch_name": "_Batch 1" - }, - { - "batch_name": "_Batch 2" - } -] \ No newline at end of file diff --git a/erpnext/education/doctype/student_batch_name/test_student_batch_name.py b/erpnext/education/doctype/student_batch_name/test_student_batch_name.py deleted file mode 100644 index bf9639bf62..0000000000 --- a/erpnext/education/doctype/student_batch_name/test_student_batch_name.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Student Batch Name') - - -class TestStudentBatchName(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/student_category/__init__.py b/erpnext/education/doctype/student_category/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_category/student_category.js b/erpnext/education/doctype/student_category/student_category.js deleted file mode 100644 index 3a264d1d4a..0000000000 --- a/erpnext/education/doctype/student_category/student_category.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Student Category', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/student_category/student_category.json b/erpnext/education/doctype/student_category/student_category.json deleted file mode 100644 index d7d4444a28..0000000000 --- a/erpnext/education/doctype/student_category/student_category.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "field:category", - "beta": 0, - "creation": "2016-09-05 06:28:33.679415", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "category", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Category", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2017-11-10 19:09:45.783401", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Category", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_category/student_category.py b/erpnext/education/doctype/student_category/student_category.py deleted file mode 100644 index 0d7185967e..0000000000 --- a/erpnext/education/doctype/student_category/student_category.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class StudentCategory(Document): - pass diff --git a/erpnext/education/doctype/student_category/student_category_dashboard.py b/erpnext/education/doctype/student_category/student_category_dashboard.py deleted file mode 100644 index d7a332c4d2..0000000000 --- a/erpnext/education/doctype/student_category/student_category_dashboard.py +++ /dev/null @@ -1,8 +0,0 @@ -from frappe import _ - - -def get_data(): - return { - "fieldname": "student_category", - "transactions": [{"label": _("Fee"), "items": ["Fee Structure", "Fee Schedule", "Fees"]}], - } diff --git a/erpnext/education/doctype/student_category/test_student_category.py b/erpnext/education/doctype/student_category/test_student_category.py deleted file mode 100644 index 5671e9fa44..0000000000 --- a/erpnext/education/doctype/student_category/test_student_category.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Student Category') - - -class TestStudentCategory(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/student_group/__init__.py b/erpnext/education/doctype/student_group/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_group/student_group.js b/erpnext/education/doctype/student_group/student_group.js deleted file mode 100644 index 39ee9cebd1..0000000000 --- a/erpnext/education/doctype/student_group/student_group.js +++ /dev/null @@ -1,145 +0,0 @@ -cur_frm.add_fetch('student', 'title', 'student_name'); - -frappe.ui.form.on('Student Group', { - onload: function(frm) { - frm.set_query('academic_term', function() { - return { - filters: { - 'academic_year': (frm.doc.academic_year) - } - }; - }); - if (!frm.__islocal) { - frm.set_query('student', 'students', function() { - return{ - query: 'erpnext.education.doctype.student_group.student_group.fetch_students', - filters: { - 'academic_year': frm.doc.academic_year, - 'group_based_on': frm.doc.group_based_on, - 'academic_term': frm.doc.academic_term, - 'program': frm.doc.program, - 'batch': frm.doc.batch, - 'student_category': frm.doc.student_category, - 'course': frm.doc.course, - 'student_group': frm.doc.name - } - } - }); - } - }, - - refresh: function(frm) { - if (!frm.doc.__islocal) { - - frm.add_custom_button(__('Add Guardians to Email Group'), function() { - frappe.call({ - method: 'erpnext.education.api.update_email_group', - args: { - 'doctype': 'Student Group', - 'name': frm.doc.name - } - }); - }, __('Actions')); - - frm.add_custom_button(__('Student Attendance Tool'), function() { - frappe.route_options = { - based_on: 'Student Group', - student_group: frm.doc.name - } - frappe.set_route('Form', 'Student Attendance Tool', 'Student Attendance Tool'); - }, __('Tools')); - - frm.add_custom_button(__('Course Scheduling Tool'), function() { - frappe.route_options = { - student_group: frm.doc.name - } - frappe.set_route('Form', 'Course Scheduling Tool', 'Course Scheduling Tool'); - }, __('Tools')); - - frm.add_custom_button(__('Newsletter'), function() { - frappe.route_options = { - 'Newsletter Email Group.email_group': frm.doc.name - } - frappe.set_route('List', 'Newsletter'); - }, __('View')); - - } - }, - - group_based_on: function(frm) { - if (frm.doc.group_based_on == 'Batch') { - frm.doc.course = null; - frm.set_df_property('program', 'reqd', 1); - frm.set_df_property('course', 'reqd', 0); - } - else if (frm.doc.group_based_on == 'Course') { - frm.set_df_property('program', 'reqd', 0); - frm.set_df_property('course', 'reqd', 1); - } - else if (frm.doc.group_based_on == 'Activity') { - frm.set_df_property('program', 'reqd', 0); - frm.set_df_property('course', 'reqd', 0); - } - }, - - get_students: function(frm) { - if (frm.doc.group_based_on == 'Batch' || frm.doc.group_based_on == 'Course') { - var student_list = []; - var max_roll_no = 0; - $.each(frm.doc.students, function(_i,d) { - student_list.push(d.student); - if (d.group_roll_number>max_roll_no) { - max_roll_no = d.group_roll_number; - } - }); - - if (frm.doc.academic_year) { - frappe.call({ - method: 'erpnext.education.doctype.student_group.student_group.get_students', - args: { - 'academic_year': frm.doc.academic_year, - 'academic_term': frm.doc.academic_term, - 'group_based_on': frm.doc.group_based_on, - 'program': frm.doc.program, - 'batch' : frm.doc.batch, - 'student_category' : frm.doc.student_category, - 'course': frm.doc.course - }, - callback: function(r) { - if (r.message) { - $.each(r.message, function(i, d) { - if(!in_list(student_list, d.student)) { - var s = frm.add_child('students'); - s.student = d.student; - s.student_name = d.student_name; - if (d.active === 0) { - s.active = 0; - } - s.group_roll_number = ++max_roll_no; - } - }); - refresh_field('students'); - frm.save(); - } else { - frappe.msgprint(__('Student Group is already updated.')) - } - } - }) - } - } else { - frappe.msgprint(__('Select students manually for the Activity based Group')); - } - } -}); - -frappe.ui.form.on('Student Group Instructor', { - instructors_add: function(frm){ - frm.fields_dict['instructors'].grid.get_field('instructor').get_query = function(doc){ - let instructor_list = []; - $.each(doc.instructors, function(idx, val){ - instructor_list.push(val.instructor); - }); - return { filters: [['Instructor', 'name', 'not in', instructor_list]] }; - }; - } -}); diff --git a/erpnext/education/doctype/student_group/student_group.json b/erpnext/education/doctype/student_group/student_group.json deleted file mode 100644 index 44b38b1345..0000000000 --- a/erpnext/education/doctype/student_group/student_group.json +++ /dev/null @@ -1,161 +0,0 @@ -{ - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:student_group_name", - "creation": "2015-09-07 12:55:52.072792", - "doctype": "DocType", - "document_type": "Document", - "engine": "InnoDB", - "field_order": [ - "academic_year", - "group_based_on", - "student_group_name", - "max_strength", - "column_break_3", - "academic_term", - "program", - "batch", - "student_category", - "course", - "disabled", - "section_break_6", - "get_students", - "students", - "section_break_12", - "instructors" - ], - "fields": [ - { - "fieldname": "academic_year", - "fieldtype": "Link", - "in_standard_filter": 1, - "label": "Academic Year", - "options": "Academic Year", - "set_only_once": 1 - }, - { - "fieldname": "group_based_on", - "fieldtype": "Select", - "in_list_view": 1, - "label": "Group Based on", - "options": "\nBatch\nCourse\nActivity", - "reqd": 1 - }, - { - "fieldname": "student_group_name", - "fieldtype": "Data", - "label": "Student Group Name", - "reqd": 1, - "unique": 1 - }, - { - "description": "Set 0 for no limit", - "fieldname": "max_strength", - "fieldtype": "Int", - "label": "Max Strength" - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fieldname": "academic_term", - "fieldtype": "Link", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Academic Term", - "options": "Academic Term" - }, - { - "fieldname": "program", - "fieldtype": "Link", - "in_global_search": 1, - "label": "Program", - "options": "Program" - }, - { - "fieldname": "batch", - "fieldtype": "Link", - "in_global_search": 1, - "label": "Batch", - "options": "Student Batch Name" - }, - { - "depends_on": "eval:doc.group_based_on == 'Course'", - "fieldname": "course", - "fieldtype": "Link", - "in_global_search": 1, - "in_standard_filter": 1, - "label": "Course", - "options": "Course" - }, - { - "default": "0", - "fieldname": "disabled", - "fieldtype": "Check", - "label": "Disabled" - }, - { - "depends_on": "eval:!doc.__islocal", - "fieldname": "section_break_6", - "fieldtype": "Section Break", - "label": "Students" - }, - { - "fieldname": "get_students", - "fieldtype": "Button", - "label": "Get Students" - }, - { - "allow_on_submit": 1, - "fieldname": "students", - "fieldtype": "Table", - "label": "Students", - "options": "Student Group Student" - }, - { - "fieldname": "section_break_12", - "fieldtype": "Section Break", - "label": "Instructors" - }, - { - "fieldname": "instructors", - "fieldtype": "Table", - "label": "Instructors", - "options": "Student Group Instructor" - }, - { - "fieldname": "student_category", - "fieldtype": "Link", - "label": "Student Category", - "options": "Student Category" - } - ], - "modified": "2019-04-26 10:52:57.303951", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Group", - "owner": "Administrator", - "permissions": [ - { - "read": 1, - "role": "Instructor" - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "write": 1 - } - ], - "restrict_to_domain": "Education", - "search_fields": "program, batch, course", - "sort_field": "modified", - "sort_order": "DESC" -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_group/student_group.py b/erpnext/education/doctype/student_group/student_group.py deleted file mode 100644 index a94489ba53..0000000000 --- a/erpnext/education/doctype/student_group/student_group.py +++ /dev/null @@ -1,200 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.utils import cint - -from erpnext.education.utils import validate_duplicate_student - - -class StudentGroup(Document): - def validate(self): - self.validate_mandatory_fields() - self.validate_strength() - self.validate_students() - self.validate_and_set_child_table_fields() - validate_duplicate_student(self.students) - - def validate_mandatory_fields(self): - if self.group_based_on == "Course" and not self.course: - frappe.throw(_("Please select Course")) - if self.group_based_on == "Course" and (not self.program and self.batch): - frappe.throw(_("Please select Program")) - if self.group_based_on == "Batch" and not self.program: - frappe.throw(_("Please select Program")) - - def validate_strength(self): - if cint(self.max_strength) < 0: - frappe.throw(_("""Max strength cannot be less than zero.""")) - if self.max_strength and len(self.students) > self.max_strength: - frappe.throw( - _("""Cannot enroll more than {0} students for this student group.""").format(self.max_strength) - ) - - def validate_students(self): - program_enrollment = get_program_enrollment( - self.academic_year, - self.academic_term, - self.program, - self.batch, - self.student_category, - self.course, - ) - students = [d.student for d in program_enrollment] if program_enrollment else [] - for d in self.students: - if not frappe.db.get_value("Student", d.student, "enabled") and d.active and not self.disabled: - frappe.throw(_("{0} - {1} is inactive student").format(d.group_roll_number, d.student_name)) - - if ( - (self.group_based_on == "Batch") - and cint(frappe.defaults.get_defaults().validate_batch) - and d.student not in students - ): - frappe.throw( - _("{0} - {1} is not enrolled in the Batch {2}").format( - d.group_roll_number, d.student_name, self.batch - ) - ) - - if ( - (self.group_based_on == "Course") - and cint(frappe.defaults.get_defaults().validate_course) - and (d.student not in students) - ): - frappe.throw( - _("{0} - {1} is not enrolled in the Course {2}").format( - d.group_roll_number, d.student_name, self.course - ) - ) - - def validate_and_set_child_table_fields(self): - roll_numbers = [d.group_roll_number for d in self.students if d.group_roll_number] - max_roll_no = max(roll_numbers) if roll_numbers else 0 - roll_no_list = [] - for d in self.students: - if not d.student_name: - d.student_name = frappe.db.get_value("Student", d.student, "title") - if not d.group_roll_number: - max_roll_no += 1 - d.group_roll_number = max_roll_no - if d.group_roll_number in roll_no_list: - frappe.throw(_("Duplicate roll number for student {0}").format(d.student_name)) - else: - roll_no_list.append(d.group_roll_number) - - -@frappe.whitelist() -def get_students( - academic_year, - group_based_on, - academic_term=None, - program=None, - batch=None, - student_category=None, - course=None, -): - enrolled_students = get_program_enrollment( - academic_year, academic_term, program, batch, student_category, course - ) - - if enrolled_students: - student_list = [] - for s in enrolled_students: - if frappe.db.get_value("Student", s.student, "enabled"): - s.update({"active": 1}) - else: - s.update({"active": 0}) - student_list.append(s) - return student_list - else: - frappe.msgprint(_("No students found")) - return [] - - -def get_program_enrollment( - academic_year, academic_term=None, program=None, batch=None, student_category=None, course=None -): - - condition1 = " " - condition2 = " " - if academic_term: - condition1 += " and pe.academic_term = %(academic_term)s" - if program: - condition1 += " and pe.program = %(program)s" - if batch: - condition1 += " and pe.student_batch_name = %(batch)s" - if student_category: - condition1 += " and pe.student_category = %(student_category)s" - if course: - condition1 += " and pe.name = pec.parent and pec.course = %(course)s" - condition2 = ", `tabProgram Enrollment Course` pec" - - return frappe.db.sql( - """ - select - pe.student, pe.student_name - from - `tabProgram Enrollment` pe {condition2} - where - pe.academic_year = %(academic_year)s {condition1} - order by - pe.student_name asc - """.format( - condition1=condition1, condition2=condition2 - ), - ( - { - "academic_year": academic_year, - "academic_term": academic_term, - "program": program, - "batch": batch, - "student_category": student_category, - "course": course, - } - ), - as_dict=1, - ) - - -@frappe.whitelist() -@frappe.validate_and_sanitize_search_inputs -def fetch_students(doctype, txt, searchfield, start, page_len, filters): - if filters.get("group_based_on") != "Activity": - enrolled_students = get_program_enrollment( - filters.get("academic_year"), - filters.get("academic_term"), - filters.get("program"), - filters.get("batch"), - filters.get("student_category"), - ) - student_group_student = frappe.db.sql_list( - """select student from `tabStudent Group Student` where parent=%s""", - (filters.get("student_group")), - ) - students = ( - [d.student for d in enrolled_students if d.student not in student_group_student] - if enrolled_students - else [""] - ) or [""] - return frappe.db.sql( - """select name, title from tabStudent - where name in ({0}) and (`{1}` LIKE %s or title LIKE %s) - order by idx desc, name - limit %s, %s""".format( - ", ".join(["%s"] * len(students)), searchfield - ), - tuple(students + ["%%%s%%" % txt, "%%%s%%" % txt, start, page_len]), - ) - else: - return frappe.db.sql( - """select name, title from tabStudent - where `{0}` LIKE %s or title LIKE %s - order by idx desc, name - limit %s, %s""".format( - searchfield - ), - tuple(["%%%s%%" % txt, "%%%s%%" % txt, start, page_len]), - ) diff --git a/erpnext/education/doctype/student_group/student_group_dashboard.py b/erpnext/education/doctype/student_group/student_group_dashboard.py deleted file mode 100644 index 094b5a0235..0000000000 --- a/erpnext/education/doctype/student_group/student_group_dashboard.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - -from frappe import _ - - -def get_data(): - return { - "fieldname": "student_group", - "transactions": [ - {"label": _("Assessment"), "items": ["Assessment Plan", "Assessment Result"]}, - {"label": _("Course"), "items": ["Course Schedule"]}, - ], - } diff --git a/erpnext/education/doctype/student_group/test_records.json b/erpnext/education/doctype/student_group/test_records.json deleted file mode 100644 index 4c4e042b15..0000000000 --- a/erpnext/education/doctype/student_group/test_records.json +++ /dev/null @@ -1,34 +0,0 @@ -[ - { - "student_group_name": "Batch-_TP1-_Batch 1-2014-2015 (_Test Academic Term)", - "group_based_on": "Batch", - "program": "_TP1", - "batch": "_Batch 1", - "academic_year": "2014-2015", - "academic_term": "2014-2015 (_Test Academic Term)", - "max_strength": 0 - }, - { - "student_group_name": "Course-TC101-2014-2015 (_Test Academic Term)", - "group_based_on": "Course", - "course": "TC101", - "academic_year": "2014-2015", - "academic_term": "2014-2015 (_Test Academic Term)", - "max_strength": 0 - }, - { - "student_group_name": "Course-TC102-2014-2015 (_Test Academic Term)", - "group_based_on": "Course", - "course": "TC102", - "academic_year": "2014-2015", - "academic_term": "2014-2015 (_Test Academic Term)", - "max_strength": 0 - }, - { - "student_group_name": "Activity-2014-2015 (_Test Academic Term)", - "group_based_on": "Activity", - "academic_year": "2014-2015", - "academic_term": "2014-2015 (_Test Academic Term)", - "max_strength": 0 - } -] \ No newline at end of file diff --git a/erpnext/education/doctype/student_group/test_student_group.py b/erpnext/education/doctype/student_group/test_student_group.py deleted file mode 100644 index 84b49309ac..0000000000 --- a/erpnext/education/doctype/student_group/test_student_group.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and Contributors -# See license.txt - -import unittest - -import frappe - -import erpnext.education - - -def get_random_group(): - doc = frappe.get_doc( - { - "doctype": "Student Group", - "student_group_name": "_Test Student Group-" + frappe.generate_hash(length=5), - "group_based_on": "Activity", - } - ).insert() - - student_list = frappe.get_all("Student", limit=5) - - doc.extend("students", [{"student": d.name, "active": 1} for d in student_list]) - doc.save() - - return doc - - -class TestStudentGroup(unittest.TestCase): - def test_student_roll_no(self): - doc = get_random_group() - self.assertEqual(max([d.group_roll_number for d in doc.students]), len(doc.students)) - - def test_in_group(self): - doc = get_random_group() - - last_student = doc.students[-1].student - - # remove last student - doc.students = doc.students[:-1] - doc.save() - - self.assertRaises( - erpnext.education.StudentNotInGroupError, - erpnext.education.validate_student_belongs_to_group, - last_student, - doc.name, - ) - - # safe, don't throw validation - erpnext.education.validate_student_belongs_to_group(doc.students[0].student, doc.name) diff --git a/erpnext/education/doctype/student_group_creation_tool/__init__.py b/erpnext/education/doctype/student_group_creation_tool/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.js b/erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.js deleted file mode 100644 index c189e2763c..0000000000 --- a/erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.js +++ /dev/null @@ -1,40 +0,0 @@ -frappe.ui.form.on("Student Group Creation Tool", "refresh", function(frm) { - frm.disable_save(); - frm.page.set_primary_action(__("Create Student Groups"), function() { - frappe.call({ - method: "create_student_groups", - doc:frm.doc - }) - }); - frappe.realtime.on("student_group_creation_progress", function(data) { - if(data.progress) { - frappe.hide_msgprint(true); - frappe.show_progress(__("Creating student groups"), data.progress[0],data.progress[1]); - } - }); -}); - -frappe.ui.form.on("Student Group Creation Tool", "get_courses", function(frm) { - frm.set_value("courses",[]); - if (frm.doc.academic_year && frm.doc.program) { - frappe.call({ - method: "get_courses", - doc:frm.doc, - callback: function(r) { - if(r.message) { - frm.set_value("courses", r.message); - } - } - }) - } -}); - -frappe.ui.form.on("Student Group Creation Tool", "onload", function(frm){ - cur_frm.set_query("academic_term",function(){ - return{ - "filters":{ - "academic_year": (frm.doc.academic_year) - } - }; - }); -}); diff --git a/erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.json b/erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.json deleted file mode 100644 index fe7cbdb0b8..0000000000 --- a/erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.json +++ /dev/null @@ -1,309 +0,0 @@ -{ - "allow_copy": 1, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-01-04 14:45:36.576933", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 0, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "academic_year", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Academic Year", - "length": 0, - "no_copy": 0, - "options": "Academic Year", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "Leave blank if you make students groups per year", - "fieldname": "academic_term", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Academic Term", - "length": 0, - "no_copy": 0, - "options": "Academic Term", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "get_courses", - "fieldtype": "Button", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Get Courses", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_4", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "", - "fieldname": "program", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Program", - "length": 0, - "no_copy": 0, - "options": "Program", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "Leave unchecked if you don't want to consider batch while making course based groups. ", - "fieldname": "separate_groups", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Separate course based Group for every Batch", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_4", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "courses", - "fieldtype": "Table", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Courses", - "length": 0, - "no_copy": 0, - "options": "Student Group Creation Tool Course", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 1, - "hide_toolbar": 1, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 1, - "istable": 0, - "max_attachments": 0, - "modified": "2017-12-27 09:35:30.211254", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Group Creation Tool", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 0, - "role": "Education Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.py b/erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.py deleted file mode 100644 index bbeb654bfc..0000000000 --- a/erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.py +++ /dev/null @@ -1,101 +0,0 @@ -# Copyright (c) 2015, Frappe and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ -from frappe.model.document import Document - -from erpnext.education.doctype.student_group.student_group import get_students - - -class StudentGroupCreationTool(Document): - @frappe.whitelist() - def get_courses(self): - group_list = [] - - batches = frappe.db.sql("""select name as batch from `tabStudent Batch Name`""", as_dict=1) - for batch in batches: - group_list.append({"group_based_on": "Batch", "batch": batch.batch}) - - courses = frappe.db.sql( - """select course, course_name from `tabProgram Course` where parent=%s""", - (self.program), - as_dict=1, - ) - if self.separate_groups: - from itertools import product - - course_list = product(courses, batches) - for course in course_list: - temp_dict = {} - temp_dict.update({"group_based_on": "Course"}) - temp_dict.update(course[0]) - temp_dict.update(course[1]) - group_list.append(temp_dict) - else: - for course in courses: - course.update({"group_based_on": "Course"}) - group_list.append(course) - - for group in group_list: - if group.get("group_based_on") == "Batch": - student_group_name = ( - self.program - + "/" - + group.get("batch") - + "/" - + (self.academic_term if self.academic_term else self.academic_year) - ) - group.update({"student_group_name": student_group_name}) - elif group.get("group_based_on") == "Course": - student_group_name = ( - group.get("course") - + "/" - + self.program - + ("/" + group.get("batch") if group.get("batch") else "") - + "/" - + (self.academic_term if self.academic_term else self.academic_year) - ) - group.update({"student_group_name": student_group_name}) - - return group_list - - @frappe.whitelist() - def create_student_groups(self): - if not self.courses: - frappe.throw(_("""No Student Groups created.""")) - - l = len(self.courses) - for d in self.courses: - if not d.student_group_name: - frappe.throw(_("Student Group Name is mandatory in row {0}").format(d.idx)) - - if d.group_based_on == "Course" and not d.course: - frappe.throw(_("Course is mandatory in row {0}").format(d.idx)) - - if d.group_based_on == "Batch" and not d.batch: - frappe.throw(_("Batch is mandatory in row {0}").format(d.idx)) - - frappe.publish_realtime( - "student_group_creation_progress", {"progress": [d.idx, l]}, user=frappe.session.user - ) - - student_group = frappe.new_doc("Student Group") - student_group.student_group_name = d.student_group_name - student_group.group_based_on = d.group_based_on - student_group.program = self.program - student_group.course = d.course - student_group.batch = d.batch - student_group.max_strength = d.max_strength - student_group.academic_term = self.academic_term - student_group.academic_year = self.academic_year - student_list = get_students( - self.academic_year, d.group_based_on, self.academic_term, self.program, d.batch, d.course - ) - - for student in student_list: - student_group.append("students", student) - student_group.save() - - frappe.msgprint(_("{0} Student Groups created.").format(l)) diff --git a/erpnext/education/doctype/student_group_creation_tool/test_student_group_creation_tool.py b/erpnext/education/doctype/student_group_creation_tool/test_student_group_creation_tool.py deleted file mode 100644 index 8722f973a8..0000000000 --- a/erpnext/education/doctype/student_group_creation_tool/test_student_group_creation_tool.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestStudentGroupCreationTool(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/student_group_creation_tool_course/__init__.py b/erpnext/education/doctype/student_group_creation_tool_course/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_group_creation_tool_course/student_group_creation_tool_course.json b/erpnext/education/doctype/student_group_creation_tool_course/student_group_creation_tool_course.json deleted file mode 100644 index 9f691a1cb0..0000000000 --- a/erpnext/education/doctype/student_group_creation_tool_course/student_group_creation_tool_course.json +++ /dev/null @@ -1,272 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-01-04 15:03:57.940079", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "group_based_on", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Group Based On", - "length": 0, - "no_copy": 0, - "options": "\nBatch\nCourse", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "course", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Course", - "length": 0, - "no_copy": 0, - "options": "Course", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "batch", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Batch", - "length": 0, - "no_copy": 0, - "options": "Student Batch Name", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_3", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student_group_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Student Group Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "course.course_name", - "fieldname": "course_code", - "fieldtype": "Read Only", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Course Code", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "max_strength", - "fieldtype": "Int", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Max Strength", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-11-04 03:38:52.525155", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Group Creation Tool Course", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_group_creation_tool_course/student_group_creation_tool_course.py b/erpnext/education/doctype/student_group_creation_tool_course/student_group_creation_tool_course.py deleted file mode 100644 index 78e45411fd..0000000000 --- a/erpnext/education/doctype/student_group_creation_tool_course/student_group_creation_tool_course.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class StudentGroupCreationToolCourse(Document): - pass diff --git a/erpnext/education/doctype/student_group_instructor/__init__.py b/erpnext/education/doctype/student_group_instructor/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_group_instructor/student_group_instructor.json b/erpnext/education/doctype/student_group_instructor/student_group_instructor.json deleted file mode 100644 index cb4e52756b..0000000000 --- a/erpnext/education/doctype/student_group_instructor/student_group_instructor.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2017-04-17 16:06:01.406768", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "instructor", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Instructor", - "length": 0, - "no_copy": 0, - "options": "Instructor", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_2", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "instructor.instructor_name", - "fieldname": "instructor_name", - "fieldtype": "Read Only", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Instructor Name", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-11-04 03:39:02.413082", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Group Instructor", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_group_instructor/student_group_instructor.py b/erpnext/education/doctype/student_group_instructor/student_group_instructor.py deleted file mode 100644 index 05ef6fc116..0000000000 --- a/erpnext/education/doctype/student_group_instructor/student_group_instructor.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class StudentGroupInstructor(Document): - pass diff --git a/erpnext/education/doctype/student_group_student/__init__.py b/erpnext/education/doctype/student_group_student/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_group_student/student_group_student.json b/erpnext/education/doctype/student_group_student/student_group_student.json deleted file mode 100644 index d55db344eb..0000000000 --- a/erpnext/education/doctype/student_group_student/student_group_student.json +++ /dev/null @@ -1,204 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2015-09-11 15:14:58.501830", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Student", - "length": 0, - "no_copy": 0, - "options": "Student", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Student Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_2", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "group_roll_number", - "fieldtype": "Int", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Group Roll Number", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "1", - "fieldname": "active", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Active", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-11-04 03:38:22.896203", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Group Student", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_group_student/student_group_student.py b/erpnext/education/doctype/student_group_student/student_group_student.py deleted file mode 100644 index f9d00abde0..0000000000 --- a/erpnext/education/doctype/student_group_student/student_group_student.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class StudentGroupStudent(Document): - pass diff --git a/erpnext/education/doctype/student_guardian/__init__.py b/erpnext/education/doctype/student_guardian/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_guardian/student_guardian.json b/erpnext/education/doctype/student_guardian/student_guardian.json deleted file mode 100644 index 3f03a3d1a2..0000000000 --- a/erpnext/education/doctype/student_guardian/student_guardian.json +++ /dev/null @@ -1,141 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-09-01 14:28:39.174471", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "guardian", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Guardian", - "length": 0, - "no_copy": 0, - "options": "Guardian", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "guardian_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Guardian Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "relation", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Relation", - "length": 0, - "no_copy": 0, - "options": "\nMother\nFather\nOthers", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-11-04 03:38:14.211238", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Guardian", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_guardian/student_guardian.py b/erpnext/education/doctype/student_guardian/student_guardian.py deleted file mode 100644 index 0843acfd50..0000000000 --- a/erpnext/education/doctype/student_guardian/student_guardian.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class StudentGuardian(Document): - pass diff --git a/erpnext/education/doctype/student_language/__init__.py b/erpnext/education/doctype/student_language/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_language/student_language.js b/erpnext/education/doctype/student_language/student_language.js deleted file mode 100644 index 6239ed1e44..0000000000 --- a/erpnext/education/doctype/student_language/student_language.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Student Language', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/student_language/student_language.json b/erpnext/education/doctype/student_language/student_language.json deleted file mode 100644 index fc53cd13c6..0000000000 --- a/erpnext/education/doctype/student_language/student_language.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "field:language_name", - "beta": 0, - "creation": "2017-02-21 01:55:00.366273", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "language_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Language Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 1 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-11-04 03:37:34.712397", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Language", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_language/student_language.py b/erpnext/education/doctype/student_language/student_language.py deleted file mode 100644 index d578c9a0b6..0000000000 --- a/erpnext/education/doctype/student_language/student_language.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class StudentLanguage(Document): - pass diff --git a/erpnext/education/doctype/student_language/test_student_language.py b/erpnext/education/doctype/student_language/test_student_language.py deleted file mode 100644 index d1a8b6d526..0000000000 --- a/erpnext/education/doctype/student_language/test_student_language.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Student Language') - - -class TestStudentLanguage(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/student_leave_application/__init__.py b/erpnext/education/doctype/student_leave_application/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_leave_application/student_leave_application.js b/erpnext/education/doctype/student_leave_application/student_leave_application.js deleted file mode 100644 index 4746148311..0000000000 --- a/erpnext/education/doctype/student_leave_application/student_leave_application.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Student Leave Application', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/student_leave_application/student_leave_application.json b/erpnext/education/doctype/student_leave_application/student_leave_application.json deleted file mode 100644 index 31b3da2fbd..0000000000 --- a/erpnext/education/doctype/student_leave_application/student_leave_application.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "actions": [], - "autoname": "EDU-SLA-.YYYY.-.#####", - "creation": "2016-11-28 15:38:54.793854", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "student", - "student_name", - "column_break_3", - "from_date", - "to_date", - "total_leave_days", - "section_break_5", - "attendance_based_on", - "student_group", - "course_schedule", - "mark_as_present", - "column_break_11", - "reason", - "amended_from" - ], - "fields": [ - { - "fieldname": "student", - "fieldtype": "Link", - "in_global_search": 1, - "label": "Student", - "options": "Student", - "reqd": 1 - }, - { - "fetch_from": "student.title", - "fieldname": "student_name", - "fieldtype": "Read Only", - "in_global_search": 1, - "label": "Student Name", - "read_only": 1 - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fieldname": "from_date", - "fieldtype": "Date", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "From Date", - "reqd": 1 - }, - { - "fieldname": "to_date", - "fieldtype": "Date", - "in_list_view": 1, - "label": "To Date", - "reqd": 1 - }, - { - "default": "0", - "description": "Check this to mark the student as present in case the student is not attending the institute to participate or represent the institute in any event.\n\n", - "fieldname": "mark_as_present", - "fieldtype": "Check", - "label": "Mark as Present" - }, - { - "fieldname": "section_break_5", - "fieldtype": "Section Break" - }, - { - "fieldname": "reason", - "fieldtype": "Text", - "label": "Reason" - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Student Leave Application", - "print_hide": 1, - "read_only": 1 - }, - { - "allow_in_quick_entry": 1, - "default": "Student Group", - "fieldname": "attendance_based_on", - "fieldtype": "Select", - "label": "Attendance Based On", - "options": "Student Group\nCourse Schedule" - }, - { - "allow_in_quick_entry": 1, - "depends_on": "eval:doc.attendance_based_on === \"Student Group\";", - "fieldname": "student_group", - "fieldtype": "Link", - "label": "Student Group", - "mandatory_depends_on": "eval:doc.attendance_based_on === \"Student Group\";", - "options": "Student Group" - }, - { - "allow_in_quick_entry": 1, - "depends_on": "eval:doc.attendance_based_on === \"Course Schedule\";", - "fieldname": "course_schedule", - "fieldtype": "Link", - "label": "Course Schedule", - "mandatory_depends_on": "eval:doc.attendance_based_on === \"Course Schedule\";", - "options": "Course Schedule" - }, - { - "fieldname": "column_break_11", - "fieldtype": "Column Break" - }, - { - "fieldname": "total_leave_days", - "fieldtype": "Float", - "label": "Total Leave Days", - "read_only": 1 - } - ], - "is_submittable": 1, - "links": [], - "modified": "2020-09-21 18:10:24.440669", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Leave Application", - "owner": "Administrator", - "permissions": [ - { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "submit": 1, - "write": 1 - }, - { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "share": 1, - "submit": 1, - "write": 1 - } - ], - "quick_entry": 1, - "restrict_to_domain": "Education", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "student_name" -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_leave_application/student_leave_application.py b/erpnext/education/doctype/student_leave_application/student_leave_application.py deleted file mode 100644 index c3645cf485..0000000000 --- a/erpnext/education/doctype/student_leave_application/student_leave_application.py +++ /dev/null @@ -1,135 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from datetime import timedelta - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.utils import date_diff, flt, get_link_to_form, getdate - -from erpnext.education.doctype.student_attendance.student_attendance import get_holiday_list -from erpnext.hr.doctype.holiday_list.holiday_list import is_holiday - - -class StudentLeaveApplication(Document): - def validate(self): - self.validate_holiday_list() - self.validate_duplicate() - self.validate_from_to_dates("from_date", "to_date") - - def on_submit(self): - self.update_attendance() - - def on_cancel(self): - self.cancel_attendance() - - def validate_duplicate(self): - data = frappe.db.sql( - """select name from `tabStudent Leave Application` - where - ((%(from_date)s > from_date and %(from_date)s < to_date) or - (%(to_date)s > from_date and %(to_date)s < to_date) or - (%(from_date)s <= from_date and %(to_date)s >= to_date)) and - name != %(name)s and student = %(student)s and docstatus < 2 - """, - { - "from_date": self.from_date, - "to_date": self.to_date, - "student": self.student, - "name": self.name, - }, - as_dict=1, - ) - - if data: - link = get_link_to_form("Student Leave Application", data[0].name) - frappe.throw( - _("Leave application {0} already exists against the student {1}").format( - link, frappe.bold(self.student) - ), - title=_("Duplicate Entry"), - ) - - def validate_holiday_list(self): - holiday_list = get_holiday_list() - self.total_leave_days = get_number_of_leave_days(self.from_date, self.to_date, holiday_list) - - def update_attendance(self): - holiday_list = get_holiday_list() - - for dt in daterange(getdate(self.from_date), getdate(self.to_date)): - date = dt.strftime("%Y-%m-%d") - - if is_holiday(holiday_list, date): - continue - - attendance = frappe.db.exists( - "Student Attendance", {"student": self.student, "date": date, "docstatus": ("!=", 2)} - ) - - status = "Present" if self.mark_as_present else "Absent" - if attendance: - # update existing attendance record - values = dict() - values["status"] = status - values["leave_application"] = self.name - frappe.db.set_value("Student Attendance", attendance, values) - else: - # make a new attendance record - doc = frappe.new_doc("Student Attendance") - doc.student = self.student - doc.student_name = self.student_name - doc.date = date - doc.leave_application = self.name - doc.status = status - if self.attendance_based_on == "Student Group": - doc.student_group = self.student_group - else: - doc.course_schedule = self.course_schedule - doc.insert(ignore_permissions=True, ignore_mandatory=True) - doc.submit() - - def cancel_attendance(self): - if self.docstatus == 2: - attendance = frappe.db.sql( - """ - SELECT name - FROM `tabStudent Attendance` - WHERE - student = %s and - (date between %s and %s) and - docstatus < 2 - """, - (self.student, self.from_date, self.to_date), - as_dict=1, - ) - - for name in attendance: - frappe.db.set_value("Student Attendance", name, "docstatus", 2) - - -def daterange(start_date, end_date): - for n in range(int((end_date - start_date).days) + 1): - yield start_date + timedelta(n) - - -def get_number_of_leave_days(from_date, to_date, holiday_list): - number_of_days = date_diff(to_date, from_date) + 1 - - holidays = frappe.db.sql( - """ - SELECT - COUNT(DISTINCT holiday_date) - FROM `tabHoliday` h1,`tabHoliday List` h2 - WHERE - h1.parent = h2.name and - h1.holiday_date between %s and %s and - h2.name = %s""", - (from_date, to_date, holiday_list), - )[0][0] - - number_of_days = flt(number_of_days) - flt(holidays) - - return number_of_days diff --git a/erpnext/education/doctype/student_leave_application/student_leave_application_dashboard.py b/erpnext/education/doctype/student_leave_application/student_leave_application_dashboard.py deleted file mode 100644 index 8819c3bf65..0000000000 --- a/erpnext/education/doctype/student_leave_application/student_leave_application_dashboard.py +++ /dev/null @@ -1,2 +0,0 @@ -def get_data(): - return {"fieldname": "leave_application", "transactions": [{"items": ["Student Attendance"]}]} diff --git a/erpnext/education/doctype/student_leave_application/test_student_leave_application.py b/erpnext/education/doctype/student_leave_application/test_student_leave_application.py deleted file mode 100644 index 7146fc2576..0000000000 --- a/erpnext/education/doctype/student_leave_application/test_student_leave_application.py +++ /dev/null @@ -1,131 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -import frappe -from frappe.utils import add_days, add_months, getdate - -from erpnext import get_default_company -from erpnext.education.doctype.student.test_student import create_student -from erpnext.education.doctype.student_group.test_student_group import get_random_group - - -class TestStudentLeaveApplication(unittest.TestCase): - def setUp(self): - frappe.db.sql("""delete from `tabStudent Leave Application`""") - create_holiday_list() - - def test_attendance_record_creation(self): - leave_application = create_leave_application() - attendance_record = frappe.db.exists( - "Student Attendance", {"leave_application": leave_application.name, "status": "Absent"} - ) - self.assertTrue(attendance_record) - - # mark as present - date = add_days(getdate(), -1) - leave_application = create_leave_application(date, date, 1) - attendance_record = frappe.db.exists( - "Student Attendance", {"leave_application": leave_application.name, "status": "Present"} - ) - self.assertTrue(attendance_record) - - def test_attendance_record_updated(self): - attendance = create_student_attendance() - create_leave_application() - self.assertEqual(frappe.db.get_value("Student Attendance", attendance.name, "status"), "Absent") - - def test_attendance_record_cancellation(self): - leave_application = create_leave_application() - leave_application.cancel() - attendance_status = frappe.db.get_value( - "Student Attendance", {"leave_application": leave_application.name}, "docstatus" - ) - self.assertTrue(attendance_status, 2) - - def test_holiday(self): - today = getdate() - leave_application = create_leave_application( - from_date=today, to_date=add_days(today, 1), submit=0 - ) - - # holiday list validation - company = get_default_company() or frappe.get_all("Company")[0].name - frappe.db.set_value("Company", company, "default_holiday_list", "") - self.assertRaises(frappe.ValidationError, leave_application.save) - - frappe.db.set_value("Company", company, "default_holiday_list", "Test Holiday List for Student") - leave_application.save() - - leave_application.reload() - self.assertEqual(leave_application.total_leave_days, 1) - - # check no attendance record created for a holiday - leave_application.submit() - self.assertIsNone( - frappe.db.exists( - "Student Attendance", {"leave_application": leave_application.name, "date": add_days(today, 1)} - ) - ) - - def tearDown(self): - company = get_default_company() or frappe.get_all("Company")[0].name - frappe.db.set_value("Company", company, "default_holiday_list", "_Test Holiday List") - - -def create_leave_application(from_date=None, to_date=None, mark_as_present=0, submit=1): - student = get_student() - - leave_application = frappe.new_doc("Student Leave Application") - leave_application.student = student.name - leave_application.attendance_based_on = "Student Group" - leave_application.student_group = get_random_group().name - leave_application.from_date = from_date if from_date else getdate() - leave_application.to_date = from_date if from_date else getdate() - leave_application.mark_as_present = mark_as_present - - if submit: - leave_application.insert() - leave_application.submit() - - return leave_application - - -def create_student_attendance(date=None, status=None): - student = get_student() - attendance = frappe.get_doc( - { - "doctype": "Student Attendance", - "student": student.name, - "status": status if status else "Present", - "date": date if date else getdate(), - "student_group": get_random_group().name, - } - ).insert() - return attendance - - -def get_student(): - return create_student( - dict(email="test_student@gmail.com", first_name="Test", last_name="Student") - ) - - -def create_holiday_list(): - holiday_list = "Test Holiday List for Student" - today = getdate() - if not frappe.db.exists("Holiday List", holiday_list): - frappe.get_doc( - dict( - doctype="Holiday List", - holiday_list_name=holiday_list, - from_date=add_months(today, -6), - to_date=add_months(today, 6), - holidays=[dict(holiday_date=add_days(today, 1), description="Test")], - ) - ).insert() - - company = get_default_company() or frappe.get_all("Company")[0].name - frappe.db.set_value("Company", company, "default_holiday_list", holiday_list) - return holiday_list diff --git a/erpnext/education/doctype/student_log/__init__.py b/erpnext/education/doctype/student_log/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_log/student_log.js b/erpnext/education/doctype/student_log/student_log.js deleted file mode 100644 index 40e63e9f88..0000000000 --- a/erpnext/education/doctype/student_log/student_log.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Student Log', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/student_log/student_log.json b/erpnext/education/doctype/student_log/student_log.json deleted file mode 100644 index cdd6aaa826..0000000000 --- a/erpnext/education/doctype/student_log/student_log.json +++ /dev/null @@ -1,423 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "EDU-SLOG-.YYYY.-.#####", - "beta": 0, - "creation": "2016-07-29 03:27:22.451772", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 1, - "label": "Student", - "length": 0, - "no_copy": 0, - "options": "Student", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "student.title", - "fieldname": "student_name", - "fieldtype": "Read Only", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Student Name", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "type", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Type", - "length": 0, - "no_copy": 0, - "options": "General\nAcademic\nMedical\nAchievement", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_3", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "academic_year", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Academic Year", - "length": 0, - "no_copy": 0, - "options": "Academic Year", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "academic_term", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Academic Term", - "length": 0, - "no_copy": 0, - "options": "Academic Term", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "program", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Program", - "length": 0, - "no_copy": 0, - "options": "Program", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student_batch", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Student Batch", - "length": 0, - "no_copy": 0, - "options": "Student Batch Name", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_5", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "log", - "fieldtype": "Text Editor", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Log", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-08-21 16:15:47.027645", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Log", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "student_name", - "track_changes": 0, - "track_seen": 1, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_log/student_log.py b/erpnext/education/doctype/student_log/student_log.py deleted file mode 100644 index b95f34e049..0000000000 --- a/erpnext/education/doctype/student_log/student_log.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class StudentLog(Document): - pass diff --git a/erpnext/education/doctype/student_log/test_student_log.py b/erpnext/education/doctype/student_log/test_student_log.py deleted file mode 100644 index fef1ab56ac..0000000000 --- a/erpnext/education/doctype/student_log/test_student_log.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -# test_records = frappe.get_test_records('Student Log') - - -class TestStudentLog(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/student_report_generation_tool/__init__.py b/erpnext/education/doctype/student_report_generation_tool/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html deleted file mode 100644 index a9e84e6e27..0000000000 --- a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html +++ /dev/null @@ -1,371 +0,0 @@ - - - - -
- -
- - {% if letterhead and add_letterhead %} -
{{ letterhead }}
- {% endif %} - -
- -
-
-
-
- -
-
- {{ doc.students[0] }} -
-
- -
-
- -
-
- {{ doc.student_name }} -
-
- -
-
- -
-
- {{ doc.program }} -
-
- -
-
- -
-
- {{ doc.student_batch }} -
-
-
- -
-
-
- -
-
- {{ doc.academic_year }} -
-
- - {% if doc.academic_term %} -
-
- -
-
- {{ doc.academic_term }} -
-
- {% endif %} - -
-
- -
-
- {{ doc.assessment_group }} -
-
-
-
- - -{% if doc.show_marks | int %} - {% set result_data = 'score' %} -{% else %} - {% set result_data = 'grade' %} -{% endif %} - - -{% for course in courses %} - -
-
- -
- - - - - - {% for assessment_group in assessment_groups %} - - {% endfor %} - - - - - {% for criteria in course_criteria[course] %} - - - {% for assessment_group in assessment_groups %} - {% if (assessment_result.get(course) and assessment_result.get(course).get(assessment_group) and assessment_result.get(course).get(assessment_group).get(criteria)) %} - - {% else %} - - {% endif %} - {% endfor %} - - {% endfor %} - - -
-
-
- -
-
- {{ course }} ({{ frappe.db.get_value("Course", course, "course_name") }}) -
-
-
{{ _("Assessment Criteria") }} {{ assessment_group }}
{{ criteria }} - {{ assessment_result.get(course).get(assessment_group).get(criteria).get(result_data) }} - {% if result_data == 'score' %} - ({{ assessment_result.get(course).get(assessment_group).get(criteria).get('maximum_score') }}) - {% endif %} -
-
-
-
- -{% endfor %} - -
- -
-
-

{{ _("Student Attendance")}}


-
- Present {{ doc.attendance.get("Present") if doc.attendance.get("Present") != None else '0' }} days - out of {{ doc.attendance.get("Present") + doc.attendance.get("Absent") }} -
-
- -
-

{{ _("Parents Teacher Meeting Attendance")}}


-
- Present {{ doc.parents_attendance if doc.parents_attendance != None else '0' }} - out of {{ doc.parents_meeting if doc.parents_meeting != None else '0' }} -
-
-
- -{% if doc.assessment_terms %} -
-
-

{{ doc.assessment_terms }}

-
-
-{% endif %} -
diff --git a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.js b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.js deleted file mode 100644 index 565074d878..0000000000 --- a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.js +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Student Report Generation Tool', { - onload: function(frm) { - frm.set_query("academic_term",function(){ - return{ - "filters":{ - "academic_year": frm.doc.academic_year - } - }; - }); - frm.set_query("assessment_group", function() { - return{ - filters: { - "is_group": 1 - } - }; - }); - }, - - refresh: function(frm) { - frm.disable_save(); - frm.page.clear_indicator(); - frm.page.set_primary_action(__('Print Report Card'), () => { - let url = "/api/method/erpnext.education.doctype.student_report_generation_tool.student_report_generation_tool.preview_report_card"; - open_url_post(url, {"doc": frm.doc}, true); - }); - }, - - student: function(frm) { - if (frm.doc.student) { - frappe.call({ - method:"erpnext.education.api.get_current_enrollment", - args: { - "student": frm.doc.student, - "academic_year": frm.doc.academic_year - }, - callback: function(r) { - if(r){ - $.each(r.message, function(i, d) { - if (frm.fields_dict.hasOwnProperty(i)) { - frm.set_value(i, d); - } - }); - } - } - }); - } - }, - - terms: function(frm) { - if(frm.doc.terms) { - return frappe.call({ - method: 'erpnext.setup.doctype.terms_and_conditions.terms_and_conditions.get_terms_and_conditions', - args: { - template_name: frm.doc.terms, - doc: frm.doc - }, - callback: function(r) { - frm.set_value("assessment_terms", r.message); - } - }); - } - } -}); diff --git a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.json b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.json deleted file mode 100644 index a3282990d0..0000000000 --- a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.json +++ /dev/null @@ -1,618 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-01-15 15:36:32.830069", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Student", - "length": 0, - "no_copy": 0, - "options": "Student", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student_name", - "fieldtype": "Read Only", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Student Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "program", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Program", - "length": 0, - "no_copy": 0, - "options": "Program", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student_batch", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Batch", - "length": 0, - "no_copy": 0, - "options": "Student Batch Name", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "include_all_assessment", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Include All Assessment Group", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "show_marks", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Show Marks", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "1", - "fieldname": "add_letterhead", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Add letterhead", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_3", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "assessment_group", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Assessment Group", - "length": 0, - "no_copy": 0, - "options": "Assessment Group", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "academic_year", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Academic Year", - "length": 0, - "no_copy": 0, - "options": "Academic Year", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "academic_term", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Academic Term", - "length": 0, - "no_copy": 0, - "options": "Academic Term", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "add_letterhead", - "fieldname": "letter_head", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Letter Head", - "length": 0, - "no_copy": 0, - "options": "Letter Head", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_5", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Print Section", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "parents_meeting", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Total Parents Teacher Meeting", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "parents_attendance", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Attended by Parents", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "terms", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Terms", - "length": 0, - "no_copy": 0, - "options": "Terms and Conditions", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "assessment_terms", - "fieldtype": "Text Editor", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Assessment Terms", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 1, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 1, - "istable": 0, - "max_attachments": 0, - "modified": "2018-11-04 03:38:42.970869", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Report Generation Tool", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 0, - "role": "System Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.py b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.py deleted file mode 100644 index ae3c140a2e..0000000000 --- a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.py +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import json - -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.utils.pdf import get_pdf - -from erpnext.education.report.course_wise_assessment_report.course_wise_assessment_report import ( - get_child_assessment_groups, - get_formatted_result, -) - - -class StudentReportGenerationTool(Document): - pass - - -@frappe.whitelist() -def preview_report_card(doc): - doc = frappe._dict(json.loads(doc)) - doc.students = [doc.student] - if not (doc.student_name and doc.student_batch): - program_enrollment = frappe.get_all( - "Program Enrollment", - fields=["student_batch_name", "student_name"], - filters={"student": doc.student, "docstatus": ("!=", 2), "academic_year": doc.academic_year}, - ) - if program_enrollment: - doc.batch = program_enrollment[0].student_batch_name - doc.student_name = program_enrollment[0].student_name - - # get the assessment result of the selected student - values = get_formatted_result( - doc, get_course=True, get_all_assessment_groups=doc.include_all_assessment - ) - assessment_result = values.get("assessment_result").get(doc.student) - courses = values.get("course_dict") - course_criteria = get_courses_criteria(courses) - - # get the assessment group as per the user selection - if doc.include_all_assessment: - assessment_groups = get_child_assessment_groups(doc.assessment_group) - else: - assessment_groups = [doc.assessment_group] - - # get the attendance of the student for that peroid of time. - doc.attendance = get_attendance_count(doc.students[0], doc.academic_year, doc.academic_term) - - template = ( - "erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html" - ) - base_template_path = "frappe/www/printview.html" - - from frappe.www.printview import get_letter_head - - letterhead = get_letter_head( - frappe._dict({"letter_head": doc.letterhead}), not doc.add_letterhead - ) - - html = frappe.render_template( - template, - { - "doc": doc, - "assessment_result": assessment_result, - "courses": courses, - "assessment_groups": assessment_groups, - "course_criteria": course_criteria, - "letterhead": letterhead and letterhead.get("content", None), - "add_letterhead": doc.add_letterhead if doc.add_letterhead else 0, - }, - ) - final_template = frappe.render_template( - base_template_path, {"body": html, "title": "Report Card"} - ) - - frappe.response.filename = "Report Card " + doc.students[0] + ".pdf" - frappe.response.filecontent = get_pdf(final_template) - frappe.response.type = "download" - - -def get_courses_criteria(courses): - course_criteria = frappe._dict() - for course in courses: - course_criteria[course] = [ - d.assessment_criteria - for d in frappe.get_all( - "Course Assessment Criteria", fields=["assessment_criteria"], filters={"parent": course} - ) - ] - return course_criteria - - -def get_attendance_count(student, academic_year, academic_term=None): - if academic_year: - from_date, to_date = frappe.db.get_value( - "Academic Year", academic_year, ["year_start_date", "year_end_date"] - ) - elif academic_term: - from_date, to_date = frappe.db.get_value( - "Academic Term", academic_term, ["term_start_date", "term_end_date"] - ) - if from_date and to_date: - attendance = dict( - frappe.db.sql( - """select status, count(student) as no_of_days - from `tabStudent Attendance` where student = %s and docstatus = 1 - and date between %s and %s group by status""", - (student, from_date, to_date), - ) - ) - if "Absent" not in attendance.keys(): - attendance["Absent"] = 0 - if "Present" not in attendance.keys(): - attendance["Present"] = 0 - return attendance - else: - frappe.throw(_("Provide the academic year and set the starting and ending date.")) diff --git a/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.py b/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.py deleted file mode 100644 index e37881f012..0000000000 --- a/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestStudentReportGenerationTool(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/student_sibling/__init__.py b/erpnext/education/doctype/student_sibling/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_sibling/student_sibling.json b/erpnext/education/doctype/student_sibling/student_sibling.json deleted file mode 100644 index f67fe79d98..0000000000 --- a/erpnext/education/doctype/student_sibling/student_sibling.json +++ /dev/null @@ -1,306 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-09-01 14:41:23.824083", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 0, - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "studying_in_same_institute", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Studying in Same Institute", - "length": 0, - "no_copy": 0, - "options": "NO\nYES", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 3, - "fieldname": "full_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Full Name", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 1, - "fieldname": "gender", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Gender", - "length": 0, - "no_copy": 0, - "options": "\nMale\nFemale", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "", - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_4", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.studying_in_same_institute == \"YES\"", - "fieldname": "student", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Student ID", - "length": 0, - "no_copy": 0, - "options": "Student", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 2, - "depends_on": "eval:doc.studying_in_same_institute == \"NO\"", - "fieldname": "institution", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Institution", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 2, - "fieldname": "program", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Program", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 2, - "fieldname": "date_of_birth", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Date of Birth", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-11-04 03:37:25.881487", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Sibling", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_sibling/student_sibling.py b/erpnext/education/doctype/student_sibling/student_sibling.py deleted file mode 100644 index 9ee0667d14..0000000000 --- a/erpnext/education/doctype/student_sibling/student_sibling.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class StudentSibling(Document): - pass diff --git a/erpnext/education/doctype/student_siblings/__init__.py b/erpnext/education/doctype/student_siblings/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/student_siblings/student_siblings.json b/erpnext/education/doctype/student_siblings/student_siblings.json deleted file mode 100644 index 9d91ad2e2c..0000000000 --- a/erpnext/education/doctype/student_siblings/student_siblings.json +++ /dev/null @@ -1,141 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-09-01 14:41:23.824083", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "name1", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Name", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "gender", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Gender", - "length": 0, - "no_copy": 0, - "options": "\nMale\nFemale", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "date_of_birth", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Date of Birth", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-11-04 03:37:46.485218", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Siblings", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/education/doctype/student_siblings/student_siblings.py b/erpnext/education/doctype/student_siblings/student_siblings.py deleted file mode 100644 index ee89f4f157..0000000000 --- a/erpnext/education/doctype/student_siblings/student_siblings.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class StudentSiblings(Document): - pass diff --git a/erpnext/education/doctype/topic/__init__.py b/erpnext/education/doctype/topic/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/topic/test_topic.py b/erpnext/education/doctype/topic/test_topic.py deleted file mode 100644 index c11204a575..0000000000 --- a/erpnext/education/doctype/topic/test_topic.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - -import frappe - - -class TestTopic(unittest.TestCase): - def setUp(self): - make_topic_and_linked_content("_Test Topic 1", [{"type": "Article", "name": "_Test Article 1"}]) - - def test_get_contents(self): - topic = frappe.get_doc("Topic", "_Test Topic 1") - contents = topic.get_contents() - self.assertEqual(contents[0].doctype, "Article") - self.assertEqual(contents[0].name, "_Test Article 1") - frappe.db.rollback() - - -def make_topic(name): - try: - topic = frappe.get_doc("Topic", name) - except frappe.DoesNotExistError: - topic = frappe.get_doc( - { - "doctype": "Topic", - "topic_name": name, - "topic_code": name, - } - ).insert() - return topic.name - - -def make_topic_and_linked_content(topic_name, content_dict_list): - try: - topic = frappe.get_doc("Topic", topic_name) - except frappe.DoesNotExistError: - make_topic(topic_name) - topic = frappe.get_doc("Topic", topic_name) - content_list = [make_content(content["type"], content["name"]) for content in content_dict_list] - for content in content_list: - topic.append("topic_content", {"content": content.title, "content_type": content.doctype}) - topic.save() - return topic - - -def make_content(type, name): - try: - content = frappe.get_doc(type, name) - except frappe.DoesNotExistError: - content = frappe.get_doc({"doctype": type, "title": name}).insert() - return content diff --git a/erpnext/education/doctype/topic/topic.js b/erpnext/education/doctype/topic/topic.js deleted file mode 100644 index 0c903c5a56..0000000000 --- a/erpnext/education/doctype/topic/topic.js +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Topic', { - refresh: function(frm) { - if (!cur_frm.doc.__islocal) { - frm.add_custom_button(__('Add to Courses'), function() { - frm.trigger('add_topic_to_courses'); - }, __('Action')); - } - }, - - add_topic_to_courses: function(frm) { - get_courses_without_topic(frm.doc.name).then(r => { - if (r.message.length) { - frappe.prompt([ - { - fieldname: 'courses', - label: __('Courses'), - fieldtype: 'MultiSelectPills', - get_data: function() { - return r.message; - } - } - ], - function(data) { - frappe.call({ - method: 'erpnext.education.doctype.topic.topic.add_topic_to_courses', - args: { - 'topic': frm.doc.name, - 'courses': data.courses - }, - callback: function(r) { - if (!r.exc) { - frm.reload_doc(); - } - }, - freeze: true, - freeze_message: __('...Adding Topic to Courses') - }); - }, __('Add Topic to Courses'), __('Add')); - } else { - frappe.msgprint(__('This topic is already added to the existing courses')); - } - }); - } -}); - -let get_courses_without_topic = function(topic) { - return frappe.call({ - type: 'GET', - method: 'erpnext.education.doctype.topic.topic.get_courses_without_topic', - args: {'topic': topic} - }); -}; diff --git a/erpnext/education/doctype/topic/topic.json b/erpnext/education/doctype/topic/topic.json deleted file mode 100644 index 305458bf67..0000000000 --- a/erpnext/education/doctype/topic/topic.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:topic_name", - "creation": "2018-12-12 11:37:39.917760", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "topic_name", - "topic_content", - "description", - "hero_image" - ], - "fields": [ - { - "fieldname": "topic_name", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Name", - "reqd": 1, - "unique": 1 - }, - { - "fieldname": "topic_content", - "fieldtype": "Table", - "label": "Topic Content", - "options": "Topic Content" - }, - { - "fieldname": "hero_image", - "fieldtype": "Attach Image", - "hidden": 1, - "label": "Hero Image" - }, - { - "fieldname": "description", - "fieldtype": "Small Text", - "label": "Description" - } - ], - "image_field": "hero_image", - "modified": "2019-06-12 12:34:49.911300", - "modified_by": "Administrator", - "module": "Education", - "name": "Topic", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Administrator", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "share": 1, - "write": 1 - } - ], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/education/doctype/topic/topic.py b/erpnext/education/doctype/topic/topic.py deleted file mode 100644 index 6dd965552b..0000000000 --- a/erpnext/education/doctype/topic/topic.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import json - -import frappe -from frappe import _ -from frappe.model.document import Document - - -class Topic(Document): - def get_contents(self): - try: - topic_content_list = self.topic_content - content_data = [ - frappe.get_doc(topic_content.content_type, topic_content.content) - for topic_content in topic_content_list - ] - except Exception as e: - frappe.log_error(frappe.get_traceback()) - return None - return content_data - - -@frappe.whitelist() -def get_courses_without_topic(topic): - data = [] - for entry in frappe.db.get_all("Course"): - course = frappe.get_doc("Course", entry.name) - topics = [t.topic for t in course.topics] - if not topics or topic not in topics: - data.append(course.name) - return data - - -@frappe.whitelist() -def add_topic_to_courses(topic, courses, mandatory=False): - courses = json.loads(courses) - for entry in courses: - course = frappe.get_doc("Course", entry) - course.append("topics", {"topic": topic, "topic_name": topic}) - course.flags.ignore_mandatory = True - course.save() - frappe.db.commit() - frappe.msgprint( - _("Topic {0} has been added to all the selected courses successfully.").format( - frappe.bold(topic) - ), - title=_("Courses updated"), - indicator="green", - ) - - -@frappe.whitelist() -def add_content_to_topics(content_type, content, topics): - topics = json.loads(topics) - for entry in topics: - topic = frappe.get_doc("Topic", entry) - topic.append( - "topic_content", - { - "content_type": content_type, - "content": content, - }, - ) - topic.flags.ignore_mandatory = True - topic.save() - frappe.db.commit() - frappe.msgprint( - _("{0} {1} has been added to all the selected topics successfully.").format( - content_type, frappe.bold(content) - ), - title=_("Topics updated"), - indicator="green", - ) diff --git a/erpnext/education/doctype/topic_content/__init__.py b/erpnext/education/doctype/topic_content/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/topic_content/test_topic_content.py b/erpnext/education/doctype/topic_content/test_topic_content.py deleted file mode 100644 index 56bb40968c..0000000000 --- a/erpnext/education/doctype/topic_content/test_topic_content.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -import unittest - - -class TestTopicContent(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/topic_content/topic_content.js b/erpnext/education/doctype/topic_content/topic_content.js deleted file mode 100644 index 9cda0cabb2..0000000000 --- a/erpnext/education/doctype/topic_content/topic_content.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Topic Content', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/topic_content/topic_content.json b/erpnext/education/doctype/topic_content/topic_content.json deleted file mode 100644 index 444fd1d07c..0000000000 --- a/erpnext/education/doctype/topic_content/topic_content.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "creation": "2018-12-12 11:42:57.987434", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "content_type", - "column_break_2", - "content" - ], - "fields": [ - { - "fieldname": "content_type", - "fieldtype": "Select", - "in_list_view": 1, - "label": "Content Type", - "options": "\nArticle\nVideo\nQuiz", - "reqd": 1 - }, - { - "fieldname": "column_break_2", - "fieldtype": "Column Break" - }, - { - "fieldname": "content", - "fieldtype": "Dynamic Link", - "in_list_view": 1, - "label": "Content", - "options": "content_type", - "reqd": 1 - } - ], - "istable": 1, - "modified": "2019-05-14 11:12:49.153771", - "modified_by": "Administrator", - "module": "Education", - "name": "Topic Content", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/education/doctype/topic_content/topic_content.py b/erpnext/education/doctype/topic_content/topic_content.py deleted file mode 100644 index 88d0eee73a..0000000000 --- a/erpnext/education/doctype/topic_content/topic_content.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from frappe.model.document import Document - - -class TopicContent(Document): - pass diff --git a/erpnext/education/education_dashboard/education/education.json b/erpnext/education/education_dashboard/education/education.json deleted file mode 100644 index 41d33758b9..0000000000 --- a/erpnext/education/education_dashboard/education/education.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "cards": [ - { - "card": "Total Students" - }, - { - "card": "Total Instructors" - }, - { - "card": "Program Enrollments" - }, - { - "card": "Student Applicants to Review" - } - ], - "charts": [ - { - "chart": "Program Enrollments", - "width": "Full" - }, - { - "chart": "Program wise Enrollment", - "width": "Half" - }, - { - "chart": "Course wise Enrollment", - "width": "Half" - }, - { - "chart": "Course wise Student Count", - "width": "Half" - }, - { - "chart": "Student Category wise Program Enrollments", - "width": "Half" - }, - { - "chart": "Student Gender Diversity Ratio", - "width": "Half" - }, - { - "chart": "Instructor Gender Diversity Ratio", - "width": "Half" - }, - { - "chart": "Program wise Fee Collection", - "width": "Full" - } - ], - "creation": "2020-07-22 18:51:02.195762", - "dashboard_name": "Education", - "docstatus": 0, - "doctype": "Dashboard", - "idx": 0, - "is_default": 0, - "is_standard": 1, - "modified": "2020-08-05 16:22:17.428101", - "modified_by": "Administrator", - "module": "Education", - "name": "Education", - "owner": "Administrator" -} \ No newline at end of file diff --git a/erpnext/education/module_onboarding/education/education.json b/erpnext/education/module_onboarding/education/education.json deleted file mode 100644 index e5f0fec3d1..0000000000 --- a/erpnext/education/module_onboarding/education/education.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "allow_roles": [ - { - "role": "Education Manager" - } - ], - "creation": "2020-07-27 19:02:49.561391", - "docstatus": 0, - "doctype": "Module Onboarding", - "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/education", - "idx": 0, - "is_complete": 0, - "modified": "2020-07-27 21:10:46.722961", - "modified_by": "Administrator", - "module": "Education", - "name": "Education", - "owner": "Administrator", - "steps": [ - { - "step": "Create a Student" - }, - { - "step": "Create an Instructor" - }, - { - "step": "Introduction to Program and Courses" - }, - { - "step": "Create a Topic" - }, - { - "step": "Create a Course" - }, - { - "step": "Create a Program" - }, - { - "step": "Enroll a Student in a Program" - }, - { - "step": "Introduction to Student Group" - }, - { - "step": "Introduction to Student Attendance" - } - ], - "subtitle": "Students, Instructors, Programs and more.", - "success_message": "The Education Module is all set up!", - "title": "Let's Set Up the Education Module." -} diff --git a/erpnext/education/number_card/program_enrollments/program_enrollments.json b/erpnext/education/number_card/program_enrollments/program_enrollments.json deleted file mode 100644 index 5847679ddd..0000000000 --- a/erpnext/education/number_card/program_enrollments/program_enrollments.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "aggregate_function_based_on": "", - "creation": "2020-07-27 18:26:27.005186", - "docstatus": 0, - "doctype": "Number Card", - "document_type": "Program Enrollment", - "dynamic_filters_json": "[]", - "filters_json": "[[\"Program Enrollment\",\"docstatus\",\"=\",\"1\",false],[\"Program Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false]]", - "function": "Count", - "idx": 0, - "is_public": 1, - "is_standard": 1, - "label": "Program Enrollments", - "modified": "2020-07-27 18:26:32.512624", - "modified_by": "Administrator", - "module": "Education", - "name": "Program Enrollments", - "owner": "Administrator", - "report_function": "Sum", - "show_percentage_stats": 1, - "stats_time_interval": "Yearly", - "type": "Document Type" -} \ No newline at end of file diff --git a/erpnext/education/number_card/student_applicants_to_review/student_applicants_to_review.json b/erpnext/education/number_card/student_applicants_to_review/student_applicants_to_review.json deleted file mode 100644 index 258667a2d4..0000000000 --- a/erpnext/education/number_card/student_applicants_to_review/student_applicants_to_review.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "aggregate_function_based_on": "", - "creation": "2020-07-27 18:42:33.366862", - "docstatus": 0, - "doctype": "Number Card", - "document_type": "Student Applicant", - "dynamic_filters_json": "[]", - "filters_json": "[[\"Student Applicant\",\"application_status\",\"=\",\"Applied\",false]]", - "function": "Count", - "idx": 0, - "is_public": 1, - "is_standard": 1, - "label": "Student Applicants to Review", - "modified": "2020-07-27 18:42:42.739710", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Applicants to Review", - "owner": "Administrator", - "report_function": "Sum", - "show_percentage_stats": 1, - "stats_time_interval": "Monthly", - "type": "Document Type" -} \ No newline at end of file diff --git a/erpnext/education/number_card/total_instructors/total_instructors.json b/erpnext/education/number_card/total_instructors/total_instructors.json deleted file mode 100644 index b8d3cc0fdf..0000000000 --- a/erpnext/education/number_card/total_instructors/total_instructors.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "aggregate_function_based_on": "", - "creation": "2020-07-23 14:19:38.423190", - "docstatus": 0, - "doctype": "Number Card", - "document_type": "Instructor", - "dynamic_filters_json": "[]", - "filters_json": "[[\"Instructor\",\"status\",\"=\",\"Active\",false]]", - "function": "Count", - "idx": 0, - "is_public": 1, - "is_standard": 1, - "label": "Total Instructors", - "modified": "2020-07-23 14:19:47.623306", - "modified_by": "Administrator", - "module": "Education", - "name": "Total Instructors", - "owner": "Administrator", - "report_function": "Sum", - "show_percentage_stats": 1, - "stats_time_interval": "Monthly", - "type": "Document Type" -} \ No newline at end of file diff --git a/erpnext/education/number_card/total_students/total_students.json b/erpnext/education/number_card/total_students/total_students.json deleted file mode 100644 index 109c3d8ad9..0000000000 --- a/erpnext/education/number_card/total_students/total_students.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "aggregate_function_based_on": "", - "creation": "2020-07-23 14:18:07.732298", - "docstatus": 0, - "doctype": "Number Card", - "document_type": "Student", - "dynamic_filters_json": "[]", - "filters_json": "[[\"Student\",\"enabled\",\"=\",1,false]]", - "function": "Count", - "idx": 0, - "is_public": 1, - "is_standard": 1, - "label": "Total Students", - "modified": "2020-07-23 14:18:40.603947", - "modified_by": "Administrator", - "module": "Education", - "name": "Total Students", - "owner": "Administrator", - "report_function": "Sum", - "show_percentage_stats": 1, - "stats_time_interval": "Monthly", - "type": "Document Type" -} \ No newline at end of file diff --git a/erpnext/education/onboarding_step/create_a_course/create_a_course.json b/erpnext/education/onboarding_step/create_a_course/create_a_course.json deleted file mode 100644 index 02eee14056..0000000000 --- a/erpnext/education/onboarding_step/create_a_course/create_a_course.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "action": "Create Entry", - "creation": "2020-07-27 19:09:04.493932", - "docstatus": 0, - "doctype": "Onboarding Step", - "idx": 0, - "is_complete": 0, - "is_mandatory": 0, - "is_single": 0, - "is_skipped": 0, - "modified": "2020-07-27 19:09:04.493932", - "modified_by": "Administrator", - "name": "Create a Course", - "owner": "Administrator", - "reference_document": "Course", - "show_full_form": 1, - "title": "Create a Course", - "validate_action": 1 -} \ No newline at end of file diff --git a/erpnext/education/onboarding_step/create_a_program/create_a_program.json b/erpnext/education/onboarding_step/create_a_program/create_a_program.json deleted file mode 100644 index 61726304e0..0000000000 --- a/erpnext/education/onboarding_step/create_a_program/create_a_program.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "action": "Create Entry", - "creation": "2020-07-27 19:09:35.451945", - "docstatus": 0, - "doctype": "Onboarding Step", - "idx": 0, - "is_complete": 0, - "is_mandatory": 0, - "is_single": 0, - "is_skipped": 0, - "modified": "2020-07-27 19:09:35.451945", - "modified_by": "Administrator", - "name": "Create a Program", - "owner": "Administrator", - "reference_document": "Program", - "show_full_form": 1, - "title": "Create a Program", - "validate_action": 1 -} \ No newline at end of file diff --git a/erpnext/education/onboarding_step/create_a_student/create_a_student.json b/erpnext/education/onboarding_step/create_a_student/create_a_student.json deleted file mode 100644 index 07c3f7331e..0000000000 --- a/erpnext/education/onboarding_step/create_a_student/create_a_student.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "action": "Create Entry", - "creation": "2020-07-27 19:17:20.326837", - "docstatus": 0, - "doctype": "Onboarding Step", - "idx": 0, - "is_complete": 0, - "is_mandatory": 1, - "is_single": 0, - "is_skipped": 0, - "modified": "2020-07-27 19:49:47.724289", - "modified_by": "Administrator", - "name": "Create a Student", - "owner": "Administrator", - "reference_document": "Student", - "show_full_form": 1, - "title": "Create a Student", - "validate_action": 1 -} \ No newline at end of file diff --git a/erpnext/education/onboarding_step/create_a_topic/create_a_topic.json b/erpnext/education/onboarding_step/create_a_topic/create_a_topic.json deleted file mode 100644 index 96a536488e..0000000000 --- a/erpnext/education/onboarding_step/create_a_topic/create_a_topic.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "action": "Create Entry", - "creation": "2020-07-27 19:08:40.754534", - "docstatus": 0, - "doctype": "Onboarding Step", - "idx": 0, - "is_complete": 0, - "is_mandatory": 0, - "is_single": 0, - "is_skipped": 0, - "modified": "2020-07-27 19:09:13.231995", - "modified_by": "Administrator", - "name": "Create a Topic", - "owner": "Administrator", - "reference_document": "Topic", - "show_full_form": 1, - "title": "Create a Topic", - "validate_action": 1 -} \ No newline at end of file diff --git a/erpnext/education/onboarding_step/create_an_instructor/create_an_instructor.json b/erpnext/education/onboarding_step/create_an_instructor/create_an_instructor.json deleted file mode 100644 index 419d6e07f1..0000000000 --- a/erpnext/education/onboarding_step/create_an_instructor/create_an_instructor.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "action": "Create Entry", - "creation": "2020-07-27 19:17:39.158037", - "docstatus": 0, - "doctype": "Onboarding Step", - "idx": 0, - "is_complete": 0, - "is_mandatory": 1, - "is_single": 0, - "is_skipped": 0, - "modified": "2020-07-27 19:49:47.723494", - "modified_by": "Administrator", - "name": "Create an Instructor", - "owner": "Administrator", - "reference_document": "Instructor", - "show_full_form": 1, - "title": "Create an Instructor", - "validate_action": 1 -} \ No newline at end of file diff --git a/erpnext/education/onboarding_step/enroll_a_student_in_a_program/enroll_a_student_in_a_program.json b/erpnext/education/onboarding_step/enroll_a_student_in_a_program/enroll_a_student_in_a_program.json deleted file mode 100644 index 61e48cd520..0000000000 --- a/erpnext/education/onboarding_step/enroll_a_student_in_a_program/enroll_a_student_in_a_program.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "action": "Create Entry", - "creation": "2020-07-27 19:10:28.530226", - "docstatus": 0, - "doctype": "Onboarding Step", - "idx": 0, - "is_complete": 0, - "is_mandatory": 0, - "is_single": 0, - "is_skipped": 0, - "modified": "2020-07-27 19:10:28.530226", - "modified_by": "Administrator", - "name": "Enroll a Student in a Program", - "owner": "Administrator", - "reference_document": "Program Enrollment", - "show_full_form": 0, - "title": "Enroll a Student in a Program", - "validate_action": 1 -} \ No newline at end of file diff --git a/erpnext/education/onboarding_step/introduction_to_program_and_courses/introduction_to_program_and_courses.json b/erpnext/education/onboarding_step/introduction_to_program_and_courses/introduction_to_program_and_courses.json deleted file mode 100644 index a9ddfc00da..0000000000 --- a/erpnext/education/onboarding_step/introduction_to_program_and_courses/introduction_to_program_and_courses.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "action": "Watch Video", - "creation": "2020-07-27 19:05:12.663987", - "docstatus": 0, - "doctype": "Onboarding Step", - "idx": 0, - "is_complete": 0, - "is_mandatory": 0, - "is_single": 0, - "is_skipped": 0, - "modified": "2020-07-27 20:18:11.831789", - "modified_by": "Administrator", - "name": "Introduction to Program and Courses", - "owner": "Administrator", - "show_full_form": 0, - "title": "Introduction to Program and Courses", - "validate_action": 1, - "video_url": "https://www.youtube.com/watch?v=1ueE4seFTp8" -} \ No newline at end of file diff --git a/erpnext/education/onboarding_step/introduction_to_student_attendance/introduction_to_student_attendance.json b/erpnext/education/onboarding_step/introduction_to_student_attendance/introduction_to_student_attendance.json deleted file mode 100644 index 3de99728ea..0000000000 --- a/erpnext/education/onboarding_step/introduction_to_student_attendance/introduction_to_student_attendance.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "action": "Watch Video", - "creation": "2020-07-27 19:14:57.176131", - "docstatus": 0, - "doctype": "Onboarding Step", - "idx": 0, - "is_complete": 0, - "is_mandatory": 0, - "is_single": 0, - "is_skipped": 0, - "modified": "2020-07-27 19:55:55.411032", - "modified_by": "Administrator", - "name": "Introduction to Student Attendance", - "owner": "Administrator", - "show_full_form": 0, - "title": "Introduction to Student Attendance", - "validate_action": 1, - "video_url": "https://youtu.be/j9pgkPuyiaI" -} \ No newline at end of file diff --git a/erpnext/education/onboarding_step/introduction_to_student_group/introduction_to_student_group.json b/erpnext/education/onboarding_step/introduction_to_student_group/introduction_to_student_group.json deleted file mode 100644 index 74bdcd17be..0000000000 --- a/erpnext/education/onboarding_step/introduction_to_student_group/introduction_to_student_group.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "action": "Watch Video", - "creation": "2020-07-27 19:12:05.046465", - "docstatus": 0, - "doctype": "Onboarding Step", - "idx": 0, - "is_complete": 0, - "is_mandatory": 0, - "is_single": 0, - "is_skipped": 0, - "modified": "2020-07-27 19:42:47.286441", - "modified_by": "Administrator", - "name": "Introduction to Student Group", - "owner": "Administrator", - "reference_document": "Student Group", - "show_full_form": 0, - "title": "Introduction to Student Group", - "validate_action": 1, - "video_url": "https://youtu.be/5K_smeeE1Q4" -} \ No newline at end of file diff --git a/erpnext/education/report/__init__.py b/erpnext/education/report/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/report/absent_student_report/__init__.py b/erpnext/education/report/absent_student_report/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/report/absent_student_report/absent_student_report.js b/erpnext/education/report/absent_student_report/absent_student_report.js deleted file mode 100644 index bf2d10d59e..0000000000 --- a/erpnext/education/report/absent_student_report/absent_student_report.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -// License: GNU General Public License v3. See license.txt - - -frappe.query_reports["Absent Student Report"] = { - "filters": [ - { - "fieldname":"date", - "label": __("Date"), - "fieldtype": "Date", - "default": frappe.datetime.get_today(), - "reqd": 1 - } - ] -} diff --git a/erpnext/education/report/absent_student_report/absent_student_report.json b/erpnext/education/report/absent_student_report/absent_student_report.json deleted file mode 100644 index 92ad860cc6..0000000000 --- a/erpnext/education/report/absent_student_report/absent_student_report.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "add_total_row": 0, - "creation": "2013-05-13 14:04:03", - "disable_prepared_report": 0, - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 3, - "is_standard": "Yes", - "modified": "2020-06-24 17:16:40.251116", - "modified_by": "Administrator", - "module": "Education", - "name": "Absent Student Report", - "owner": "Administrator", - "prepared_report": 0, - "ref_doctype": "Student Attendance", - "report_name": "Absent Student Report", - "report_type": "Script Report", - "roles": [ - { - "role": "Academics User" - } - ] -} \ No newline at end of file diff --git a/erpnext/education/report/absent_student_report/absent_student_report.py b/erpnext/education/report/absent_student_report/absent_student_report.py deleted file mode 100644 index ac27f715ec..0000000000 --- a/erpnext/education/report/absent_student_report/absent_student_report.py +++ /dev/null @@ -1,132 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - - -import frappe -from frappe import _, msgprint -from frappe.utils import formatdate - -from erpnext.education.doctype.student_attendance.student_attendance import get_holiday_list -from erpnext.hr.doctype.holiday_list.holiday_list import is_holiday - - -def execute(filters=None): - if not filters: - filters = {} - - if not filters.get("date"): - msgprint(_("Please select date"), raise_exception=1) - - columns = get_columns(filters) - date = filters.get("date") - - holiday_list = get_holiday_list() - if is_holiday(holiday_list, filters.get("date")): - msgprint( - _("No attendance has been marked for {0} as it is a Holiday").format( - frappe.bold(formatdate(filters.get("date"))) - ) - ) - - absent_students = get_absent_students(date) - leave_applicants = get_leave_applications(date) - if absent_students: - student_list = [d["student"] for d in absent_students] - transportation_details = get_transportation_details(date, student_list) - - data = [] - for student in absent_students: - if not student.student in leave_applicants: - row = [student.student, student.student_name, student.student_group] - stud_details = frappe.db.get_value( - "Student", student.student, ["student_email_id", "student_mobile_number"], as_dict=True - ) - - if stud_details.student_email_id: - row += [stud_details.student_email_id] - else: - row += [""] - - if stud_details.student_mobile_number: - row += [stud_details.student_mobile_number] - else: - row += [""] - if transportation_details.get(student.student): - row += transportation_details.get(student.student) - - data.append(row) - - return columns, data - - -def get_columns(filters): - columns = [ - _("Student") + ":Link/Student:90", - _("Student Name") + "::150", - _("Student Group") + "::180", - _("Student Email Address") + "::180", - _("Student Mobile No.") + "::150", - _("Mode of Transportation") + "::150", - _("Vehicle/Bus Number") + "::150", - ] - return columns - - -def get_absent_students(date): - absent_students = frappe.db.sql( - """ - SELECT student, student_name, student_group - FROM `tabStudent Attendance` - WHERE - status='Absent' and docstatus=1 and date = %s - ORDER BY - student_group, student_name""", - date, - as_dict=1, - ) - return absent_students - - -def get_leave_applications(date): - leave_applicants = [] - leave_applications = frappe.db.sql( - """ - SELECT student - FROM - `tabStudent Leave Application` - WHERE - docstatus = 1 and mark_as_present = 1 and - from_date <= %s and to_date >= %s - """, - (date, date), - ) - for student in leave_applications: - leave_applicants.append(student[0]) - - return leave_applicants - - -def get_transportation_details(date, student_list): - academic_year = frappe.get_all( - "Academic Year", filters=[["year_start_date", "<=", date], ["year_end_date", ">=", date]] - ) - if academic_year: - academic_year = academic_year[0].name - elif frappe.defaults.get_defaults().academic_year: - academic_year = frappe.defaults.get_defaults().academic_year - else: - return {} - - transportation_details = frappe.get_all( - "Program Enrollment", - fields=["student", "mode_of_transportation", "vehicle_no"], - filters={ - "student": ("in", student_list), - "academic_year": academic_year, - "docstatus": ("not in", ["2"]), - }, - ) - transportation_map = {} - for d in transportation_details: - transportation_map[d.student] = [d.mode_of_transportation, d.vehicle_no] - return transportation_map diff --git a/erpnext/education/report/assessment_plan_status/__init__.py b/erpnext/education/report/assessment_plan_status/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/report/assessment_plan_status/assessment_plan_status.js b/erpnext/education/report/assessment_plan_status/assessment_plan_status.js deleted file mode 100644 index 2d1eb09640..0000000000 --- a/erpnext/education/report/assessment_plan_status/assessment_plan_status.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt -/* eslint-disable */ - -frappe.query_reports["Assessment Plan Status"] = { - "filters": [ - { - "fieldname":"assessment_group", - "label": __("Assessment Group"), - "fieldtype": "Link", - "options": "Assessment Group", - "get_query": function() { - return{ - filters: { - 'is_group': 0 - } - }; - } - }, - { - "fieldname":"schedule_date", - "label": __("Scheduled Upto"), - "fieldtype": "Date", - "options": "" - } - - ] -} diff --git a/erpnext/education/report/assessment_plan_status/assessment_plan_status.json b/erpnext/education/report/assessment_plan_status/assessment_plan_status.json deleted file mode 100644 index cbca648d57..0000000000 --- a/erpnext/education/report/assessment_plan_status/assessment_plan_status.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "add_total_row": 0, - "creation": "2017-11-09 15:07:30.404428", - "disable_prepared_report": 0, - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 0, - "is_standard": "Yes", - "modified": "2020-06-24 17:16:02.027410", - "modified_by": "Administrator", - "module": "Education", - "name": "Assessment Plan Status", - "owner": "Administrator", - "prepared_report": 0, - "ref_doctype": "Assessment Plan", - "report_name": "Assessment Plan Status", - "report_type": "Script Report", - "roles": [ - { - "role": "Academics User" - } - ] -} \ No newline at end of file diff --git a/erpnext/education/report/assessment_plan_status/assessment_plan_status.py b/erpnext/education/report/assessment_plan_status/assessment_plan_status.py deleted file mode 100644 index 7cf5b30548..0000000000 --- a/erpnext/education/report/assessment_plan_status/assessment_plan_status.py +++ /dev/null @@ -1,187 +0,0 @@ -# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from itertools import groupby - -import frappe -from frappe import _ -from frappe.utils import cint - -DOCSTATUS = { - 0: "saved", - 1: "submitted", -} - - -def execute(filters=None): - columns, data = [], [] - - args = frappe._dict() - args["assessment_group"] = filters.get("assessment_group") - args["schedule_date"] = filters.get("schedule_date") - - columns = get_column() - - data, chart = get_assessment_data(args) - - return columns, data, None, chart - - -def get_assessment_data(args=None): - - # [total, saved, submitted, remaining] - chart_data = [0, 0, 0, 0] - - condition = "" - if args["assessment_group"]: - condition += "and assessment_group = %(assessment_group)s" - if args["schedule_date"]: - condition += "and schedule_date <= %(schedule_date)s" - - assessment_plan = frappe.db.sql( - """ - SELECT - ap.name as assessment_plan, - ap.assessment_name, - ap.student_group, - ap.schedule_date, - (select count(*) from `tabStudent Group Student` sgs where sgs.parent=ap.student_group) - as student_group_strength - FROM - `tabAssessment Plan` ap - WHERE - ap.docstatus = 1 {condition} - ORDER BY - ap.modified desc - """.format( - condition=condition - ), - (args), - as_dict=1, - ) - - assessment_plan_list = [d.assessment_plan for d in assessment_plan] if assessment_plan else [""] - assessment_result = get_assessment_result(assessment_plan_list) - - for d in assessment_plan: - - assessment_plan_details = assessment_result.get(d.assessment_plan) - assessment_plan_details = ( - frappe._dict() if not assessment_plan_details else frappe._dict(assessment_plan_details) - ) - if "saved" not in assessment_plan_details: - assessment_plan_details.update({"saved": 0}) - if "submitted" not in assessment_plan_details: - assessment_plan_details.update({"submitted": 0}) - - # remaining students whose marks not entered - remaining_students = ( - cint(d.student_group_strength) - - cint(assessment_plan_details.saved) - - cint(assessment_plan_details.submitted) - ) - assessment_plan_details.update({"remaining": remaining_students}) - d.update(assessment_plan_details) - - chart_data[0] += cint(d.student_group_strength) - chart_data[1] += assessment_plan_details.saved - chart_data[2] += assessment_plan_details.submitted - chart_data[3] += assessment_plan_details.remaining - - chart = get_chart(chart_data[1:]) - - return assessment_plan, chart - - -def get_assessment_result(assessment_plan_list): - assessment_result_dict = frappe._dict() - - assessment_result = frappe.db.sql( - """ - SELECT - assessment_plan, docstatus, count(*) as count - FROM - `tabAssessment Result` - WHERE - assessment_plan in (%s) - GROUP BY - assessment_plan, docstatus - ORDER BY - assessment_plan - """ - % ", ".join(["%s"] * len(assessment_plan_list)), - tuple(assessment_plan_list), - as_dict=1, - ) - - for key, group in groupby(assessment_result, lambda ap: ap["assessment_plan"]): - tmp = {} - for d in group: - if d.docstatus in [0, 1]: - tmp.update({DOCSTATUS[d.docstatus]: d.count}) - assessment_result_dict[key] = tmp - - return assessment_result_dict - - -def get_chart(chart_data): - return { - "data": {"labels": ["Saved", "Submitted", "Remaining"], "datasets": [{"values": chart_data}]}, - "type": "percentage", - } - - -def get_column(): - return [ - { - "fieldname": "assessment_plan", - "label": _("Assessment Plan"), - "fieldtype": "Link", - "options": "Assessment Plan", - "width": 120, - }, - { - "fieldname": "assessment_name", - "label": _("Assessment Plan Name"), - "fieldtype": "Data", - "options": "", - "width": 200, - }, - { - "fieldname": "schedule_date", - "label": _("Schedule Date"), - "fieldtype": "Date", - "options": "", - "width": 100, - }, - { - "fieldname": "student_group", - "label": _("Student Group"), - "fieldtype": "Link", - "options": "Student Group", - "width": 200, - }, - { - "fieldname": "student_group_strength", - "label": _("Total Student"), - "fieldtype": "Data", - "options": "", - "width": 100, - }, - { - "fieldname": "submitted", - "label": _("Submitted"), - "fieldtype": "Data", - "options": "", - "width": 100, - }, - {"fieldname": "saved", "label": _("Saved"), "fieldtype": "Data", "options": "", "width": 100}, - { - "fieldname": "remaining", - "label": _("Remaining"), - "fieldtype": "Data", - "options": "", - "width": 100, - }, - ] diff --git a/erpnext/education/report/course_wise_assessment_report/__init__.py b/erpnext/education/report/course_wise_assessment_report/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.html b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.html deleted file mode 100644 index 33e725f08b..0000000000 --- a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.html +++ /dev/null @@ -1,50 +0,0 @@ -{% - var letterhead = filters.letter_head || (frappe.get_doc(":Company", filters.company) && frappe.get_doc(":Company", filters.company).default_letter_head) || frappe.defaults.get_default("letter_head"); - var report_columns = report.get_columns_for_print(); -%} -{% if(letterhead) { %} -
- {%= frappe.boot.letter_heads[letterhead].header %} -
-{% } %} -

{%= __("Assessment Report") %}

-
-
{%= __("Academic Year: ") %} {%= filters.academic_year %}
-{% if (filters.academic_term){ %} -
{%= __("Academic Term: ") %} {%= filters.academic_term %}
-{% } %} -
{%= __("Course Code: ") %} {%= filters.course %}
-
{%= __("Assessment Group: ") %} {%= filters.assessment_group %}
-{% if (filters.student_group){ %} -
{%= __("Student Group: ") %} {%= filters.student_group %}
-{% } %} -
- - - - - {% for(var i=1, l=report_columns.length; i{%= report_columns[i].label %} - {% } %} - - - - {% for(var j=0, k=data.length; j - {% for(var i=1, l=report_columns.length; i - {% var fieldname = report_columns[i].fieldname; %} - {% if (!is_null(row[fieldname])) { %} - {%= row[fieldname] %} - {% } %} - - {% } %} - - {% } %} - -
- -

Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}

diff --git a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.js b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.js deleted file mode 100644 index 8c42d48641..0000000000 --- a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.js +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.query_reports["Course wise Assessment Report"] = { - "filters": [ - { - "fieldname":"academic_year", - "label": __("Academic Year"), - "fieldtype": "Link", - "options": "Academic Year", - "reqd": 1 - }, - { - "fieldname":"academic_term", - "label": __("Academic Term"), - "fieldtype": "Link", - "options": "Academic Term" - }, - { - "fieldname":"course", - "label": __("Course"), - "fieldtype": "Link", - "options": "Course", - "reqd": 1 - }, - { - "fieldname":"student_group", - "label": __("Student Group"), - "fieldtype": "Link", - "options": "Student Group" - }, - { - "fieldname":"assessment_group", - "label": __("Assessment Group"), - "fieldtype": "Link", - "options": "Assessment Group", - "reqd": 1 - } - ] -}; diff --git a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.json b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.json deleted file mode 100644 index 416db9d00f..0000000000 --- a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "add_total_row": 0, - "creation": "2017-05-05 14:46:13.776133", - "disable_prepared_report": 0, - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 0, - "is_standard": "Yes", - "modified": "2020-06-24 17:15:15.477530", - "modified_by": "Administrator", - "module": "Education", - "name": "Course wise Assessment Report", - "owner": "Administrator", - "prepared_report": 0, - "query": "", - "ref_doctype": "Assessment Result", - "report_name": "Course wise Assessment Report", - "report_type": "Script Report", - "roles": [ - { - "role": "Instructor" - }, - { - "role": "Education Manager" - } - ] -} \ No newline at end of file diff --git a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py deleted file mode 100644 index 0930882e40..0000000000 --- a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py +++ /dev/null @@ -1,303 +0,0 @@ -# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from collections import OrderedDict, defaultdict - -import frappe -from frappe import _ - -from erpnext.education.api import get_grade - - -def execute(filters=None): - data, chart, grades = [], [], [] - args = frappe._dict() - grade_wise_analysis = defaultdict(dict) - - args["academic_year"] = filters.get("academic_year") - args["course"] = filters.get("course") - args["assessment_group"] = filters.get("assessment_group") - - args["academic_term"] = filters.get("academic_term") - args["student_group"] = filters.get("student_group") - - if args["assessment_group"] == "All Assessment Groups": - frappe.throw(_("Please select the assessment group other than 'All Assessment Groups'")) - - returned_values = get_formatted_result(args, get_assessment_criteria=True) - student_dict = returned_values["student_details"] - result_dict = returned_values["assessment_result"] - assessment_criteria_dict = returned_values["assessment_criteria"] - - for student in result_dict: - student_row = {} - student_row["student"] = student - student_row["student_name"] = student_dict[student] - for criteria in assessment_criteria_dict: - scrub_criteria = frappe.scrub(criteria) - if criteria in result_dict[student][args.course][args.assessment_group]: - student_row[scrub_criteria] = result_dict[student][args.course][args.assessment_group][ - criteria - ]["grade"] - student_row[scrub_criteria + "_score"] = result_dict[student][args.course][ - args.assessment_group - ][criteria]["score"] - - # create the list of possible grades - if student_row[scrub_criteria] not in grades: - grades.append(student_row[scrub_criteria]) - - # create the dict of for gradewise analysis - if student_row[scrub_criteria] not in grade_wise_analysis[criteria]: - grade_wise_analysis[criteria][student_row[scrub_criteria]] = 1 - else: - grade_wise_analysis[criteria][student_row[scrub_criteria]] += 1 - else: - student_row[frappe.scrub(criteria)] = "" - student_row[frappe.scrub(criteria) + "_score"] = "" - data.append(student_row) - - assessment_criteria_list = [d for d in assessment_criteria_dict] - columns = get_column(assessment_criteria_dict) - chart = get_chart_data(grades, assessment_criteria_list, grade_wise_analysis) - - return columns, data, None, chart - - -def get_formatted_result( - args, get_assessment_criteria=False, get_course=False, get_all_assessment_groups=False -): - cond, cond1, cond2, cond3, cond4 = " ", " ", " ", " ", " " - args_list = [args.academic_year] - - if args.course: - cond = " and ar.course=%s" - args_list.append(args.course) - - if args.academic_term: - cond1 = " and ar.academic_term=%s" - args_list.append(args.academic_term) - - if args.student_group: - cond2 = " and ar.student_group=%s" - args_list.append(args.student_group) - - create_total_dict = False - - assessment_groups = get_child_assessment_groups(args.assessment_group) - cond3 = " and ar.assessment_group in (%s)" % (", ".join(["%s"] * len(assessment_groups))) - args_list += assessment_groups - - if args.students: - cond4 = " and ar.student in (%s)" % (", ".join(["%s"] * len(args.students))) - args_list += args.students - - assessment_result = frappe.db.sql( - """ - SELECT - ar.student, ar.student_name, ar.academic_year, ar.academic_term, ar.program, ar.course, - ar.assessment_plan, ar.grading_scale, ar.assessment_group, ar.student_group, - ard.assessment_criteria, ard.maximum_score, ard.grade, ard.score - FROM - `tabAssessment Result` ar, `tabAssessment Result Detail` ard - WHERE - ar.name=ard.parent and ar.docstatus=1 and ar.academic_year=%s {0} {1} {2} {3} {4} - ORDER BY - ard.assessment_criteria""".format( - cond, cond1, cond2, cond3, cond4 - ), - tuple(args_list), - as_dict=1, - ) - - # create the nested dictionary structure as given below: - # ..... - # "Final Grade" -> assessment criteria used for totaling and args.assessment_group -> for totaling all the assesments - - student_details = {} - formatted_assessment_result = defaultdict(dict) - assessment_criteria_dict = OrderedDict() - course_dict = OrderedDict() - total_maximum_score = None - if not (len(assessment_groups) == 1 and assessment_groups[0] == args.assessment_group): - create_total_dict = True - - # add the score for a given score and recalculate the grades - def add_score_and_recalculate_grade(result, assessment_group, assessment_criteria): - formatted_assessment_result[result.student][result.course][assessment_group][ - assessment_criteria - ]["maximum_score"] += result.maximum_score - formatted_assessment_result[result.student][result.course][assessment_group][ - assessment_criteria - ]["score"] += result.score - tmp_grade = get_grade( - result.grading_scale, - ( - ( - formatted_assessment_result[result.student][result.course][assessment_group][ - assessment_criteria - ]["score"] - ) - / ( - formatted_assessment_result[result.student][result.course][assessment_group][ - assessment_criteria - ]["maximum_score"] - ) - ) - * 100, - ) - formatted_assessment_result[result.student][result.course][assessment_group][ - assessment_criteria - ]["grade"] = tmp_grade - - # create the assessment criteria "Final Grade" with the sum of all the scores of the assessment criteria in a given assessment group - def add_total_score(result, assessment_group): - if ( - "Final Grade" - not in formatted_assessment_result[result.student][result.course][assessment_group] - ): - formatted_assessment_result[result.student][result.course][assessment_group][ - "Final Grade" - ] = frappe._dict( - { - "assessment_criteria": "Final Grade", - "maximum_score": result.maximum_score, - "score": result.score, - "grade": result.grade, - } - ) - else: - add_score_and_recalculate_grade(result, assessment_group, "Final Grade") - - for result in assessment_result: - if result.student not in student_details: - student_details[result.student] = result.student_name - - assessment_criteria_details = frappe._dict( - { - "assessment_criteria": result.assessment_criteria, - "maximum_score": result.maximum_score, - "score": result.score, - "grade": result.grade, - } - ) - - if not formatted_assessment_result[result.student]: - formatted_assessment_result[result.student] = defaultdict(dict) - if not formatted_assessment_result[result.student][result.course]: - formatted_assessment_result[result.student][result.course] = defaultdict(dict) - - if not create_total_dict: - formatted_assessment_result[result.student][result.course][result.assessment_group][ - result.assessment_criteria - ] = assessment_criteria_details - add_total_score(result, result.assessment_group) - - # create the total of all the assessment groups criteria-wise - elif create_total_dict: - if get_all_assessment_groups: - formatted_assessment_result[result.student][result.course][result.assessment_group][ - result.assessment_criteria - ] = assessment_criteria_details - if not formatted_assessment_result[result.student][result.course][args.assessment_group]: - formatted_assessment_result[result.student][result.course][ - args.assessment_group - ] = defaultdict(dict) - formatted_assessment_result[result.student][result.course][args.assessment_group][ - result.assessment_criteria - ] = assessment_criteria_details - elif ( - result.assessment_criteria - not in formatted_assessment_result[result.student][result.course][args.assessment_group] - ): - formatted_assessment_result[result.student][result.course][args.assessment_group][ - result.assessment_criteria - ] = assessment_criteria_details - elif ( - result.assessment_criteria - in formatted_assessment_result[result.student][result.course][args.assessment_group] - ): - add_score_and_recalculate_grade(result, args.assessment_group, result.assessment_criteria) - - add_total_score(result, args.assessment_group) - - total_maximum_score = formatted_assessment_result[result.student][result.course][ - args.assessment_group - ]["Final Grade"]["maximum_score"] - if get_assessment_criteria: - assessment_criteria_dict[result.assessment_criteria] = formatted_assessment_result[ - result.student - ][result.course][args.assessment_group][result.assessment_criteria]["maximum_score"] - if get_course: - course_dict[result.course] = total_maximum_score - - if get_assessment_criteria and total_maximum_score: - assessment_criteria_dict["Final Grade"] = total_maximum_score - - return { - "student_details": student_details, - "assessment_result": formatted_assessment_result, - "assessment_criteria": assessment_criteria_dict, - "course_dict": course_dict, - } - - -def get_column(assessment_criteria): - columns = [ - { - "fieldname": "student", - "label": _("Student ID"), - "fieldtype": "Link", - "options": "Student", - "width": 90, - }, - {"fieldname": "student_name", "label": _("Student Name"), "fieldtype": "Data", "width": 160}, - ] - for d in assessment_criteria: - columns.append({"fieldname": frappe.scrub(d), "label": d, "fieldtype": "Data", "width": 110}) - columns.append( - { - "fieldname": frappe.scrub(d) + "_score", - "label": "Score(" + str(int(assessment_criteria[d])) + ")", - "fieldtype": "Float", - "width": 100, - } - ) - - return columns - - -def get_chart_data(grades, criteria_list, kounter): - grades = sorted(grades) - datasets = [] - - for grade in grades: - tmp = frappe._dict({"name": grade, "values": []}) - for criteria in criteria_list: - if grade in kounter[criteria]: - tmp["values"].append(kounter[criteria][grade]) - else: - tmp["values"].append(0) - datasets.append(tmp) - - return { - "data": {"labels": criteria_list, "datasets": datasets}, - "type": "bar", - } - - -def get_child_assessment_groups(assessment_group): - assessment_groups = [] - group_type = frappe.get_value("Assessment Group", assessment_group, "is_group") - if group_type: - from frappe.desk.treeview import get_children - - assessment_groups = [ - d.get("value") - for d in get_children("Assessment Group", assessment_group) - if d.get("value") and not d.get("expandable") - ] - else: - assessment_groups = [assessment_group] - return assessment_groups diff --git a/erpnext/education/report/final_assessment_grades/__init__.py b/erpnext/education/report/final_assessment_grades/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/report/final_assessment_grades/final_assessment_grades.js b/erpnext/education/report/final_assessment_grades/final_assessment_grades.js deleted file mode 100644 index ddff8a884e..0000000000 --- a/erpnext/education/report/final_assessment_grades/final_assessment_grades.js +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt -/* eslint-disable */ - -frappe.query_reports["Final Assessment Grades"] = { - "filters": [ - { - "fieldname":"academic_year", - "label": __("Academic Year"), - "fieldtype": "Link", - "options": "Academic Year", - "reqd": 1 - }, - { - "fieldname":"student_group", - "label": __("Student Group"), - "fieldtype": "Link", - "options": "Student Group", - "reqd": 1, - "get_query": function() { - return{ - filters: { - "group_based_on": "Batch", - "academic_year": frappe.query_report.get_filter_value('academic_year') - } - }; - } - }, - { - "fieldname":"assessment_group", - "label": __("Assessment Group"), - "fieldtype": "Link", - "options": "Assessment Group", - "reqd": 1 - } - - ] -} diff --git a/erpnext/education/report/final_assessment_grades/final_assessment_grades.json b/erpnext/education/report/final_assessment_grades/final_assessment_grades.json deleted file mode 100644 index 6a23494768..0000000000 --- a/erpnext/education/report/final_assessment_grades/final_assessment_grades.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "add_total_row": 0, - "creation": "2018-01-22 17:04:43.412054", - "disable_prepared_report": 0, - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 0, - "is_standard": "Yes", - "modified": "2020-06-24 17:13:35.373756", - "modified_by": "Administrator", - "module": "Education", - "name": "Final Assessment Grades", - "owner": "Administrator", - "prepared_report": 0, - "ref_doctype": "Assessment Result", - "report_name": "Final Assessment Grades", - "report_type": "Script Report", - "roles": [ - { - "role": "Instructor" - }, - { - "role": "Education Manager" - } - ] -} \ No newline at end of file diff --git a/erpnext/education/report/final_assessment_grades/final_assessment_grades.py b/erpnext/education/report/final_assessment_grades/final_assessment_grades.py deleted file mode 100644 index 8d5acc61f2..0000000000 --- a/erpnext/education/report/final_assessment_grades/final_assessment_grades.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from collections import defaultdict - -import frappe -from frappe import _ - -from erpnext.education.report.course_wise_assessment_report.course_wise_assessment_report import ( - get_chart_data, - get_formatted_result, -) - - -def execute(filters=None): - columns, data, grades = [], [], [] - args = frappe._dict() - course_wise_analysis = defaultdict(dict) - - args["academic_year"] = filters.get("academic_year") - assessment_group = args["assessment_group"] = filters.get("assessment_group") - - student_group = filters.get("student_group") - args.students = frappe.db.sql_list( - "select student from `tabStudent Group Student` where parent=%s", (student_group) - ) - - values = get_formatted_result(args, get_course=True) - student_details = values.get("student_details") - assessment_result = values.get("assessment_result") - course_dict = values.get("course_dict") - - for student in args.students: - if student_details.get(student): - student_row = {} - student_row["student"] = student - student_row["student_name"] = student_details[student] - for course in course_dict: - scrub_course = frappe.scrub(course) - if assessment_group in assessment_result[student][course]: - student_row["grade_" + scrub_course] = assessment_result[student][course][assessment_group][ - "Total Score" - ]["grade"] - student_row["score_" + scrub_course] = assessment_result[student][course][assessment_group][ - "Total Score" - ]["score"] - - # create the list of possible grades - if student_row["grade_" + scrub_course] not in grades: - grades.append(student_row["grade_" + scrub_course]) - - # create the dict of for gradewise analysis - if student_row["grade_" + scrub_course] not in course_wise_analysis[course]: - course_wise_analysis[course][student_row["grade_" + scrub_course]] = 1 - else: - course_wise_analysis[course][student_row["grade_" + scrub_course]] += 1 - - data.append(student_row) - - course_list = [d for d in course_dict] - columns = get_column(course_dict) - chart = get_chart_data(grades, course_list, course_wise_analysis) - return columns, data, None, chart - - -def get_column(course_dict): - columns = [ - { - "fieldname": "student", - "label": _("Student ID"), - "fieldtype": "Link", - "options": "Student", - "width": 90, - }, - {"fieldname": "student_name", "label": _("Student Name"), "fieldtype": "Data", "width": 160}, - ] - for course in course_dict: - columns.append( - { - "fieldname": "grade_" + frappe.scrub(course), - "label": course, - "fieldtype": "Data", - "width": 110, - } - ) - columns.append( - { - "fieldname": "score_" + frappe.scrub(course), - "label": "Score(" + str(course_dict[course]) + ")", - "fieldtype": "Float", - "width": 100, - } - ) - - return columns diff --git a/erpnext/education/report/program_wise_fee_collection/__init__.py b/erpnext/education/report/program_wise_fee_collection/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.js b/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.js deleted file mode 100644 index 72e8f12e9d..0000000000 --- a/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt -/* eslint-disable */ - -frappe.query_reports["Program wise Fee Collection"] = { - "filters": [ - { - "fieldname": "from_date", - "label": __("From Date"), - "fieldtype": "Date", - "default": frappe.datetime.add_months(frappe.datetime.get_today(), -1), - "reqd": 1 - }, - { - "fieldname": "to_date", - "label": __("To Date"), - "fieldtype": "Date", - "default": frappe.datetime.get_today(), - "reqd": 1 - } - ] -}; diff --git a/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.json b/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.json deleted file mode 100644 index ee5c0dec79..0000000000 --- a/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "add_total_row": 1, - "creation": "2020-07-27 16:05:33.263539", - "disable_prepared_report": 0, - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 0, - "is_standard": "Yes", - "json": "{}", - "modified": "2020-08-05 14:14:12.410515", - "modified_by": "Administrator", - "module": "Education", - "name": "Program wise Fee Collection", - "owner": "Administrator", - "prepared_report": 0, - "query": "SELECT \n FeesCollected.program AS \"Program:Link/Program:200\",\n FeesCollected.paid_amount AS \"Fees Collected:Currency:150\",\n FeesCollected.outstanding_amount AS \"Outstanding Amount:Currency:150\",\n FeesCollected.grand_total \"Grand Total:Currency:150\"\nFROM (\n SELECT \n sum(grand_total) - sum(outstanding_amount) AS paid_amount, program,\n sum(outstanding_amount) AS outstanding_amount,\n sum(grand_total) AS grand_total\n FROM `tabFees`\n WHERE docstatus = 1\n GROUP BY program\n) AS FeesCollected\nORDER BY FeesCollected.paid_amount DESC", - "ref_doctype": "Fees", - "report_name": "Program wise Fee Collection", - "report_type": "Script Report", - "roles": [ - { - "role": "Academics User" - }, - { - "role": "Accounts User" - }, - { - "role": "Accounts Manager" - } - ] -} \ No newline at end of file diff --git a/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.py b/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.py deleted file mode 100644 index e5591f9b6b..0000000000 --- a/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.py +++ /dev/null @@ -1,122 +0,0 @@ -# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ - - -def execute(filters=None): - if not filters: - filters = {} - - columns = get_columns(filters) - data = get_data(filters) - chart = get_chart_data(data) - - return columns, data, None, chart - - -def get_columns(filters=None): - return [ - { - "label": _("Program"), - "fieldname": "program", - "fieldtype": "Link", - "options": "Program", - "width": 300, - }, - { - "label": _("Fees Collected"), - "fieldname": "fees_collected", - "fieldtype": "Currency", - "width": 200, - }, - { - "label": _("Outstanding Amount"), - "fieldname": "outstanding_amount", - "fieldtype": "Currency", - "width": 200, - }, - {"label": _("Grand Total"), "fieldname": "grand_total", "fieldtype": "Currency", "width": 200}, - ] - - -def get_data(filters=None): - data = [] - - conditions = get_filter_conditions(filters) - - fee_details = frappe.db.sql( - """ - SELECT - FeesCollected.program, - FeesCollected.paid_amount, - FeesCollected.outstanding_amount, - FeesCollected.grand_total - FROM ( - SELECT - sum(grand_total) - sum(outstanding_amount) AS paid_amount, program, - sum(outstanding_amount) AS outstanding_amount, - sum(grand_total) AS grand_total - FROM `tabFees` - WHERE - docstatus = 1 and - program IS NOT NULL - %s - GROUP BY program - ) AS FeesCollected - ORDER BY FeesCollected.paid_amount DESC - """ - % (conditions), - as_dict=1, - ) - - for entry in fee_details: - data.append( - { - "program": entry.program, - "fees_collected": entry.paid_amount, - "outstanding_amount": entry.outstanding_amount, - "grand_total": entry.grand_total, - } - ) - - return data - - -def get_filter_conditions(filters): - conditions = "" - - if filters.get("from_date") and filters.get("to_date"): - conditions += " and posting_date BETWEEN '%s' and '%s'" % ( - filters.get("from_date"), - filters.get("to_date"), - ) - - return conditions - - -def get_chart_data(data): - if not data: - return - - labels = [] - fees_collected = [] - outstanding_amount = [] - - for entry in data: - labels.append(entry.get("program")) - fees_collected.append(entry.get("fees_collected")) - outstanding_amount.append(entry.get("outstanding_amount")) - - return { - "data": { - "labels": labels, - "datasets": [ - {"name": _("Fees Collected"), "values": fees_collected}, - {"name": _("Outstanding Amt"), "values": outstanding_amount}, - ], - }, - "type": "bar", - } diff --git a/erpnext/education/report/student_and_guardian_contact_details/__init__.py b/erpnext/education/report/student_and_guardian_contact_details/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.js b/erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.js deleted file mode 100644 index 2734b538b2..0000000000 --- a/erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.query_reports["Student and Guardian Contact Details"] = { - "filters": [ - { - "fieldname":"academic_year", - "label": __("Academic Year"), - "fieldtype": "Link", - "options": "Academic Year", - "reqd": 1, - }, - { - "fieldname":"program", - "label": __("Program"), - "fieldtype": "Link", - "options": "Program", - "reqd": 1 - }, - { - "fieldname":"student_batch_name", - "label": __("Batch Name"), - "fieldtype": "Link", - "options": "Student Batch Name", - "reqd": 1 - }, - - ] -} diff --git a/erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.json b/erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.json deleted file mode 100644 index fa9be65681..0000000000 --- a/erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "add_total_row": 0, - "creation": "2017-03-27 17:47:16.831433", - "disable_prepared_report": 0, - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 0, - "is_standard": "Yes", - "modified": "2020-06-24 17:16:50.639488", - "modified_by": "Administrator", - "module": "Education", - "name": "Student and Guardian Contact Details", - "owner": "Administrator", - "prepared_report": 0, - "ref_doctype": "Program Enrollment", - "report_name": "Student and Guardian Contact Details", - "report_type": "Script Report", - "roles": [ - { - "role": "Instructor" - }, - { - "role": "Academics User" - } - ] -} \ No newline at end of file diff --git a/erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py b/erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py deleted file mode 100644 index 6f871d7ad7..0000000000 --- a/erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py +++ /dev/null @@ -1,151 +0,0 @@ -# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe -from frappe import _ - - -def execute(filters=None): - columns, data = [], [] - - academic_year = filters.get("academic_year") - program = filters.get("program") - student_batch_name = filters.get("student_batch_name") - - columns = get_columns() - - program_enrollments = frappe.get_list( - "Program Enrollment", - fields=["student", "student_name"], - filters={ - "academic_year": academic_year, - "program": program, - "student_batch_name": student_batch_name, - }, - ) - - student_list = [d.student for d in program_enrollments] - if not student_list: - return columns, [] - - group_roll_no_map = get_student_roll_no(academic_year, program, student_batch_name) - student_map = get_student_details(student_list) - guardian_map = get_guardian_map(student_list) - - for d in program_enrollments: - student_details = student_map.get(d.student) - row = [ - group_roll_no_map.get(d.student), - d.student, - d.student_name, - student_details.get("student_mobile_number"), - student_details.get("student_email_id"), - student_details.get("address"), - ] - - student_guardians = guardian_map.get(d.student) - - if student_guardians: - for i in range(2): - if i < len(student_guardians): - g = student_guardians[i] - row += [g.guardian_name, g.relation, g.mobile_number, g.email_address] - - data.append(row) - - return columns, data - - -def get_columns(): - columns = [ - _("Group Roll No") + "::60", - _("Student ID") + ":Link/Student:90", - _("Student Name") + "::150", - _("Student Mobile No.") + "::110", - _("Student Email ID") + "::125", - _("Student Address") + "::175", - _("Guardian1 Name") + "::150", - _("Relation with Guardian1") + "::80", - _("Guardian1 Mobile No") + "::125", - _("Guardian1 Email ID") + "::125", - _("Guardian2 Name") + "::150", - _("Relation with Guardian2") + "::80", - _("Guardian2 Mobile No") + "::125", - _("Guardian2 Email ID") + "::125", - ] - return columns - - -def get_student_details(student_list): - student_map = frappe._dict() - student_details = frappe.db.sql( - """ - select name, student_mobile_number, student_email_id, address_line_1, address_line_2, city, state from `tabStudent` where name in (%s)""" - % ", ".join(["%s"] * len(student_list)), - tuple(student_list), - as_dict=1, - ) - for s in student_details: - student = frappe._dict() - student["student_mobile_number"] = s.student_mobile_number - student["student_email_id"] = s.student_email_id - student["address"] = ", ".join( - [d for d in [s.address_line_1, s.address_line_2, s.city, s.state] if d] - ) - student_map[s.name] = student - return student_map - - -def get_guardian_map(student_list): - guardian_map = frappe._dict() - guardian_details = frappe.db.sql( - """ - select parent, guardian, guardian_name, relation from `tabStudent Guardian` where parent in (%s)""" - % ", ".join(["%s"] * len(student_list)), - tuple(student_list), - as_dict=1, - ) - - guardian_list = list(set([g.guardian for g in guardian_details])) or [""] - - guardian_mobile_no = dict( - frappe.db.sql( - """select name, mobile_number from `tabGuardian` - where name in (%s)""" - % ", ".join(["%s"] * len(guardian_list)), - tuple(guardian_list), - ) - ) - - guardian_email_id = dict( - frappe.db.sql( - """select name, email_address from `tabGuardian` - where name in (%s)""" - % ", ".join(["%s"] * len(guardian_list)), - tuple(guardian_list), - ) - ) - - for guardian in guardian_details: - guardian["mobile_number"] = guardian_mobile_no.get(guardian.guardian) - guardian["email_address"] = guardian_email_id.get(guardian.guardian) - guardian_map.setdefault(guardian.parent, []).append(guardian) - - return guardian_map - - -def get_student_roll_no(academic_year, program, batch): - student_group = frappe.get_all( - "Student Group", - filters={"academic_year": academic_year, "program": program, "batch": batch, "disabled": 0}, - ) - if student_group: - roll_no_dict = dict( - frappe.db.sql( - """select student, group_roll_number from `tabStudent Group Student` where parent=%s""", - (student_group[0].name), - ) - ) - return roll_no_dict - return {} diff --git a/erpnext/education/report/student_batch_wise_attendance/__init__.py b/erpnext/education/report/student_batch_wise_attendance/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/report/student_batch_wise_attendance/student_batch_wise_attendance.js b/erpnext/education/report/student_batch_wise_attendance/student_batch_wise_attendance.js deleted file mode 100644 index 9f1fcbc816..0000000000 --- a/erpnext/education/report/student_batch_wise_attendance/student_batch_wise_attendance.js +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.query_reports["Student Batch-Wise Attendance"] = { - "filters": [{ - "fieldname": "date", - "label": __("Date"), - "fieldtype": "Date", - "default": frappe.datetime.get_today(), - "reqd": 1 - }] -} diff --git a/erpnext/education/report/student_batch_wise_attendance/student_batch_wise_attendance.json b/erpnext/education/report/student_batch_wise_attendance/student_batch_wise_attendance.json deleted file mode 100644 index 8baf8f9fe0..0000000000 --- a/erpnext/education/report/student_batch_wise_attendance/student_batch_wise_attendance.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "add_total_row": 0, - "creation": "2016-11-28 22:07:03.859124", - "disable_prepared_report": 0, - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 2, - "is_standard": "Yes", - "modified": "2020-06-24 17:16:59.823709", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Batch-Wise Attendance", - "owner": "Administrator", - "prepared_report": 0, - "ref_doctype": "Student Attendance", - "report_name": "Student Batch-Wise Attendance", - "report_type": "Script Report", - "roles": [ - { - "role": "Academics User" - } - ] -} \ No newline at end of file diff --git a/erpnext/education/report/student_batch_wise_attendance/student_batch_wise_attendance.py b/erpnext/education/report/student_batch_wise_attendance/student_batch_wise_attendance.py deleted file mode 100644 index 282f5c9aec..0000000000 --- a/erpnext/education/report/student_batch_wise_attendance/student_batch_wise_attendance.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - - -import frappe -from frappe import _, msgprint -from frappe.utils import formatdate - -from erpnext.education.doctype.student_attendance.student_attendance import get_holiday_list -from erpnext.hr.doctype.holiday_list.holiday_list import is_holiday - - -def execute(filters=None): - if not filters: - filters = {} - - if not filters.get("date"): - msgprint(_("Please select date"), raise_exception=1) - - holiday_list = get_holiday_list() - if is_holiday(holiday_list, filters.get("date")): - msgprint( - _("No attendance has been marked for {0} as it is a Holiday").format( - frappe.bold(formatdate(filters.get("date"))) - ) - ) - - columns = get_columns(filters) - - active_student_group = get_active_student_group() - - data = [] - for student_group in active_student_group: - row = [student_group.name] - present_students = 0 - absent_students = 0 - student_group_strength = get_student_group_strength(student_group.name) - student_attendance = get_student_attendance(student_group.name, filters.get("date")) - if student_attendance: - for attendance in student_attendance: - if attendance.status == "Present": - present_students = attendance.count - elif attendance.status == "Absent": - absent_students = attendance.count - - unmarked_students = student_group_strength - (present_students + absent_students) - row += [student_group_strength, present_students, absent_students, unmarked_students] - data.append(row) - - return columns, data - - -def get_columns(filters): - columns = [ - _("Student Group") + ":Link/Student Group:250", - _("Student Group Strength") + "::170", - _("Present") + "::90", - _("Absent") + "::90", - _("Not Marked") + "::90", - ] - return columns - - -def get_active_student_group(): - active_student_groups = frappe.db.sql( - """select name from `tabStudent Group` where group_based_on = "Batch" - and academic_year=%s order by name""", - (frappe.defaults.get_defaults().academic_year), - as_dict=1, - ) - return active_student_groups - - -def get_student_group_strength(student_group): - student_group_strength = frappe.db.sql( - """select count(*) from `tabStudent Group Student` - where parent = %s and active=1""", - student_group, - )[0][0] - return student_group_strength - - -def get_student_attendance(student_group, date): - student_attendance = frappe.db.sql( - """select count(*) as count, status from `tabStudent Attendance` where - student_group= %s and date= %s and docstatus = 1 and - (course_schedule is Null or course_schedule='') group by status""", - (student_group, date), - as_dict=1, - ) - return student_attendance diff --git a/erpnext/education/report/student_fee_collection/__init__.py b/erpnext/education/report/student_fee_collection/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/report/student_fee_collection/student_fee_collection.json b/erpnext/education/report/student_fee_collection/student_fee_collection.json deleted file mode 100644 index c0229a2ee2..0000000000 --- a/erpnext/education/report/student_fee_collection/student_fee_collection.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "add_total_row": 1, - "creation": "2016-06-22 02:58:41.024538", - "disable_prepared_report": 0, - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 3, - "is_standard": "Yes", - "modified": "2020-06-24 17:14:39.452551", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Fee Collection", - "owner": "Administrator", - "prepared_report": 0, - "query": "SELECT\n student as \"Student:Link/Student:200\",\n student_name as \"Student Name::200\",\n sum(grand_total) - sum(outstanding_amount) as \"Paid Amount:Currency:150\",\n sum(outstanding_amount) as \"Outstanding Amount:Currency:150\",\n sum(grand_total) as \"Grand Total:Currency:150\"\nFROM\n `tabFees` \nWHERE\n docstatus=1 \nGROUP BY\n student", - "ref_doctype": "Fees", - "report_name": "Student Fee Collection", - "report_type": "Query Report", - "roles": [ - { - "role": "Academics User" - } - ] -} diff --git a/erpnext/education/report/student_monthly_attendance_sheet/__init__.py b/erpnext/education/report/student_monthly_attendance_sheet/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.js b/erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.js deleted file mode 100644 index 62c94557d7..0000000000 --- a/erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.js +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -// License: GNU General Public License v3. See license.txt - - -frappe.query_reports["Student Monthly Attendance Sheet"] = { - "filters": [{ - "fieldname": "month", - "label": __("Month"), - "fieldtype": "Select", - "options": "Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec", - "default": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", - "Dec" - ][frappe.datetime.str_to_obj(frappe.datetime.get_today()).getMonth()], - }, - { - "fieldname": "year", - "label": __("Year"), - "fieldtype": "Select", - "reqd": 1 - }, - { - "fieldname": "student_group", - "label": __("Student Group"), - "fieldtype": "Link", - "options": "Student Group", - "reqd": 1 - } - ], - - "onload": function() { - return frappe.call({ - method: "erpnext.education.report.student_monthly_attendance_sheet.student_monthly_attendance_sheet.get_attendance_years", - callback: function(r) { - var year_filter = frappe.query_report.get_filter('year'); - year_filter.df.options = r.message; - year_filter.df.default = r.message.split("\n")[0]; - year_filter.refresh(); - year_filter.set_input(year_filter.df.default); - } - }); - } -} diff --git a/erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.json b/erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.json deleted file mode 100644 index 1423d4fee1..0000000000 --- a/erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "add_total_row": 0, - "creation": "2013-05-13 14:04:03", - "disable_prepared_report": 0, - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 3, - "is_standard": "Yes", - "modified": "2020-06-24 17:16:13.307053", - "modified_by": "Administrator", - "module": "Education", - "name": "Student Monthly Attendance Sheet", - "owner": "Administrator", - "prepared_report": 0, - "ref_doctype": "Student Attendance", - "report_name": "Student Monthly Attendance Sheet", - "report_type": "Script Report", - "roles": [ - { - "role": "Academics User" - } - ] -} \ No newline at end of file diff --git a/erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.py b/erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.py deleted file mode 100644 index 9312e2b018..0000000000 --- a/erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.py +++ /dev/null @@ -1,154 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - - -import frappe -from frappe import _ -from frappe.utils import add_days, cstr, date_diff, get_first_day, get_last_day, getdate - -from erpnext.education.api import get_student_group_students -from erpnext.education.doctype.student_attendance.student_attendance import get_holiday_list -from erpnext.support.doctype.issue.issue import get_holidays - - -def execute(filters=None): - if not filters: - filters = {} - - from_date = get_first_day(filters["month"] + "-" + filters["year"]) - to_date = get_last_day(filters["month"] + "-" + filters["year"]) - total_days_in_month = date_diff(to_date, from_date) + 1 - columns = get_columns(total_days_in_month) - students = get_student_group_students(filters.get("student_group"), 1) - students_list = get_students_list(students) - att_map = get_attendance_list(from_date, to_date, filters.get("student_group"), students_list) - data = [] - - for stud in students: - row = [stud.student, stud.student_name] - student_status = frappe.db.get_value("Student", stud.student, "enabled") - date = from_date - total_p = total_a = 0.0 - - for day in range(total_days_in_month): - status = "None" - - if att_map.get(stud.student): - status = att_map.get(stud.student).get(date, "None") - elif not student_status: - status = "Inactive" - else: - status = "None" - - status_map = {"Present": "P", "Absent": "A", "None": "", "Inactive": "-", "Holiday": "H"} - row.append(status_map[status]) - - if status == "Present": - total_p += 1 - elif status == "Absent": - total_a += 1 - date = add_days(date, 1) - - row += [total_p, total_a] - data.append(row) - return columns, data - - -def get_columns(days_in_month): - columns = [_("Student") + ":Link/Student:90", _("Student Name") + "::150"] - for day in range(days_in_month): - columns.append(cstr(day + 1) + "::20") - columns += [_("Total Present") + ":Int:95", _("Total Absent") + ":Int:90"] - return columns - - -def get_students_list(students): - student_list = [] - for stud in students: - student_list.append(stud.student) - return student_list - - -def get_attendance_list(from_date, to_date, student_group, students_list): - attendance_list = frappe.db.sql( - """select student, date, status - from `tabStudent Attendance` where student_group = %s - and docstatus = 1 - and date between %s and %s - order by student, date""", - (student_group, from_date, to_date), - as_dict=1, - ) - - att_map = {} - students_with_leave_application = get_students_with_leave_application( - from_date, to_date, students_list - ) - for d in attendance_list: - att_map.setdefault(d.student, frappe._dict()).setdefault(d.date, "") - - if students_with_leave_application.get( - d.date - ) and d.student in students_with_leave_application.get(d.date): - att_map[d.student][d.date] = "Present" - else: - att_map[d.student][d.date] = d.status - - att_map = mark_holidays(att_map, from_date, to_date, students_list) - - return att_map - - -def get_students_with_leave_application(from_date, to_date, students_list): - if not students_list: - return - leave_applications = frappe.db.sql( - """ - select student, from_date, to_date - from `tabStudent Leave Application` - where - mark_as_present = 1 and docstatus = 1 - and student in %(students)s - and ( - from_date between %(from_date)s and %(to_date)s - or to_date between %(from_date)s and %(to_date)s - or (%(from_date)s between from_date and to_date and %(to_date)s between from_date and to_date) - ) - """, - {"students": students_list, "from_date": from_date, "to_date": to_date}, - as_dict=True, - ) - students_with_leaves = {} - for application in leave_applications: - for date in daterange(application.from_date, application.to_date): - students_with_leaves.setdefault(date, []).append(application.student) - - return students_with_leaves - - -def daterange(d1, d2): - import datetime - - return (d1 + datetime.timedelta(days=i) for i in range((d2 - d1).days + 1)) - - -@frappe.whitelist() -def get_attendance_years(): - year_list = frappe.db.sql_list( - """select distinct YEAR(date) from `tabStudent Attendance` ORDER BY YEAR(date) DESC""" - ) - if not year_list: - year_list = [getdate().year] - return "\n".join(str(year) for year in year_list) - - -def mark_holidays(att_map, from_date, to_date, students_list): - holiday_list = get_holiday_list() - holidays = get_holidays(holiday_list) - - for dt in daterange(getdate(from_date), getdate(to_date)): - if dt in holidays: - for student in students_list: - att_map.setdefault(student, frappe._dict()).setdefault(dt, "Holiday") - - return att_map diff --git a/erpnext/education/setup.py b/erpnext/education/setup.py deleted file mode 100644 index 2b82da556c..0000000000 --- a/erpnext/education/setup.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import frappe - - -def setup_education(): - disable_desk_access_for_student_role() - if frappe.db.exists("Academic Year", "2015-16"): - # already setup - return - create_academic_sessions() - - -def insert_record(records): - for r in records: - doc = frappe.new_doc(r.get("doctype")) - doc.update(r) - try: - doc.insert(ignore_permissions=True) - except frappe.DuplicateEntryError as e: - # pass DuplicateEntryError and continue - if e.args and e.args[0] == doc.doctype and e.args[1] == doc.name: - # make sure DuplicateEntryError is for the exact same doc and not a related doc - pass - else: - raise - - -def create_academic_sessions(): - data = [ - {"doctype": "Academic Year", "academic_year_name": "2015-16"}, - {"doctype": "Academic Year", "academic_year_name": "2016-17"}, - {"doctype": "Academic Year", "academic_year_name": "2017-18"}, - {"doctype": "Academic Year", "academic_year_name": "2018-19"}, - {"doctype": "Academic Term", "academic_year": "2016-17", "term_name": "Semester 1"}, - {"doctype": "Academic Term", "academic_year": "2016-17", "term_name": "Semester 2"}, - {"doctype": "Academic Term", "academic_year": "2017-18", "term_name": "Semester 1"}, - {"doctype": "Academic Term", "academic_year": "2017-18", "term_name": "Semester 2"}, - ] - insert_record(data) - - -def disable_desk_access_for_student_role(): - try: - student_role = frappe.get_doc("Role", "Student") - except frappe.DoesNotExistError: - create_student_role() - return - - student_role.desk_access = 0 - student_role.save() - - -def create_student_role(): - student_role = frappe.get_doc( - {"doctype": "Role", "role_name": "Student", "desk_access": 0, "restrict_to_domain": "Education"} - ) - student_role.insert() diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py deleted file mode 100644 index e6eb1c9987..0000000000 --- a/erpnext/education/utils.py +++ /dev/null @@ -1,449 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies and contributors - -import frappe -from frappe import _ - - -class OverlapError(frappe.ValidationError): - pass - - -def validate_overlap_for(doc, doctype, fieldname, value=None): - """Checks overlap for specified field. - - :param fieldname: Checks Overlap for this field - """ - - existing = get_overlap_for(doc, doctype, fieldname, value) - if existing: - frappe.throw( - _("This {0} conflicts with {1} for {2} {3}").format( - doc.doctype, - existing.name, - doc.meta.get_label(fieldname) if not value else fieldname, - value or doc.get(fieldname), - ), - OverlapError, - ) - - -def get_overlap_for(doc, doctype, fieldname, value=None): - """Returns overlaping document for specified field. - - :param fieldname: Checks Overlap for this field - """ - - existing = frappe.db.sql( - """select name, from_time, to_time from `tab{0}` - where `{1}`=%(val)s and schedule_date = %(schedule_date)s and - ( - (from_time > %(from_time)s and from_time < %(to_time)s) or - (to_time > %(from_time)s and to_time < %(to_time)s) or - (%(from_time)s > from_time and %(from_time)s < to_time) or - (%(from_time)s = from_time and %(to_time)s = to_time)) - and name!=%(name)s and docstatus!=2""".format( - doctype, fieldname - ), - { - "schedule_date": doc.schedule_date, - "val": value or doc.get(fieldname), - "from_time": doc.from_time, - "to_time": doc.to_time, - "name": doc.name or "No Name", - }, - as_dict=True, - ) - - return existing[0] if existing else None - - -def validate_duplicate_student(students): - unique_students = [] - for stud in students: - if stud.student in unique_students: - frappe.throw( - _("Student {0} - {1} appears Multiple times in row {2} & {3}").format( - stud.student, stud.student_name, unique_students.index(stud.student) + 1, stud.idx - ) - ) - else: - unique_students.append(stud.student) - - return None - - -# LMS Utils -def get_current_student(): - """Returns current student from frappe.session.user - - Returns: - object: Student Document - """ - email = frappe.session.user - if email in ("Administrator", "Guest"): - return None - try: - student_id = frappe.get_all("Student", {"student_email_id": email}, ["name"])[0].name - return frappe.get_doc("Student", student_id) - except (IndexError, frappe.DoesNotExistError): - return None - - -def get_portal_programs(): - """Returns a list of all program to be displayed on the portal - Programs are returned based on the following logic - is_published and (student_is_enrolled or student_can_self_enroll) - - Returns: - list of dictionary: List of all programs and to be displayed on the portal along with access rights - """ - published_programs = frappe.get_all("Program", filters={"is_published": True}) - if not published_programs: - return None - - program_list = [frappe.get_doc("Program", program) for program in published_programs] - portal_programs = [ - {"program": program, "has_access": allowed_program_access(program.name)} - for program in program_list - if allowed_program_access(program.name) or program.allow_self_enroll - ] - - return portal_programs - - -def allowed_program_access(program, student=None): - """Returns enrollment status for current student - - Args: - program (string): Name of the program - student (object): instance of Student document - - Returns: - bool: Is current user enrolled or not - """ - if has_super_access(): - return True - if not student: - student = get_current_student() - if student and get_enrollment("program", program, student.name): - return True - else: - return False - - -def get_enrollment(master, document, student): - """Gets enrollment for course or program - - Args: - master (string): can either be program or course - document (string): program or course name - student (string): Student ID - - Returns: - string: Enrollment Name if exists else returns empty string - """ - if master == "program": - enrollments = frappe.get_all( - "Program Enrollment", filters={"student": student, "program": document, "docstatus": 1} - ) - if master == "course": - enrollments = frappe.get_all( - "Course Enrollment", filters={"student": student, "course": document} - ) - - if enrollments: - return enrollments[0].name - else: - return None - - -@frappe.whitelist() -def enroll_in_program(program_name, student=None): - """Enroll student in program - - Args: - program_name (string): Name of the program to be enrolled into - student (string, optional): name of student who has to be enrolled, if not - provided, a student will be created from the current user - - Returns: - string: name of the program enrollment document - """ - if has_super_access(): - return - - if not student == None: - student = frappe.get_doc("Student", student) - else: - # Check if self enrollment in allowed - program = frappe.get_doc("Program", program_name) - if not program.allow_self_enroll: - return frappe.throw(_("You are not allowed to enroll for this course")) - - student = get_current_student() - if not student: - student = create_student_from_current_user() - - # Check if student is already enrolled in program - enrollment = get_enrollment("program", program_name, student.name) - if enrollment: - return enrollment - - # Check if self enrollment in allowed - program = frappe.get_doc("Program", program_name) - if not program.allow_self_enroll: - return frappe.throw(_("You are not allowed to enroll for this course")) - - # Enroll in program - program_enrollment = student.enroll_in_program(program_name) - return program_enrollment.name - - -def has_super_access(): - """Check if user has a role that allows full access to LMS - - Returns: - bool: true if user has access to all lms content - """ - current_user = frappe.get_doc("User", frappe.session.user) - roles = set([role.role for role in current_user.roles]) - return bool( - roles & {"Administrator", "Instructor", "Education Manager", "System Manager", "Academic User"} - ) - - -@frappe.whitelist() -def add_activity(course, content_type, content, program): - if has_super_access(): - return None - - student = get_current_student() - if not student: - return frappe.throw( - _("Student with email {0} does not exist").format(frappe.session.user), frappe.DoesNotExistError - ) - - enrollment = get_or_create_course_enrollment(course, program) - if content_type == "Quiz": - return - else: - return enrollment.add_activity(content_type, content) - - -@frappe.whitelist() -def evaluate_quiz(quiz_response, quiz_name, course, program, time_taken): - import json - - student = get_current_student() - - quiz_response = json.loads(quiz_response) - quiz = frappe.get_doc("Quiz", quiz_name) - result, score, status = quiz.evaluate(quiz_response, quiz_name) - - if has_super_access(): - return {"result": result, "score": score, "status": status} - - if student: - enrollment = get_or_create_course_enrollment(course, program) - if quiz.allowed_attempt(enrollment, quiz_name): - enrollment.add_quiz_activity(quiz_name, quiz_response, result, score, status, time_taken) - return {"result": result, "score": score, "status": status} - else: - return None - - -@frappe.whitelist() -def get_quiz(quiz_name, course): - try: - quiz = frappe.get_doc("Quiz", quiz_name) - questions = quiz.get_questions() - except Exception: - frappe.throw(_("Quiz {0} does not exist").format(quiz_name), frappe.DoesNotExistError) - return None - - questions = [ - { - "name": question.name, - "question": question.question, - "type": question.question_type, - "options": [{"name": option.name, "option": option.option} for option in question.options], - } - for question in questions - ] - - if has_super_access(): - return { - "questions": questions, - "activity": None, - "is_time_bound": quiz.is_time_bound, - "duration": quiz.duration, - } - - student = get_current_student() - course_enrollment = get_enrollment("course", course, student.name) - status, score, result, time_taken = check_quiz_completion(quiz, course_enrollment) - return { - "questions": questions, - "activity": {"is_complete": status, "score": score, "result": result, "time_taken": time_taken}, - "is_time_bound": quiz.is_time_bound, - "duration": quiz.duration, - } - - -def get_topic_progress(topic, course_name, program): - """ - Return the porgress of a course in a program as well as the content to continue from. - :param topic_name: - :param course_name: - """ - student = get_current_student() - if not student: - return None - course_enrollment = get_or_create_course_enrollment(course_name, program) - progress = student.get_topic_progress(course_enrollment.name, topic) - if not progress: - return None - count = sum([activity["is_complete"] for activity in progress]) - if count == 0: - return {"completed": False, "started": False} - elif count == len(progress): - return {"completed": True, "started": True} - elif count < len(progress): - return {"completed": False, "started": True} - - -def get_course_progress(course, program): - """ - Return the porgress of a course in a program as well as the content to continue from. - :param topic_name: - :param course_name: - """ - course_progress = [] - for course_topic in course.topics: - topic = frappe.get_doc("Topic", course_topic.topic) - progress = get_topic_progress(topic, course.name, program) - if progress: - course_progress.append(progress) - if course_progress: - number_of_completed_topics = sum([activity["completed"] for activity in course_progress]) - total_topics = len(course_progress) - if total_topics == 1: - return course_progress[0] - if number_of_completed_topics == 0: - return {"completed": False, "started": False} - if number_of_completed_topics == total_topics: - return {"completed": True, "started": True} - if number_of_completed_topics < total_topics: - return {"completed": False, "started": True} - - return None - - -def get_program_progress(program): - program_progress = [] - if not program.courses: - return None - for program_course in program.courses: - course = frappe.get_doc("Course", program_course.course) - progress = get_course_progress(course, program.name) - if progress: - progress["name"] = course.name - progress["course"] = course.course_name - program_progress.append(progress) - - if program_progress: - return program_progress - - return None - - -def get_program_completion(program): - topics = frappe.db.sql( - """select `tabCourse Topic`.topic, `tabCourse Topic`.parent - from `tabCourse Topic`, - `tabProgram Course` - where `tabCourse Topic`.parent = `tabProgram Course`.course - and `tabProgram Course`.parent = %s""", - program.name, - ) - - progress = [] - for topic in topics: - topic_doc = frappe.get_doc("Topic", topic[0]) - topic_progress = get_topic_progress(topic_doc, topic[1], program.name) - if topic_progress: - progress.append(topic_progress) - - if progress: - number_of_completed_topics = sum([activity["completed"] for activity in progress if activity]) - total_topics = len(progress) - try: - return int((float(number_of_completed_topics) / total_topics) * 100) - except ZeroDivisionError: - return 0 - - return 0 - - -def create_student_from_current_user(): - user = frappe.get_doc("User", frappe.session.user) - - student = frappe.get_doc( - { - "doctype": "Student", - "first_name": user.first_name, - "last_name": user.last_name, - "student_email_id": user.email, - "user": frappe.session.user, - } - ) - - student.save(ignore_permissions=True) - return student - - -def get_or_create_course_enrollment(course, program): - student = get_current_student() - course_enrollment = get_enrollment("course", course, student.name) - if not course_enrollment: - program_enrollment = get_enrollment("program", program.name, student.name) - if not program_enrollment: - frappe.throw(_("You are not enrolled in program {0}").format(program)) - return - return student.enroll_in_course( - course_name=course, program_enrollment=get_enrollment("program", program.name, student.name) - ) - else: - return frappe.get_doc("Course Enrollment", course_enrollment) - - -def check_content_completion(content_name, content_type, enrollment_name): - activity = frappe.get_all( - "Course Activity", - filters={"enrollment": enrollment_name, "content_type": content_type, "content": content_name}, - ) - if activity: - return True - else: - return False - - -def check_quiz_completion(quiz, enrollment_name): - attempts = frappe.get_all( - "Quiz Activity", - filters={"enrollment": enrollment_name, "quiz": quiz.name}, - fields=["name", "activity_date", "score", "status", "time_taken"], - ) - status = False if quiz.max_attempts == 0 else bool(len(attempts) >= quiz.max_attempts) - score = None - result = None - time_taken = None - if attempts: - if quiz.grading_basis == "Last Highest Score": - attempts = sorted(attempts, key=lambda i: int(i.score), reverse=True) - score = attempts[0]["score"] - result = attempts[0]["status"] - time_taken = attempts[0]["time_taken"] - if result == "Pass": - status = True - return status, score, result, time_taken diff --git a/erpnext/education/web_form/__init__.py b/erpnext/education/web_form/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/web_form/student_applicant/__init__.py b/erpnext/education/web_form/student_applicant/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/web_form/student_applicant/student_applicant.js b/erpnext/education/web_form/student_applicant/student_applicant.js deleted file mode 100644 index ffc5e98425..0000000000 --- a/erpnext/education/web_form/student_applicant/student_applicant.js +++ /dev/null @@ -1,3 +0,0 @@ -frappe.ready(function() { - // bind events here -}) diff --git a/erpnext/education/web_form/student_applicant/student_applicant.json b/erpnext/education/web_form/student_applicant/student_applicant.json deleted file mode 100644 index 7b4eaa18ff..0000000000 --- a/erpnext/education/web_form/student_applicant/student_applicant.json +++ /dev/null @@ -1,250 +0,0 @@ -{ - "accept_payment": 0, - "allow_comments": 0, - "allow_delete": 0, - "allow_edit": 1, - "allow_incomplete": 0, - "allow_multiple": 1, - "allow_print": 0, - "amount": 0.0, - "amount_based_on_field": 0, - "apply_document_permissions": 0, - "creation": "2016-09-22 13:10:10.792735", - "doc_type": "Student Applicant", - "docstatus": 0, - "doctype": "Web Form", - "idx": 0, - "is_standard": 1, - "login_required": 1, - "max_attachment_size": 0, - "modified": "2020-10-07 23:13:07.814941", - "modified_by": "Administrator", - "module": "Education", - "name": "student-applicant", - "owner": "Administrator", - "payment_button_label": "Buy Now", - "published": 1, - "route": "student-applicant", - "route_to_success_link": 0, - "show_attachments": 0, - "show_in_grid": 0, - "show_sidebar": 1, - "sidebar_items": [], - "success_url": "/student-applicant", - "title": "Student Applicant", - "web_form_fields": [ - { - "allow_read_on_all_link_options": 0, - "fieldname": "first_name", - "fieldtype": "Data", - "hidden": 0, - "label": "First Name", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 1, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 0, - "fieldname": "middle_name", - "fieldtype": "Data", - "hidden": 0, - "label": "Middle Name", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 0, - "fieldname": "last_name", - "fieldtype": "Data", - "hidden": 0, - "label": "Last Name", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 1, - "fieldname": "program", - "fieldtype": "Link", - "hidden": 0, - "label": "Program", - "max_length": 0, - "max_value": 0, - "options": "Program", - "read_only": 0, - "reqd": 1, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 1, - "fieldname": "academic_year", - "fieldtype": "Link", - "hidden": 0, - "label": "Academic Year", - "max_length": 0, - "max_value": 0, - "options": "Academic Year", - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 1, - "fieldname": "academic_term", - "fieldtype": "Link", - "hidden": 0, - "label": "Academic Term", - "max_length": 0, - "max_value": 0, - "options": "Academic Term", - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 0, - "fieldname": "date_of_birth", - "fieldtype": "Date", - "hidden": 0, - "label": "Date of Birth", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 1, - "fieldname": "gender", - "fieldtype": "Link", - "hidden": 0, - "label": "Gender", - "max_length": 0, - "max_value": 0, - "options": "Gender", - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 0, - "fieldname": "blood_group", - "fieldtype": "Select", - "hidden": 0, - "label": "Blood Group", - "max_length": 0, - "max_value": 0, - "options": "\nA+\nA-\nB+\nB-\nO+\nO-\nAB+\nAB-", - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 0, - "fieldname": "student_email_id", - "fieldtype": "Data", - "hidden": 0, - "label": "Student Email ID", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 1, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 0, - "fieldname": "student_mobile_number", - "fieldtype": "Data", - "hidden": 0, - "label": "Student Mobile Number", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 0, - "default": "", - "fieldname": "nationality", - "fieldtype": "Data", - "hidden": 0, - "label": "Nationality", - "max_length": 0, - "max_value": 0, - "options": "", - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 0, - "fieldname": "address_line_1", - "fieldtype": "Data", - "hidden": 0, - "label": "Address Line 1", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 0, - "fieldname": "address_line_2", - "fieldtype": "Data", - "hidden": 0, - "label": "Address Line 2", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 0, - "fieldname": "pincode", - "fieldtype": "Data", - "hidden": 0, - "label": "Pincode", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 0, - "fieldname": "siblings", - "fieldtype": "Table", - "hidden": 0, - "label": "Siblings", - "max_length": 0, - "max_value": 0, - "options": "Student Sibling", - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 0, - "fieldname": "student_admission", - "fieldtype": "Link", - "hidden": 0, - "label": "Student Admission", - "max_length": 0, - "max_value": 0, - "options": "Student Admission", - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - } - ] -} \ No newline at end of file diff --git a/erpnext/education/web_form/student_applicant/student_applicant.py b/erpnext/education/web_form/student_applicant/student_applicant.py deleted file mode 100644 index 02e3e93333..0000000000 --- a/erpnext/education/web_form/student_applicant/student_applicant.py +++ /dev/null @@ -1,3 +0,0 @@ -def get_context(context): - # do your magic here - pass diff --git a/erpnext/education/workspace/education/education.json b/erpnext/education/workspace/education/education.json deleted file mode 100644 index 0c7f19894c..0000000000 --- a/erpnext/education/workspace/education/education.json +++ /dev/null @@ -1,765 +0,0 @@ -{ - "charts": [ - { - "chart_name": "Program Enrollments", - "label": "Program Enrollments" - } - ], - "content": "[{\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Education\",\"col\":12}},{\"type\":\"chart\",\"data\":{\"chart_name\":\"Program Enrollments\",\"col\":12}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"Your Shortcuts\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Student\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Instructor\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Program\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Course\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Fees\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Student Monthly Attendance Sheet\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Course Scheduling Tool\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Student Attendance Tool\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"Reports & Masters\",\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Student and Instructor\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Masters\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Content Masters\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Admission\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Fees\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Schedule\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Attendance\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"LMS Activity\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Assessment\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Assessment Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Tools\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Other Reports\",\"col\":4}}]", - "creation": "2020-03-02 17:22:57.066401", - "docstatus": 0, - "doctype": "Workspace", - "for_user": "", - "hide_custom": 0, - "icon": "education", - "idx": 0, - "label": "Education", - "links": [ - { - "hidden": 0, - "is_query_report": 0, - "label": "Student and Instructor", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Student", - "link_count": 0, - "link_to": "Student", - "link_type": "DocType", - "onboard": 1, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Instructor", - "link_count": 0, - "link_to": "Instructor", - "link_type": "DocType", - "onboard": 1, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Guardian", - "link_count": 0, - "link_to": "Guardian", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Student Group", - "link_count": 0, - "link_to": "Student Group", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Student Log", - "link_count": 0, - "link_to": "Student Log", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Masters", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Program", - "link_count": 0, - "link_to": "Program", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Course", - "link_count": 0, - "link_to": "Course", - "link_type": "DocType", - "onboard": 1, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Topic", - "link_count": 0, - "link_to": "Topic", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Room", - "link_count": 0, - "link_to": "Room", - "link_type": "DocType", - "onboard": 1, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Content Masters", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Article", - "link_count": 0, - "link_to": "Article", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Video", - "link_count": 0, - "link_to": "Video", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Quiz", - "link_count": 0, - "link_to": "Quiz", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Settings", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Education Settings", - "link_count": 0, - "link_to": "Education Settings", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Student Category", - "link_count": 0, - "link_to": "Student Category", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Student Batch Name", - "link_count": 0, - "link_to": "Student Batch Name", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Grading Scale", - "link_count": 0, - "link_to": "Grading Scale", - "link_type": "DocType", - "onboard": 1, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Academic Term", - "link_count": 0, - "link_to": "Academic Term", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Academic Year", - "link_count": 0, - "link_to": "Academic Year", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Admission", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Student Applicant", - "link_count": 0, - "link_to": "Student Applicant", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Student Admission", - "link_count": 0, - "link_to": "Student Admission", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Program Enrollment", - "link_count": 0, - "link_to": "Program Enrollment", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Course Enrollment", - "link_count": 0, - "link_to": "Course Enrollment", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Fees", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Fee Structure", - "link_count": 0, - "link_to": "Fee Structure", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Fee Category", - "link_count": 0, - "link_to": "Fee Category", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Fee Schedule", - "link_count": 0, - "link_to": "Fee Schedule", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Fees", - "link_count": 0, - "link_to": "Fees", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Fees", - "hidden": 0, - "is_query_report": 1, - "label": "Student Fee Collection Report", - "link_count": 0, - "link_to": "Student Fee Collection", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Fees", - "hidden": 0, - "is_query_report": 1, - "label": "Program wise Fee Collection Report", - "link_count": 0, - "link_to": "Program wise Fee Collection", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Schedule", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Course Schedule", - "link_count": 0, - "link_to": "Course Schedule", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Course Scheduling Tool", - "link_count": 0, - "link_to": "Course Scheduling Tool", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Attendance", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Student Attendance", - "link_count": 0, - "link_to": "Student Attendance", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Student Leave Application", - "link_count": 0, - "link_to": "Student Leave Application", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Student Attendance", - "hidden": 0, - "is_query_report": 1, - "label": "Student Monthly Attendance Sheet", - "link_count": 0, - "link_to": "Student Monthly Attendance Sheet", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Student Attendance", - "hidden": 0, - "is_query_report": 1, - "label": "Absent Student Report", - "link_count": 0, - "link_to": "Absent Student Report", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Student Attendance", - "hidden": 0, - "is_query_report": 1, - "label": "Student Batch-Wise Attendance", - "link_count": 0, - "link_to": "Student Batch-Wise Attendance", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "LMS Activity", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Course Enrollment", - "link_count": 0, - "link_to": "Course Enrollment", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Course Activity", - "link_count": 0, - "link_to": "Course Activity", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Quiz Activity", - "link_count": 0, - "link_to": "Quiz Activity", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Assessment", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Assessment Plan", - "link_count": 0, - "link_to": "Assessment Plan", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Assessment Group", - "link_count": 0, - "link_to": "Assessment Group", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Assessment Result", - "link_count": 0, - "link_to": "Assessment Result", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Assessment Criteria", - "link_count": 0, - "link_to": "Assessment Criteria", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Assessment Reports", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "Assessment Result", - "hidden": 0, - "is_query_report": 1, - "label": "Course wise Assessment Report", - "link_count": 0, - "link_to": "Course wise Assessment Report", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Assessment Result", - "hidden": 0, - "is_query_report": 1, - "label": "Final Assessment Grades", - "link_count": 0, - "link_to": "Final Assessment Grades", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Assessment Plan", - "hidden": 0, - "is_query_report": 1, - "label": "Assessment Plan Status", - "link_count": 0, - "link_to": "Assessment Plan Status", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Student Report Generation Tool", - "link_count": 0, - "link_to": "Student Report Generation Tool", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Tools", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Student Attendance Tool", - "link_count": 0, - "link_to": "Student Attendance Tool", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Assessment Result Tool", - "link_count": 0, - "link_to": "Assessment Result Tool", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Student Group Creation Tool", - "link_count": 0, - "link_to": "Student Group Creation Tool", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Program Enrollment Tool", - "link_count": 0, - "link_to": "Program Enrollment Tool", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Course Scheduling Tool", - "link_count": 0, - "link_to": "Course Scheduling Tool", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Other Reports", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "Program Enrollment", - "hidden": 0, - "is_query_report": 1, - "label": "Student and Guardian Contact Details", - "link_count": 0, - "link_to": "Student and Guardian Contact Details", - "link_type": "Report", - "onboard": 0, - "type": "Link" - } - ], - "modified": "2022-01-13 17:29:13.676542", - "modified_by": "Administrator", - "module": "Education", - "name": "Education", - "owner": "Administrator", - "parent_page": "", - "public": 1, - "restrict_to_domain": "Education", - "roles": [], - "sequence_id": 9.0, - "shortcuts": [ - { - "color": "Grey", - "format": "{} Active", - "label": "Student", - "link_to": "Student", - "stats_filter": "{\n \"enabled\": 1\n}", - "type": "DocType" - }, - { - "color": "Grey", - "format": "{} Active", - "label": "Instructor", - "link_to": "Instructor", - "stats_filter": "{\n \"status\": \"Active\"\n}", - "type": "DocType" - }, - { - "color": "", - "format": "", - "label": "Program", - "link_to": "Program", - "stats_filter": "", - "type": "DocType" - }, - { - "label": "Course", - "link_to": "Course", - "type": "DocType" - }, - { - "color": "Grey", - "format": "{} Unpaid", - "label": "Fees", - "link_to": "Fees", - "stats_filter": "{\n \"outstanding_amount\": [\"!=\", 0.0]\n}", - "type": "DocType" - }, - { - "label": "Student Monthly Attendance Sheet", - "link_to": "Student Monthly Attendance Sheet", - "type": "Report" - }, - { - "label": "Course Scheduling Tool", - "link_to": "Course Scheduling Tool", - "type": "DocType" - }, - { - "label": "Student Attendance Tool", - "link_to": "Student Attendance Tool", - "type": "DocType" - }, - { - "label": "Dashboard", - "link_to": "Education", - "type": "Dashboard" - } - ], - "title": "Education" -} \ No newline at end of file From 41e2959389c0c5c878e6fda13bebb3e99071d074 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 28 Apr 2022 10:41:30 +0530 Subject: [PATCH 081/106] chore: remove files related to LMS --- erpnext/domains/education.py | 19 -- erpnext/hooks.py | 1 - erpnext/projects/doctype/project/project.py | 16 +- .../js/education/assessment_result_tool.html | 72 ----- erpnext/public/js/education/lms/quiz.js | 238 ----------------- erpnext/www/lms/__init__.py | 0 erpnext/www/lms/content.html | 246 ------------------ erpnext/www/lms/content.py | 75 ------ erpnext/www/lms/course.html | 106 -------- erpnext/www/lms/course.py | 28 -- erpnext/www/lms/index.html | 69 ----- erpnext/www/lms/index.py | 17 -- erpnext/www/lms/macros/__init__.py | 0 erpnext/www/lms/macros/card.html | 34 --- erpnext/www/lms/macros/hero.html | 53 ---- erpnext/www/lms/profile.html | 64 ----- erpnext/www/lms/profile.py | 37 --- erpnext/www/lms/program.html | 87 ------- erpnext/www/lms/program.py | 32 --- erpnext/www/lms/topic.html | 58 ----- erpnext/www/lms/topic.py | 57 ---- 21 files changed, 14 insertions(+), 1295 deletions(-) delete mode 100644 erpnext/domains/education.py delete mode 100644 erpnext/public/js/education/assessment_result_tool.html delete mode 100644 erpnext/public/js/education/lms/quiz.js delete mode 100644 erpnext/www/lms/__init__.py delete mode 100644 erpnext/www/lms/content.html delete mode 100644 erpnext/www/lms/content.py delete mode 100644 erpnext/www/lms/course.html delete mode 100644 erpnext/www/lms/course.py delete mode 100644 erpnext/www/lms/index.html delete mode 100644 erpnext/www/lms/index.py delete mode 100644 erpnext/www/lms/macros/__init__.py delete mode 100644 erpnext/www/lms/macros/card.html delete mode 100644 erpnext/www/lms/macros/hero.html delete mode 100644 erpnext/www/lms/profile.html delete mode 100644 erpnext/www/lms/profile.py delete mode 100644 erpnext/www/lms/program.html delete mode 100644 erpnext/www/lms/program.py delete mode 100644 erpnext/www/lms/topic.html delete mode 100644 erpnext/www/lms/topic.py diff --git a/erpnext/domains/education.py b/erpnext/domains/education.py deleted file mode 100644 index 23b8258baf..0000000000 --- a/erpnext/domains/education.py +++ /dev/null @@ -1,19 +0,0 @@ -data = { - "desktop_icons": [ - "Student", - "Program", - "Course", - "Student Group", - "Instructor", - "Fees", - "Task", - "ToDo", - "Education", - "Student Attendance Tool", - "Student Applicant", - ], - "default_portal_role": "Student", - "restricted_roles": ["Student", "Instructor", "Academics User", "Education Manager"], - "modules": ["Education"], - "on_setup": "erpnext.education.setup.setup_education", -} diff --git a/erpnext/hooks.py b/erpnext/hooks.py index fe0a89a276..e1785626ee 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -69,7 +69,6 @@ treeviews = [ # website update_website_context = [ "erpnext.e_commerce.shopping_cart.utils.update_website_context", - "erpnext.education.doctype.education_settings.education_settings.update_website_context", ] my_account_context = "erpnext.e_commerce.shopping_cart.utils.update_my_account_context" webform_list_context = "erpnext.controllers.website_list_for_contact.get_webform_list_context" diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 29f1ce455e..a97efffec8 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -11,10 +11,9 @@ from frappe.utils import add_days, flt, get_datetime, get_time, get_url, nowtime from erpnext.controllers.employee_boarding_controller import update_employee_boarding_status from erpnext.controllers.queries import get_filters_cond -from erpnext.education.doctype.student_attendance.student_attendance import get_holiday_list from erpnext.hr.doctype.daily_work_summary.daily_work_summary import get_users_email from erpnext.hr.doctype.holiday_list.holiday_list import is_holiday - +from erpnext import get_default_company class Project(Document): def get_feed(self): @@ -665,3 +664,16 @@ def set_project_status(project, status): project.status = status project.save() + +def get_holiday_list(company=None): + if not company: + company = get_default_company() or frappe.get_all("Company")[0].name + + holiday_list = frappe.get_cached_value("Company", company, "default_holiday_list") + if not holiday_list: + frappe.throw( + _("Please set a default Holiday List for Company {0}").format( + frappe.bold(get_default_company()) + ) + ) + return holiday_list \ No newline at end of file diff --git a/erpnext/public/js/education/assessment_result_tool.html b/erpnext/public/js/education/assessment_result_tool.html deleted file mode 100644 index f7d1ab39fc..0000000000 --- a/erpnext/public/js/education/assessment_result_tool.html +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - {% for c in criteria %} - - {% endfor %} - - - - - - {% for c in criteria %} - - {% endfor %} - - - - - {% for s in students %} - - - - - {% for c in criteria %} - - {% endfor %} - - - {% endfor %} - -
StudentStudent Name{{ c.assessment_criteria }}CommentsTotal Marks
Score ({{ c.maximum_score }})Score ({{max_total_score}})
{{ s.student }}{{ s.student_name }} - - {% if(s.assessment_details) { %} - {{s.assessment_details[c.assessment_criteria][1]}} - {% } %} - - - - - - - {% if(s.assessment_details) { %} - {{s.assessment_details.total_score[1]}} - {% } %} - - - {% if(s.assessment_details) { %} - {{s.assessment_details.total_score[0]}} - {% } %} - - - - - - -
diff --git a/erpnext/public/js/education/lms/quiz.js b/erpnext/public/js/education/lms/quiz.js deleted file mode 100644 index 66160a7610..0000000000 --- a/erpnext/public/js/education/lms/quiz.js +++ /dev/null @@ -1,238 +0,0 @@ -class Quiz { - constructor(wrapper, options) { - this.wrapper = wrapper; - Object.assign(this, options); - this.questions = [] - this.refresh(); - } - - refresh() { - this.get_quiz(); - } - - get_quiz() { - frappe.call('erpnext.education.utils.get_quiz', { - quiz_name: this.name, - course: this.course - }).then(res => { - this.make(res.message) - }); - } - - make(data) { - if (data.is_time_bound) { - $(".lms-timer").removeClass("hide"); - if (!data.activity || (data.activity && !data.activity.is_complete)) { - this.initialiseTimer(data.duration); - this.is_time_bound = true; - this.time_taken = 0; - } - } - data.questions.forEach(question_data => { - let question_wrapper = document.createElement('div'); - let question = new Question({ - wrapper: question_wrapper, - ...question_data - }); - this.questions.push(question) - this.wrapper.appendChild(question_wrapper); - }) - if (data.activity && data.activity.is_complete) { - this.disable() - let indicator = 'red' - let message = 'Your are not allowed to attempt the quiz again.' - if (data.activity.result == 'Pass') { - indicator = 'green' - message = 'You have already cleared the quiz.' - } - if (data.activity.time_taken) { - this.calculate_and_display_time(data.activity.time_taken, "Time Taken - "); - } - this.set_quiz_footer(message, indicator, data.activity.score) - } - else { - this.make_actions(); - } - window.addEventListener('beforeunload', (event) => { - event.preventDefault(); - event.returnValue = ''; - }); - } - - initialiseTimer(duration) { - this.time_left = duration; - var self = this; - var old_diff; - this.calculate_and_display_time(this.time_left, "Time Left - "); - this.start_time = new Date().getTime(); - this.timer = setInterval(function () { - var diff = (new Date().getTime() - self.start_time)/1000; - var variation = old_diff ? diff - old_diff : diff; - old_diff = diff; - self.time_left -= variation; - self.time_taken += variation; - self.calculate_and_display_time(self.time_left, "Time Left - "); - if (self.time_left <= 0) { - clearInterval(self.timer); - self.time_taken -= 1; - self.submit(); - } - }, 1000); - } - - calculate_and_display_time(second, text) { - var timer_display = document.getElementsByClassName("lms-timer")[0]; - var hours = this.append_zero(Math.floor(second / 3600)); - var minutes = this.append_zero(Math.floor(second % 3600 / 60)); - var seconds = this.append_zero(Math.ceil(second % 3600 % 60)); - timer_display.innerText = text + hours + ":" + minutes + ":" + seconds; - } - - append_zero(time) { - return time > 9 ? time : "0" + time; - } - - make_actions() { - const button = document.createElement("button"); - button.classList.add("btn", "btn-primary", "mt-5", "mr-2"); - - button.id = 'submit-button'; - button.innerText = 'Submit'; - button.onclick = () => this.submit(); - this.submit_btn = button - this.wrapper.appendChild(button); - } - - submit() { - if (this.is_time_bound) { - clearInterval(this.timer); - $(".lms-timer").text(""); - } - this.submit_btn.innerText = 'Evaluating..' - this.submit_btn.disabled = true - this.disable() - frappe.call('erpnext.education.utils.evaluate_quiz', { - quiz_name: this.name, - quiz_response: this.get_selected(), - course: this.course, - program: this.program, - time_taken: this.is_time_bound ? this.time_taken : 0 - }).then(res => { - this.submit_btn.remove() - if (!res.message) { - frappe.throw(__("Something went wrong while evaluating the quiz.")) - } - - let indicator = 'red' - let message = 'Fail' - if (res.message.status == 'Pass') { - indicator = 'green' - message = 'Congratulations, you cleared the quiz.' - } - - this.set_quiz_footer(message, indicator, res.message.score) - }); - } - - set_quiz_footer(message, indicator, score) { - const div = document.createElement("div"); - div.classList.add("mt-5"); - div.innerHTML = `
-
-

${message}

-
Score: ${score}/100
-
- -
` - - this.wrapper.appendChild(div) - } - - disable() { - this.questions.forEach(que => que.disable()) - } - - get_selected() { - let que = {} - this.questions.forEach(question => { - que[question.name] = question.get_selected() - }) - return que - } -} - -class Question { - constructor(opts) { - Object.assign(this, opts); - this.make(); - } - - make() { - this.make_question() - this.make_options() - } - - get_selected() { - let selected = this.options.filter(opt => opt.input.checked) - if (this.type == 'Single Correct Answer') { - if (selected[0]) return selected[0].name - } - if (this.type == 'Multiple Correct Answer') { - return selected.map(opt => opt.name) - } - return null - } - - disable() { - let selected = this.options.forEach(opt => opt.input.disabled = true) - } - - make_question() { - let question_wrapper = document.createElement('h5'); - question_wrapper.classList.add('mt-3'); - question_wrapper.innerHTML = this.question; - this.wrapper.appendChild(question_wrapper); - } - - make_options() { - let make_input = (name, value) => { - let input = document.createElement('input'); - input.id = name; - input.name = this.name; - input.value = value; - input.type = 'radio'; - if (this.type == 'Multiple Correct Answer') - input.type = 'checkbox'; - input.classList.add('form-check-input'); - return input; - } - - let make_label = function (name, value) { - let label = document.createElement('label'); - label.classList.add('form-check-label'); - label.htmlFor = name; - label.innerText = value; - return label - } - - let make_option = function (wrapper, option) { - let option_div = document.createElement('div'); - option_div.classList.add('form-check', 'pb-1'); - let input = make_input(option.name, option.option); - let label = make_label(option.name, option.option); - option_div.appendChild(input); - option_div.appendChild(label); - wrapper.appendChild(option_div); - return { input: input, ...option }; - } - - let options_wrapper = document.createElement('div') - options_wrapper.classList.add('ml-2') - let option_list = [] - this.options.forEach(opt => option_list.push(make_option(options_wrapper, opt))) - this.options = option_list - this.wrapper.appendChild(options_wrapper) - } -} diff --git a/erpnext/www/lms/__init__.py b/erpnext/www/lms/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/www/lms/content.html b/erpnext/www/lms/content.html deleted file mode 100644 index d22ef66d2a..0000000000 --- a/erpnext/www/lms/content.html +++ /dev/null @@ -1,246 +0,0 @@ -{% extends "templates/base.html" %} -{% block title %}{{ content.name or 'Content Page' }}{% endblock %} - -{% block head_include %} - - -{% endblock %} - -{% macro title() %} - -
-

{{ content.name }} ({{ position + 1 }}/{{length}})

-
-
-{% endmacro %} - -{% macro navigation() %} - {% if previous %} - {{_('Previous')}} - {% else %} - {{ _('Back to Course') }} - {% endif %} - - {% if next %} - - {% else %} - - {% endif %} -{% endmacro %} - -{% macro video() %} -
- {{ title() }} -
- {% if content.duration %} - {{ content.duration }} {{_('Mins')}} - {% endif %} - - {% if content.publish_date and content.duration%} - - - {% endif %} - - {% if content.publish_date %} - {{_('Published on')}} {{ content.publish_date.strftime('%d, %b %Y') }} - {% endif %} -
-
-
-
- {{ content.description }} -
-{% endmacro %} - -{% macro article() %} -
- {{ title() }} -
- {% if content.author or content.publish_date %} - {{_('Published')}} - {% endif %} - {% if content.author %} - {{_('by')}} {{ content.author }} - {% endif %} - {% if content.publish_date %} - {{_('on')}} {{ content.publish_date.strftime('%d, %b %Y') }} - {% endif %} -
-
-
- {{ content.content }} -
-{% endmacro %} - -{% macro quiz() %} -
- {{ title() }} -
-
-
-{% endmacro %} - -{% block content %} -
-
-
- {% if content_type=='Video' %} - {{ video() }} - {% elif content_type=='Article'%} - {{ article() }} - {% elif content_type=='Quiz' %} - {{ quiz() }} - {% endif %} -
- {{ navigation() }} -
-
-
-
-{% endblock %} - -{% block script %} - {% if content_type=='Video' %} - - {% elif content_type == 'Quiz' %} - - {% endif %} - -{% endblock %} diff --git a/erpnext/www/lms/content.py b/erpnext/www/lms/content.py deleted file mode 100644 index 99462ceeee..0000000000 --- a/erpnext/www/lms/content.py +++ /dev/null @@ -1,75 +0,0 @@ -import frappe - -import erpnext.education.utils as utils - -no_cache = 1 - - -def get_context(context): - # Load Query Parameters - try: - program = frappe.form_dict["program"] - content = frappe.form_dict["content"] - content_type = frappe.form_dict["type"] - course = frappe.form_dict["course"] - topic = frappe.form_dict["topic"] - except KeyError: - frappe.local.flags.redirect_location = "/lms" - raise frappe.Redirect - - # Check if user has access to the content - has_program_access = utils.allowed_program_access(program) - has_content_access = allowed_content_access(program, content, content_type) - - if frappe.session.user == "Guest" or not has_program_access or not has_content_access: - frappe.local.flags.redirect_location = "/lms" - raise frappe.Redirect - - # Set context for content to be displayer - context.content = frappe.get_doc(content_type, content).as_dict() - context.content_type = content_type - context.program = program - context.course = course - context.topic = topic - - topic = frappe.get_doc("Topic", topic) - content_list = [ - {"content_type": item.content_type, "content": item.content} for item in topic.topic_content - ] - - # Set context for progress numbers - context.position = content_list.index({"content": content, "content_type": content_type}) - context.length = len(content_list) - - # Set context for navigation - context.previous = get_previous_content(content_list, context.position) - context.next = get_next_content(content_list, context.position) - - -def get_next_content(content_list, current_index): - try: - return content_list[current_index + 1] - except IndexError: - return None - - -def get_previous_content(content_list, current_index): - if current_index == 0: - return None - else: - return content_list[current_index - 1] - - -def allowed_content_access(program, content, content_type): - contents_of_program = frappe.db.sql( - """select `tabTopic Content`.content, `tabTopic Content`.content_type - from `tabCourse Topic`, - `tabProgram Course`, - `tabTopic Content` - where `tabCourse Topic`.parent = `tabProgram Course`.course - and `tabTopic Content`.parent = `tabCourse Topic`.topic - and `tabProgram Course`.parent = %(program)s""", - {"program": program}, - ) - - return (content, content_type) in contents_of_program diff --git a/erpnext/www/lms/course.html b/erpnext/www/lms/course.html deleted file mode 100644 index c07b9402b1..0000000000 --- a/erpnext/www/lms/course.html +++ /dev/null @@ -1,106 +0,0 @@ -{% extends "templates/base.html" %} -{% block title %}{{ course.course_name }}{% endblock %} -{% from "www/lms/macros/hero.html" import hero %} -{% from "www/lms/macros/card.html" import null_card %} - -{% block head_include %} - -{% endblock %} - - -{% macro card(topic) %} -
-
- {% if has_access %} - - {% else %} - - {% endif %} - {% if topic.hero_image %} -
- {% else %} -
-
-
- {% endif %} -
- {% if has_access %} - - - {% else %} - - {% endif %} -
-
-{% endmacro %} - -{% block content %} -
- {{ hero(course.course_name, course.description, has_access, {'name': 'Program', 'url': '/lms/program?program=' + program }) }} -
-
- {% for topic in topics %} - {{ card(topic) }} - {% endfor %} - {% if topics %} - {% for n in range( (3 - (topics|length)) %3) %} - {{ null_card() }} - {% endfor %} - {% endif %} -
-
-
-{% endblock %} diff --git a/erpnext/www/lms/course.py b/erpnext/www/lms/course.py deleted file mode 100644 index 840beee3ad..0000000000 --- a/erpnext/www/lms/course.py +++ /dev/null @@ -1,28 +0,0 @@ -import frappe - -import erpnext.education.utils as utils - -no_cache = 1 - - -def get_context(context): - try: - program = frappe.form_dict["program"] - course_name = frappe.form_dict["name"] - except KeyError: - frappe.local.flags.redirect_location = "/lms" - raise frappe.Redirect - - context.education_settings = frappe.get_single("Education Settings") - course = frappe.get_doc("Course", course_name) - context.program = program - context.course = course - - context.topics = course.get_topics() - context.has_access = utils.allowed_program_access(context.program) - context.progress = get_topic_progress(context.topics, course, context.program) - - -def get_topic_progress(topics, course, program): - progress = {topic.name: utils.get_topic_progress(topic, course.name, program) for topic in topics} - return progress diff --git a/erpnext/www/lms/index.html b/erpnext/www/lms/index.html deleted file mode 100644 index c1e96205eb..0000000000 --- a/erpnext/www/lms/index.html +++ /dev/null @@ -1,69 +0,0 @@ -{% extends "templates/base.html" %} -{% block title %}{{ education_settings.portal_title }}{% endblock %} -{% from "www/lms/macros/card.html" import program_card %} -{% from "www/lms/macros/card.html" import null_card %} - -{% block head_include %} - - - -{% endblock %} - -{% block content %} -
-
-

{{ education_settings.portal_title }}

- {% if education_settings.description %} -

{{ education_settings.description }}

- {% endif %} -

- {% if frappe.session.user == 'Guest' %} - {{_('Sign Up')}} - {% endif %} -

-
-
-
- {% if featured_programs %} - {% for program in featured_programs %} - {{ program_card(program.program, program.has_access) }} - {% endfor %} - {% for n in range( (3 - (featured_programs|length)) %3) %} - {{ null_card() }} - {% endfor %} - {% else %} -

You have not enrolled in any program. Contact your Instructor.

- {% endif %} -
-
-
-{% endblock %} diff --git a/erpnext/www/lms/index.py b/erpnext/www/lms/index.py deleted file mode 100644 index 782ac481a0..0000000000 --- a/erpnext/www/lms/index.py +++ /dev/null @@ -1,17 +0,0 @@ -import frappe - -import erpnext.education.utils as utils - -no_cache = 1 - - -def get_context(context): - context.education_settings = frappe.get_single("Education Settings") - if not context.education_settings.enable_lms: - frappe.local.flags.redirect_location = "/" - raise frappe.Redirect - context.featured_programs = get_featured_programs() - - -def get_featured_programs(): - return utils.get_portal_programs() or [] diff --git a/erpnext/www/lms/macros/__init__.py b/erpnext/www/lms/macros/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/www/lms/macros/card.html b/erpnext/www/lms/macros/card.html deleted file mode 100644 index 3cbdec61aa..0000000000 --- a/erpnext/www/lms/macros/card.html +++ /dev/null @@ -1,34 +0,0 @@ -{% macro program_card(program, has_access) %} - -{% endmacro %} - - -{% macro null_card() %} -
-
-
-
-{% endmacro %} diff --git a/erpnext/www/lms/macros/hero.html b/erpnext/www/lms/macros/hero.html deleted file mode 100644 index dd3c23a014..0000000000 --- a/erpnext/www/lms/macros/hero.html +++ /dev/null @@ -1,53 +0,0 @@ -{% macro hero(title, description, has_access, back) %} -
- -

{{ title }}

-

{{ description or ''}}

-

- {% if frappe.session.user == 'Guest' %} - {{_('Sign Up')}} - {% elif not has_access %} - - {% endif %} -

-
- -{% block script %} - -{% endblock %} -{% endmacro %} diff --git a/erpnext/www/lms/profile.html b/erpnext/www/lms/profile.html deleted file mode 100644 index 5755dfe6d8..0000000000 --- a/erpnext/www/lms/profile.html +++ /dev/null @@ -1,64 +0,0 @@ -{% extends "templates/base.html" %} -{% block title %}Profile{% endblock %} -{% from "www/lms/macros/hero.html" import hero %} - -{% block head_include %} - -{% endblock %} - -{% macro card(program) %} - -{% endmacro %} - -{% block content %} -
-
- -

{{ student.first_name }} {{ student.last_name or '' }}

-

{{ student.name }}

-
-
-
- {% for program in progress %} - {{ card(program) }} - {% endfor %} -
-
-
-{% endblock %} diff --git a/erpnext/www/lms/profile.py b/erpnext/www/lms/profile.py deleted file mode 100644 index c4c1cd78eb..0000000000 --- a/erpnext/www/lms/profile.py +++ /dev/null @@ -1,37 +0,0 @@ -import frappe - -import erpnext.education.utils as utils - -no_cache = 1 - - -def get_context(context): - if frappe.session.user == "Guest": - frappe.local.flags.redirect_location = "/lms" - raise frappe.Redirect - - context.student = utils.get_current_student() - if not context.student: - context.student = frappe.get_doc("User", frappe.session.user) - context.progress = get_program_progress(context.student.name) - - -def get_program_progress(student): - enrolled_programs = frappe.get_all( - "Program Enrollment", filters={"student": student}, fields=["program"] - ) - student_progress = [] - for list_item in enrolled_programs: - program = frappe.get_doc("Program", list_item.program) - progress = utils.get_program_progress(program) - completion = utils.get_program_completion(program) - student_progress.append( - { - "program": program.program_name, - "name": program.name, - "progress": progress, - "completion": completion, - } - ) - - return student_progress diff --git a/erpnext/www/lms/program.html b/erpnext/www/lms/program.html deleted file mode 100644 index 30528c667d..0000000000 --- a/erpnext/www/lms/program.html +++ /dev/null @@ -1,87 +0,0 @@ -{% extends "templates/base.html" %} -{% block title %}{{ program.program_name }}{% endblock %} -{% from "www/lms/macros/hero.html" import hero %} -{% from "www/lms/macros/card.html" import null_card %} - -{% block head_include %} - -{% endblock %} - - -{% macro card(course) %} - -{% endmacro %} - -{% block content %} -
- {{ hero(program.program_name, program.description, has_access, {'name': 'Home', 'url': '/lms'}) }} -
-
- {% for course in courses %} - {{ card(course) }} - {% endfor %} - {% if courses %} - {% for n in range( (3 - (courses|length)) %3) %} - {{ null_card() }} - {% endfor %} - {% endif %} -
-
-
-{% endblock %} diff --git a/erpnext/www/lms/program.py b/erpnext/www/lms/program.py deleted file mode 100644 index 1df2aa5bac..0000000000 --- a/erpnext/www/lms/program.py +++ /dev/null @@ -1,32 +0,0 @@ -import frappe -from frappe import _ - -import erpnext.education.utils as utils - -no_cache = 1 - - -def get_context(context): - try: - program = frappe.form_dict["program"] - except KeyError: - frappe.local.flags.redirect_location = "/lms" - raise frappe.Redirect - - context.education_settings = frappe.get_single("Education Settings") - context.program = get_program(program) - context.courses = [frappe.get_doc("Course", course.course) for course in context.program.courses] - context.has_access = utils.allowed_program_access(program) - context.progress = get_course_progress(context.courses, context.program) - - -def get_program(program_name): - try: - return frappe.get_doc("Program", program_name) - except frappe.DoesNotExistError: - frappe.throw(_("Program {0} does not exist.").format(program_name)) - - -def get_course_progress(courses, program): - progress = {course.name: utils.get_course_progress(course, program) for course in courses} - return progress or {} diff --git a/erpnext/www/lms/topic.html b/erpnext/www/lms/topic.html deleted file mode 100644 index dc69599112..0000000000 --- a/erpnext/www/lms/topic.html +++ /dev/null @@ -1,58 +0,0 @@ -{% extends "templates/base.html" %} -{% block title %}{{ topic.name }}{% endblock %} -{% from "www/lms/macros/hero.html" import hero %} -{% from "www/lms/macros/card.html" import null_card %} - -{% block head_include %} - -{% endblock %} - - -{% macro card(content, index, length) %} - -{% endmacro %} - -{% block content %} -
- {{ hero(topic.topic_name, topic.description, has_access, {'name': 'Course', 'url': '/lms/course?name=' + course +'&program=' + program}) }} -
-
- {% for content in contents %} - {{ card(content, loop.index, topic.contents|length) }} - {% endfor %} - {% if contents %} - {% for n in range( (3 - (contents|length)) %3) %} - {{ null_card() }} - {% endfor %} - {% endif %} -
-
-
-{% endblock %} diff --git a/erpnext/www/lms/topic.py b/erpnext/www/lms/topic.py deleted file mode 100644 index 7783211a41..0000000000 --- a/erpnext/www/lms/topic.py +++ /dev/null @@ -1,57 +0,0 @@ -import frappe - -import erpnext.education.utils as utils - -no_cache = 1 - - -def get_context(context): - try: - course = frappe.form_dict["course"] - program = frappe.form_dict["program"] - topic = frappe.form_dict["topic"] - except KeyError: - frappe.local.flags.redirect_location = "/lms" - raise frappe.Redirect - - context.program = program - context.course = course - context.topic = frappe.get_doc("Topic", topic) - context.contents = get_contents(context.topic, course, program) - context.has_access = utils.allowed_program_access(program) - - -def get_contents(topic, course, program): - student = utils.get_current_student() - if student: - course_enrollment = utils.get_or_create_course_enrollment(course, program) - contents = topic.get_contents() - progress = [] - if contents: - for content in contents: - if content.doctype in ("Article", "Video"): - if student: - status = utils.check_content_completion(content.name, content.doctype, course_enrollment.name) - else: - status = True - progress.append({"content": content, "content_type": content.doctype, "completed": status}) - elif content.doctype == "Quiz": - if student: - status, score, result, time_taken = utils.check_quiz_completion( - content, course_enrollment.name - ) - else: - status = False - score = None - result = None - progress.append( - { - "content": content, - "content_type": content.doctype, - "completed": status, - "score": score, - "result": result, - } - ) - - return progress From 3c7176d69010485a368e32cf2d84588e180ad788 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Thu, 28 Apr 2022 11:07:02 +0530 Subject: [PATCH 082/106] fix: Update links to Frappe Cloud (#30833) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f8f5f80b34..cea3472447 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ ERPNext is built on the [Frappe Framework](https://github.com/frappe/frappe), a ## Installation
- + From 60b693f84f873278921852106e11b0622f9283a8 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 28 Apr 2022 12:02:54 +0530 Subject: [PATCH 083/106] chore: clean up hooks --- erpnext/config/education.py | 192 ------------- erpnext/hooks.py | 64 +---- erpnext/modules.txt | 1 - .../v11_0/set_department_for_doctypes.py | 1 - erpnext/projects/doctype/project/project.py | 6 +- erpnext/public/js/erpnext.bundle.js | 1 - erpnext/public/js/setup_wizard.js | 14 +- .../operations/install_fixtures.py | 1 - .../erpnext_settings/erpnext_settings.json | 18 +- erpnext/tests/ui/agriculture.txt | 7 - erpnext/tests/ui/make_fixtures.js | 258 ------------------ erpnext/tests/ui/setup_wizard.js | 47 ---- erpnext/tests/ui/tests.txt | 110 -------- erpnext/tests/ui/tests2.txt | 46 ---- erpnext/utilities/activation.py | 18 -- 15 files changed, 10 insertions(+), 774 deletions(-) delete mode 100644 erpnext/config/education.py delete mode 100644 erpnext/tests/ui/agriculture.txt delete mode 100644 erpnext/tests/ui/make_fixtures.js delete mode 100644 erpnext/tests/ui/setup_wizard.js delete mode 100644 erpnext/tests/ui/tests.txt delete mode 100644 erpnext/tests/ui/tests2.txt diff --git a/erpnext/config/education.py b/erpnext/config/education.py deleted file mode 100644 index c37cf2b196..0000000000 --- a/erpnext/config/education.py +++ /dev/null @@ -1,192 +0,0 @@ -from frappe import _ - - -def get_data(): - return [ - { - "label": _("Student"), - "items": [ - { - "type": "doctype", - "name": "Student", - "onboard": 1, - }, - {"type": "doctype", "name": "Guardian"}, - {"type": "doctype", "name": "Student Log"}, - {"type": "doctype", "name": "Student Group"}, - ], - }, - { - "label": _("Admission"), - "items": [ - {"type": "doctype", "name": "Student Applicant"}, - {"type": "doctype", "name": "Web Academy Applicant"}, - {"type": "doctype", "name": "Student Admission"}, - {"type": "doctype", "name": "Program Enrollment"}, - ], - }, - { - "label": _("Attendance"), - "items": [ - {"type": "doctype", "name": "Student Attendance"}, - {"type": "doctype", "name": "Student Leave Application"}, - { - "type": "report", - "is_query_report": True, - "name": "Absent Student Report", - "doctype": "Student Attendance", - }, - { - "type": "report", - "is_query_report": True, - "name": "Student Batch-Wise Attendance", - "doctype": "Student Attendance", - }, - ], - }, - { - "label": _("Tools"), - "items": [ - {"type": "doctype", "name": "Student Attendance Tool"}, - {"type": "doctype", "name": "Assessment Result Tool"}, - {"type": "doctype", "name": "Student Group Creation Tool"}, - {"type": "doctype", "name": "Program Enrollment Tool"}, - {"type": "doctype", "name": "Course Scheduling Tool"}, - ], - }, - { - "label": _("Assessment"), - "items": [ - {"type": "doctype", "name": "Assessment Plan"}, - { - "type": "doctype", - "name": "Assessment Group", - "link": "Tree/Assessment Group", - }, - {"type": "doctype", "name": "Assessment Result"}, - {"type": "doctype", "name": "Assessment Criteria"}, - ], - }, - { - "label": _("Assessment Reports"), - "items": [ - { - "type": "report", - "is_query_report": True, - "name": "Course wise Assessment Report", - "doctype": "Assessment Result", - }, - { - "type": "report", - "is_query_report": True, - "name": "Final Assessment Grades", - "doctype": "Assessment Result", - }, - { - "type": "report", - "is_query_report": True, - "name": "Assessment Plan Status", - "doctype": "Assessment Plan", - }, - {"type": "doctype", "name": "Student Report Generation Tool"}, - ], - }, - { - "label": _("Fees"), - "items": [ - {"type": "doctype", "name": "Fees"}, - {"type": "doctype", "name": "Fee Schedule"}, - {"type": "doctype", "name": "Fee Structure"}, - {"type": "doctype", "name": "Fee Category"}, - ], - }, - { - "label": _("Schedule"), - "items": [ - {"type": "doctype", "name": "Course Schedule", "route": "/app/List/Course Schedule/Calendar"}, - {"type": "doctype", "name": "Course Scheduling Tool"}, - ], - }, - { - "label": _("Masters"), - "items": [ - { - "type": "doctype", - "name": "Program", - }, - { - "type": "doctype", - "name": "Course", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Topic", - }, - { - "type": "doctype", - "name": "Instructor", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Room", - "onboard": 1, - }, - ], - }, - { - "label": _("Content Masters"), - "items": [ - {"type": "doctype", "name": "Article"}, - {"type": "doctype", "name": "Video"}, - {"type": "doctype", "name": "Quiz"}, - ], - }, - { - "label": _("LMS Activity"), - "items": [ - {"type": "doctype", "name": "Course Enrollment"}, - {"type": "doctype", "name": "Course Activity"}, - {"type": "doctype", "name": "Quiz Activity"}, - ], - }, - { - "label": _("Settings"), - "items": [ - {"type": "doctype", "name": "Student Category"}, - {"type": "doctype", "name": "Student Batch Name"}, - { - "type": "doctype", - "name": "Grading Scale", - "onboard": 1, - }, - {"type": "doctype", "name": "Academic Term"}, - {"type": "doctype", "name": "Academic Year"}, - {"type": "doctype", "name": "Education Settings"}, - ], - }, - { - "label": _("Other Reports"), - "items": [ - { - "type": "report", - "is_query_report": True, - "name": "Student and Guardian Contact Details", - "doctype": "Program Enrollment", - }, - { - "type": "report", - "is_query_report": True, - "name": "Student Monthly Attendance Sheet", - "doctype": "Student Attendance", - }, - { - "type": "report", - "name": "Student Fee Collection", - "doctype": "Fees", - "is_query_report": True, - }, - ], - }, - ] diff --git a/erpnext/hooks.py b/erpnext/hooks.py index e1785626ee..14a2f15c17 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -79,25 +79,16 @@ calendars = [ "Leave Application", "Sales Order", "Holiday List", - "Course Schedule", ] domains = { "Distribution": "erpnext.domains.distribution", - "Education": "erpnext.domains.education", "Manufacturing": "erpnext.domains.manufacturing", "Retail": "erpnext.domains.retail", "Services": "erpnext.domains.services", } -website_generators = [ - "Item Group", - "Website Item", - "BOM", - "Sales Partner", - "Job Opening", - "Student Admission", -] +website_generators = ["Item Group", "Website Item", "BOM", "Sales Partner", "Job Opening"] website_context = { "favicon": "/assets/erpnext/images/erpnext-favicon.svg", @@ -181,7 +172,6 @@ website_route_rules = [ "defaults": {"doctype": "Address", "parents": [{"label": _("Addresses"), "route": "addresses"}]}, }, {"from_route": "/jobs", "to_route": "Job Opening"}, - {"from_route": "/admissions", "to_route": "Student Admission"}, {"from_route": "/boms", "to_route": "BOM"}, {"from_route": "/timesheets", "to_route": "Timesheet"}, {"from_route": "/material-requests", "to_route": "Material Request"}, @@ -254,14 +244,7 @@ standard_portal_menu_items = [ "reference_doctype": "Timesheet", "role": "Customer", }, - {"title": _("Fees"), "route": "/fees", "reference_doctype": "Fees", "role": "Student"}, {"title": _("Newsletter"), "route": "/newsletters", "reference_doctype": "Newsletter"}, - { - "title": _("Admission"), - "route": "/admissions", - "reference_doctype": "Student Admission", - "role": "Student", - }, { "title": _("Material Request"), "route": "/material-requests", @@ -274,7 +257,6 @@ standard_portal_menu_items = [ default_roles = [ {"role": "Customer", "doctype": "Contact", "email_field": "email_id"}, {"role": "Supplier", "doctype": "Contact", "email_field": "email_id"}, - {"role": "Student", "doctype": "Student", "email_field": "student_email_id"}, ] sounds = [ @@ -538,8 +520,6 @@ accounting_dimension_doctypes = [ "Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", - "Fee Schedule", - "Fee Structure", "Stock Reconciliation", "Travel Request", "Fees", @@ -645,48 +625,6 @@ global_search_doctypes = { {"doctype": "Maintenance Visit", "index": 46}, {"doctype": "Warranty Claim", "index": 47}, ], - "Education": [ - {"doctype": "Article", "index": 1}, - {"doctype": "Video", "index": 2}, - {"doctype": "Topic", "index": 3}, - {"doctype": "Course", "index": 4}, - {"doctype": "Program", "index": 5}, - {"doctype": "Quiz", "index": 6}, - {"doctype": "Question", "index": 7}, - {"doctype": "Fee Schedule", "index": 8}, - {"doctype": "Fee Structure", "index": 9}, - {"doctype": "Fees", "index": 10}, - {"doctype": "Student Group", "index": 11}, - {"doctype": "Student", "index": 12}, - {"doctype": "Instructor", "index": 13}, - {"doctype": "Course Activity", "index": 14}, - {"doctype": "Quiz Activity", "index": 15}, - {"doctype": "Course Enrollment", "index": 16}, - {"doctype": "Program Enrollment", "index": 17}, - {"doctype": "Student Language", "index": 18}, - {"doctype": "Student Applicant", "index": 19}, - {"doctype": "Assessment Result", "index": 20}, - {"doctype": "Assessment Plan", "index": 21}, - {"doctype": "Grading Scale", "index": 22}, - {"doctype": "Guardian", "index": 23}, - {"doctype": "Student Leave Application", "index": 24}, - {"doctype": "Student Log", "index": 25}, - {"doctype": "Room", "index": 26}, - {"doctype": "Course Schedule", "index": 27}, - {"doctype": "Student Attendance", "index": 28}, - {"doctype": "Announcement", "index": 29}, - {"doctype": "Student Category", "index": 30}, - {"doctype": "Assessment Group", "index": 31}, - {"doctype": "Student Batch Name", "index": 32}, - {"doctype": "Assessment Criteria", "index": 33}, - {"doctype": "Academic Year", "index": 34}, - {"doctype": "Academic Term", "index": 35}, - {"doctype": "School House", "index": 36}, - {"doctype": "Student Admission", "index": 37}, - {"doctype": "Fee Category", "index": 38}, - {"doctype": "Assessment Code", "index": 39}, - {"doctype": "Discussion", "index": 40}, - ], } additional_timeline_content = { diff --git a/erpnext/modules.txt b/erpnext/modules.txt index c6b3159e0f..869166b939 100644 --- a/erpnext/modules.txt +++ b/erpnext/modules.txt @@ -12,7 +12,6 @@ Utilities Assets Portal Maintenance -Education Regional ERPNext Integrations Quality Management diff --git a/erpnext/patches/v11_0/set_department_for_doctypes.py b/erpnext/patches/v11_0/set_department_for_doctypes.py index 1e14b9ceb0..4900458e10 100644 --- a/erpnext/patches/v11_0/set_department_for_doctypes.py +++ b/erpnext/patches/v11_0/set_department_for_doctypes.py @@ -19,7 +19,6 @@ def execute(): "Training Event Employee", "Payroll Employee Detail", ], - "education": ["Instructor"], "projects": ["Activity Cost", "Timesheet"], "setup": ["Sales Person"], } diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index a97efffec8..6ea1343e0b 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -9,11 +9,12 @@ from frappe.desk.reportview import get_match_cond from frappe.model.document import Document from frappe.utils import add_days, flt, get_datetime, get_time, get_url, nowtime, today +from erpnext import get_default_company from erpnext.controllers.employee_boarding_controller import update_employee_boarding_status from erpnext.controllers.queries import get_filters_cond from erpnext.hr.doctype.daily_work_summary.daily_work_summary import get_users_email from erpnext.hr.doctype.holiday_list.holiday_list import is_holiday -from erpnext import get_default_company + class Project(Document): def get_feed(self): @@ -665,6 +666,7 @@ def set_project_status(project, status): project.status = status project.save() + def get_holiday_list(company=None): if not company: company = get_default_company() or frappe.get_all("Company")[0].name @@ -676,4 +678,4 @@ def get_holiday_list(company=None): frappe.bold(get_default_company()) ) ) - return holiday_list \ No newline at end of file + return holiday_list diff --git a/erpnext/public/js/erpnext.bundle.js b/erpnext/public/js/erpnext.bundle.js index 3baf66784f..3dae6d407b 100644 --- a/erpnext/public/js/erpnext.bundle.js +++ b/erpnext/public/js/erpnext.bundle.js @@ -16,7 +16,6 @@ import "./templates/item_quick_entry.html"; import "./utils/item_quick_entry"; import "./utils/customer_quick_entry"; import "./utils/supplier_quick_entry"; -import "./education/assessment_result_tool.html"; import "./call_popup/call_popup"; import "./utils/dimension_tree_filter"; import "./utils/barcode_scanner"; diff --git a/erpnext/public/js/setup_wizard.js b/erpnext/public/js/setup_wizard.js index 83b69aebc5..2173c2d4de 100644 --- a/erpnext/public/js/setup_wizard.js +++ b/erpnext/public/js/setup_wizard.js @@ -23,7 +23,6 @@ erpnext.setup.slides_settings = [ fieldtype: 'MultiCheck', options: [ { "label": __("Distribution"), "value": "Distribution" }, - { "label": __("Education"), "value": "Education" }, { "label": __("Manufacturing"), "value": "Manufacturing" }, { "label": __("Retail"), "value": "Retail" }, { "label": __("Services"), "value": "Services" }, @@ -59,15 +58,13 @@ erpnext.setup.slides_settings = [ }, { fieldname: 'company_name', - label: frappe.setup.domains.includes('Education') ? - __('Institute Name') : __('Company Name'), + label: __('Company Name'), fieldtype: 'Data', reqd: 1 }, { fieldname: 'company_abbr', - label: frappe.setup.domains.includes('Education') ? - __('Institute Abbreviation') : __('Company Abbreviation'), + label: __('Company Abbreviation'), fieldtype: 'Data' } ], @@ -107,17 +104,12 @@ erpnext.setup.slides_settings = [ name: 'organisation', title: __("Your Organization"), icon: "fa fa-building", - // help: frappe.setup.domains.includes('Education') ? - // __('The name of the institute for which you are setting up this system.') : - // __('The name of your company for which you are setting up this system.')), fields: [ { fieldname: 'company_tagline', label: __('What does it do?'), fieldtype: 'Data', - placeholder: frappe.setup.domains.includes('Education') ? - __('e.g. "Primary School" or "University"') : - __('e.g. "Build tools for builders"'), + placeholder: __('e.g. "Build tools for builders"'), reqd: 1 }, { fieldname: 'bank_account', label: __('Bank Name'), fieldtype: 'Data', reqd: 1 }, diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py index a0056e2112..e31c12671e 100644 --- a/erpnext/setup/setup_wizard/operations/install_fixtures.py +++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py @@ -48,7 +48,6 @@ def install(country=None): {"doctype": "Domain", "domain": "Manufacturing"}, {"doctype": "Domain", "domain": "Retail"}, {"doctype": "Domain", "domain": "Services"}, - {"doctype": "Domain", "domain": "Education"}, {"doctype": "Domain", "domain": "Healthcare"}, {"doctype": "Domain", "domain": "Non Profit"}, # ensure at least an empty Address Template exists for this Country diff --git a/erpnext/setup/workspace/erpnext_settings/erpnext_settings.json b/erpnext/setup/workspace/erpnext_settings/erpnext_settings.json index c5640bc079..eeb71c7709 100644 --- a/erpnext/setup/workspace/erpnext_settings/erpnext_settings.json +++ b/erpnext/setup/workspace/erpnext_settings/erpnext_settings.json @@ -1,7 +1,7 @@ { "charts": [], "content": "[{\"type\":\"header\",\"data\":{\"text\":\"Your Shortcuts\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Projects Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"HR Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Selling Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Buying Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Support Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Shopping Cart Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Portal Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Domain Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Products Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Naming Series\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Manufacturing Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Education Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Hotel Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"CRM Settings\",\"col\":3}}]", - "creation": "2020-03-12 14:47:51.166455", + "creation": "2022-01-27 13:14:47.349433", "docstatus": 0, "doctype": "Workspace", "for_user": "", @@ -10,7 +10,7 @@ "idx": 0, "label": "ERPNext Settings", "links": [], - "modified": "2022-01-13 19:18:59.362820", + "modified": "2022-04-28 11:42:01.043569", "modified_by": "Administrator", "module": "Setup", "name": "ERPNext Settings", @@ -90,20 +90,6 @@ "restrict_to_domain": "Manufacturing", "type": "DocType" }, - { - "icon": "education", - "label": "Education Settings", - "link_to": "Education Settings", - "restrict_to_domain": "Education", - "type": "DocType" - }, - { - "icon": "organization", - "label": "Hotel Settings", - "link_to": "Hotel Settings", - "restrict_to_domain": "Hospitality", - "type": "DocType" - }, { "icon": "setting", "label": "Domain Settings", diff --git a/erpnext/tests/ui/agriculture.txt b/erpnext/tests/ui/agriculture.txt deleted file mode 100644 index 4622bc0df3..0000000000 --- a/erpnext/tests/ui/agriculture.txt +++ /dev/null @@ -1,7 +0,0 @@ -erpnext/agriculture/doctype/land_unit/test_land_unit.js -erpnext/agriculture/doctype/fertilizer/test_fertilizer.js -erpnext/agriculture/doctype/water_analysis/test_water_analysis.js -erpnext/agriculture/doctype/disease/test_disease.js -erpnext/agriculture/doctype/soil_texture/test_soil_texture.js -erpnext/agriculture/doctype/crop/test_crop.js -erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.js \ No newline at end of file diff --git a/erpnext/tests/ui/make_fixtures.js b/erpnext/tests/ui/make_fixtures.js deleted file mode 100644 index 8c9e50884a..0000000000 --- a/erpnext/tests/ui/make_fixtures.js +++ /dev/null @@ -1,258 +0,0 @@ -$.extend(frappe.test_data, { - // "Fiscal Year": { - // "2017-18": [ - // {"year": "2017-18"}, - // {"year_start_date": "2017-04-01"}, - // {"year_end_date": "2018-03-31"}, - // ] - // }, - "Customer": { - "Test Customer 1": [ - {customer_name: "Test Customer 1"} - ], - "Test Customer 2": [ - {customer_name: "Test Customer 2"} - ], - "Test Customer 3": [ - {customer_name: "Test Customer 3"} - ], - }, - "Item": { - "Test Product 1": [ - {item_code: "Test Product 1"}, - {item_group: "Products"}, - {is_stock_item: 1}, - {standard_rate: 100}, - {opening_stock: 100}, - ], - "Test Product 2": [ - {item_code: "Test Product 2"}, - {item_group: "Products"}, - {is_stock_item: 1}, - {standard_rate: 150}, - {opening_stock: 200}, - ], - "Test Product 3": [ - {item_code: "Test Product 3"}, - {item_group: "Products"}, - {is_stock_item: 1}, - {standard_rate: 250}, - {opening_stock: 100}, - {stock_uom:'Kg'} - ], - "Test Service 1": [ - {item_code: "Test Service 1"}, - {item_group: "Services"}, - {is_stock_item: 0}, - {standard_rate: 200} - ], - "Test Service 2": [ - {item_code: "Test Service 2"}, - {item_group: "Services"}, - {is_stock_item: 0}, - {standard_rate: 300} - ] - }, - "Lead": { - "LEAD-00001": [ - {lead_name: "Test Lead 1"} - ], - "LEAD-00002": [ - {lead_name: "Test Lead 2"} - ], - "LEAD-00003": [ - {lead_name: "Test Lead 3"} - ] - }, - "Address": { - "Test1-Billing": [ - {address_title:"Test1"}, - {address_type: "Billing"}, - {address_line1: "Billing Street 1"}, - {city: "Billing City 1"}, - {links: [ - [ - {link_doctype: "Customer"}, - {link_name: "Test Customer 1"} - ] - ]} - ], - "Test1-Shipping": [ - {address_title:"Test1"}, - {address_type: "Shipping"}, - {address_line1: "Shipping Street 1"}, - {city: "Shipping City 1"}, - {links: [ - [ - {link_doctype: "Customer"}, - {link_name: "Test Customer 1"} - ] - ]} - ], - "Test1-Warehouse": [ - {address_title:"Test1"}, - {address_type: "Warehouse"}, - {address_line1: "Warehouse Street 1"}, - {city: "Warehouse City 1"}, - {links: [ - [ - {link_doctype: "Customer"}, - {link_name: "Test Customer 1"} - ] - ]} - ], - "Test2-Billing": [ - {address_title:"Test2"}, - {address_type: "Billing"}, - {address_line1: "Billing Street 2"}, - {city: "Billing City 2"}, - {links: [ - [ - {link_doctype: "Customer"}, - {link_name: "Test Customer 2"} - ] - ]} - ], - "Test2-Shipping": [ - {address_title:"Test2"}, - {address_type: "Shipping"}, - {address_line1: "Shipping Street 2"}, - {city: "Shipping City 2"}, - {links: [ - [ - {link_doctype: "Customer"}, - {link_name: "Test Customer 2"} - ] - ]} - ], - "Test2-Warehouse": [ - {address_title:"Test2"}, - {address_type: "Warehouse"}, - {address_line1: "Warehouse Street 2"}, - {city: "Warehouse City 2"}, - {links: [ - [ - {link_doctype: "Customer"}, - {link_name: "Test Customer 2"} - ] - ]} - ] - }, - "Contact": { - "Contact 1-Test Customer 1": [ - {first_name: "Contact 1"}, - {links: [ - [ - {link_doctype: "Customer"}, - {link_name: "Test Customer 1"} - ] - ]} - ], - "Contact 2-Test Customer 1": [ - {first_name: "Contact 2"}, - {links: [ - [ - {link_doctype: "Customer"}, - {link_name: "Test Customer 1"} - ] - ]} - ], - "Contact 1-Test Customer 2": [ - {first_name: "Contact 1"}, - {links: [ - [ - {link_doctype: "Customer"}, - {link_name: "Test Customer 2"} - ] - ]} - ], - "Contact 2-Test Customer 2": [ - {first_name: "Contact 2"}, - {links: [ - [ - {link_doctype: "Customer"}, - {link_name: "Test Customer 2"} - ] - ]} - ], - }, - "Price List": { - "Test-Buying-USD": [ - {price_list_name: "Test-Buying-USD"}, - {currency: "USD"}, - {buying: "1"} - ], - "Test-Buying-EUR": [ - {price_list_name: "Test-Buying-EUR"}, - {currency: "EUR"}, - {buying: "1"} - ], - "Test-Selling-USD": [ - {price_list_name: "Test-Selling-USD"}, - {currency: "USD"}, - {selling: "1"} - ], - "Test-Selling-EUR": [ - {price_list_name: "Test-Selling-EUR"}, - {currency: "EUR"}, - {selling: "1"} - ], - }, - "Terms and Conditions": { - "Test Term 1": [ - {title: "Test Term 1"} - ], - "Test Term 2": [ - {title: "Test Term 2"} - ] - }, - "Item Price": { - "ITEM-PRICE-00001": [ - {item_code: 'Test Product 1'}, - {price_list: '_Test Price List'}, - {price_list_rate: 100} - ], - "ITEM-PRICE-00002": [ - {item_code: 'Test Product 2'}, - {price_list: '_Test Price List'}, - {price_list_rate: 200} - ] - }, - "Payment Term": { - "_Test Payment Term": [ - {payment_term_name: '_Test Payment Term'}, - {due_date_based_on: 'Day(s) after invoice date'}, - {invoice_portion: 100}, - {credit_days: 0} - ] - }, - "Payment Terms Template": { - "_Test Payment Term Template UI": [ - {template_name: "_Test Payment Term Template UI"}, - {terms: [ - [ - {payment_term: '_Test Payment Term'}, - {invoice_portion: 100} - ] - ]} - ] - } -}); - - -// this is a script that creates all fixtures -// called as a test -QUnit.module('fixture'); - -QUnit.test('Make fixtures', assert => { - // create all fixtures first - assert.expect(0); - let done = assert.async(); - let tasks = []; - Object.keys(frappe.test_data).forEach(function(doctype) { - tasks.push(function() { - return frappe.tests.setup_doctype(doctype, frappe.test_data[doctype]); - }); - }); - frappe.run_serially(tasks).then(() => done()); -}); diff --git a/erpnext/tests/ui/setup_wizard.js b/erpnext/tests/ui/setup_wizard.js deleted file mode 100644 index ccff785ec9..0000000000 --- a/erpnext/tests/ui/setup_wizard.js +++ /dev/null @@ -1,47 +0,0 @@ -const path = require('path'); -const path_join = path.resolve; -const apps_path = path_join(__dirname, '..', '..', '..', '..'); -const frappe_ui_tests_path = path_join(apps_path, 'frappe', 'frappe', 'tests', 'ui'); - -const login = require(frappe_ui_tests_path + "/login.js")['Login']; -const welcome = require(frappe_ui_tests_path + "/setup_wizard.js")['Welcome']; -const region = require(frappe_ui_tests_path + "/setup_wizard.js")['Region']; -const user = require(frappe_ui_tests_path + "/setup_wizard.js")['User']; - -module.exports = { - before: browser => { - browser - .url(browser.launch_url + '/login') - .waitForElementVisible('body', 5000); - }, - 'Login': login, - 'Welcome': welcome, - 'Region': region, - 'User': user, - 'Domain': browser => { - let slide_selector = '[data-slide-name="domain"]'; - browser - .waitForElementVisible(slide_selector, 2000) - .setValue('select[data-fieldname="domain"]', "Manufacturing") - .click(slide_selector + ' .next-btn'); - }, - 'Brand': browser => { - let slide_selector = '[data-slide-name="brand"]'; - browser - .waitForElementVisible(slide_selector, 2000) - .setValue('input[data-fieldname="company_name"]', "Acme") - .click(slide_selector + " .next-btn"); - }, - 'Organisation': browser => { - let slide_selector = '[data-slide-name="organisation"]'; - browser - .waitForElementVisible(slide_selector, 2000) - .setValue('input[data-fieldname="company_tagline"]', "Build tools for Builders") - .setValue('input[data-fieldname="bank_account"]', "YNG") - .click(slide_selector + " .next-btn"); - }, - - after: browser => { - browser.end(); - }, -}; diff --git a/erpnext/tests/ui/tests.txt b/erpnext/tests/ui/tests.txt deleted file mode 100644 index 5e238e449e..0000000000 --- a/erpnext/tests/ui/tests.txt +++ /dev/null @@ -1,110 +0,0 @@ -erpnext/tests/ui/make_fixtures.js #long -erpnext/accounts/doctype/account/tests/test_account.js -erpnext/accounts/doctype/account/tests/test_make_tax_account.js -erpnext/accounts/doctype/account/tests/test_account_with_number.js -erpnext/accounts/doctype/pricing_rule/tests/test_pricing_rule.js -erpnext/accounts/doctype/sales_taxes_and_charges_template/test_sales_taxes_and_charges_template.js -erpnext/accounts/doctype/purchase_taxes_and_charges_template/test_purchase_taxes_and_charges_template.js -erpnext/accounts/doctype/shipping_rule/test_shipping_rule.js -erpnext/crm/doctype/opportunity/test_opportunity.js -erpnext/stock/doctype/item/tests/test_item.js -erpnext/selling/doctype/quotation/tests/test_quotation_with_discount_on_grand_total.js -erpnext/selling/doctype/quotation/tests/test_quotation_with_item_wise_discount.js -erpnext/selling/doctype/quotation/tests/test_quotation_with_multi_uom.js -erpnext/selling/doctype/quotation/tests/test_quotation_with_taxes_and_charges.js -erpnext/selling/doctype/quotation/tests/test_quotation_with_shipping_rule.js -erpnext/selling/doctype/quotation/tests/test_quotation.js -erpnext/selling/doctype/sales_order/tests/test_sales_order.js -erpnext/selling/doctype/sales_order/tests/test_sales_order_with_multiple_delivery_date.js -erpnext/selling/doctype/sales_order/tests/test_sales_order_with_item_wise_discount.js -erpnext/selling/doctype/sales_order/tests/test_sales_order_with_multi_uom.js -erpnext/selling/doctype/sales_order/tests/test_sales_order_with_discount_on_grand_total.js -erpnext/selling/doctype/sales_order/tests/test_sales_order_with_taxes_and_charges.js -erpnext/selling/doctype/sales_order/tests/test_sales_order_with_shipping_rule.js -erpnext/selling/doctype/sales_order/tests/test_sales_order_with_pricing_rule.js -erpnext/manufacturing/doctype/workstation/test_workstation.js -erpnext/manufacturing/doctype/operation/test_operation.js -erpnext/manufacturing/doctype/bom/test_bom.js -erpnext/projects/doctype/project/project_timesheet.js -erpnext/hr/doctype/holiday_list/test_holiday_list.js -erpnext/hr/doctype/branch/test_branch.js -erpnext/hr/doctype/leave_block_list/test_leave_block_list.js -erpnext/hr/doctype/department/test_department.js -erpnext/hr/doctype/designation/test_designation.js -erpnext/hr/doctype/employment_type/test_employment_type.js -erpnext/hr/doctype/employee/test_employee.js -erpnext/hr/doctype/employee_attendance_tool/test_employee_attendance_tool.js -erpnext/hr/doctype/attendance/test_attendance.js -erpnext/hr/doctype/leave_type/test_leave_type.js -erpnext/hr/doctype/leave_control_panel/test_leave_control_panel.js -erpnext/hr/doctype/leave_allocation/test_leave_allocation.js -erpnext/hr/doctype/leave_application/test_leave_application.js -erpnext/stock/doctype/warehouse/test_warehouse.js -erpnext/manufacturing/doctype/work_order/test_work_order.js #long -erpnext/accounts/page/pos/test_pos.js -erpnext/selling/page/point_of_sale/tests/test_point_of_sale.js -erpnext/selling/doctype/product_bundle/test_product_bundle.js -erpnext/stock/doctype/delivery_note/test_delivery_note.js -erpnext/stock/doctype/material_request/tests/test_material_request.js -erpnext/stock/doctype/material_request/tests/test_material_request_type_material_issue.js -erpnext/stock/doctype/material_request/tests/test_material_request_type_material_transfer.js -erpnext/stock/doctype/material_request/tests/test_material_request_type_manufacture.js -erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_issue.js -erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_receipt.js -erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer.js -erpnext/hr/doctype/salary_structure/test_salary_structure.js -erpnext/hr/doctype/salary_slip/test_salary_slip.js -erpnext/hr/doctype/job_opening/test_job_opening.js -erpnext/hr/doctype/job_applicant/test_job_applicant.js -erpnext/hr/doctype/job_offer/test_job_offer.js -erpnext/hr/doctype/appraisal_template/test_appraisal_template.js -erpnext/hr/doctype/appraisal/test_appraisal.js -erpnext/hr/doctype/expense_claim_type/test_expense_claim_type.js -erpnext/hr/doctype/expense_claim/test_expense_claim.js -erpnext/hr/doctype/training_event/tests/test_training_event.js -erpnext/hr/doctype/training_result_employee/test_training_result.js -erpnext/hr/doctype/training_feedback/test_training_feedback.js -erpnext/hr/doctype/loan_type/test_loan_type.js -erpnext/hr/doctype/loan_application/test_loan_application.js -erpnext/hr/doctype/loan/test_loan.js -erpnext/buying/doctype/supplier/test_supplier.js -erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation.js -erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation.js -erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation_for_taxes_and_charges.js -erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice.js -erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_payment.js -erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_payment_request.js -erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.js -erpnext/accounts/doctype/payment_entry/tests/test_payment_against_purchase_invoice.js -erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation_for_item_wise_discount.js -erpnext/buying/doctype/purchase_order/tests/test_purchase_order.js -erpnext/buying/doctype/purchase_order/tests/test_purchase_order_with_multi_uom.js -erpnext/buying/doctype/purchase_order/tests/test_purchase_order_get_items.js -erpnext/buying/doctype/purchase_order/tests/test_purchase_order_with_discount_on_grand_total.js -erpnext/buying/doctype/purchase_order/tests/test_purchase_order_with_item_wise_discount.js -erpnext/buying/doctype/purchase_order/tests/test_purchase_order_with_taxes_and_charges.js -erpnext/buying/doctype/purchase_order/tests/test_purchase_order_receipt.js -erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.js -erpnext/accounts/doctype/journal_entry/test_journal_entry.js -erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.js -erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js -erpnext/selling/doctype/quotation/tests/test_quotation_submit_cancel_amend.js -erpnext/stock/doctype/batch/test_batch.js -erpnext/accounts/doctype/bank_reconciliation/test_bank_reconciliation.js -erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_receipt_for_serialize_item.js -erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer_for_manufacture.js -erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_subcontract.js -erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_issue_with_serialize_item.js -erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_repack.js -erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_serialize_item.js -erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js -erpnext/buying/doctype/purchase_order/tests/test_purchase_order_with_last_purchase_rate.js -erpnext/stock/doctype/item_price/test_item_price.js -erpnext/stock/doctype/delivery_note/test_delivery_note_with_margin.js -erpnext/selling/doctype/sales_order/tests/test_sales_order_with_margin.js -erpnext/selling/doctype/quotation/tests/test_quotation_with_margin.js -erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_margin.js -erpnext/hr/doctype/payroll_entry/test_set_salary_components.js -erpnext/hr/doctype/payroll_entry/test_payroll_entry.js -erpnext/accounts/doctype/pricing_rule/tests/test_pricing_rule_with_same_currency.js -erpnext/accounts/doctype/pricing_rule/tests/test_pricing_rule_with_different_currency.js \ No newline at end of file diff --git a/erpnext/tests/ui/tests2.txt b/erpnext/tests/ui/tests2.txt deleted file mode 100644 index e410a83b2e..0000000000 --- a/erpnext/tests/ui/tests2.txt +++ /dev/null @@ -1,46 +0,0 @@ -erpnext/setup/doctype/company/tests/test_company.js -erpnext/crm/doctype/lead/tests/test_lead_individual.js -erpnext/crm/doctype/lead/tests/test_lead_organization.js -erpnext/setup/doctype/company/tests/test_company_production.js -erpnext/hr/doctype/leave_block_list/test_leave_block_list.js -erpnext/hr/doctype/department/test_department.js -erpnext/hr/doctype/designation/test_designation.js -erpnext/education/doctype/academic_year/test_academic_year.js -erpnext/education/doctype/academic_term/test_academic_term.js -erpnext/education/doctype/education_settings/test_education_settings.js -erpnext/education/doctype/student_batch_name/test_student_batch_name.js -erpnext/education/doctype/student_category/test_student_category.js -erpnext/education/doctype/room/test_room.js -erpnext/education/doctype/instructor/test_instructor.js -erpnext/education/doctype/grading_scale/test_grading_scale.js -erpnext/education/doctype/assessment_criteria_group/test_assessment_criteria_group.js -erpnext/education/doctype/assessment_criteria/test_assessment_criteria.js -erpnext/education/doctype/course/test_course.js -erpnext/education/doctype/program/test_program.js -erpnext/education/doctype/guardian/test_guardian.js -erpnext/education/doctype/student_admission/test_student_admission.js -erpnext/education/doctype/student_applicant/tests/test_student_applicant_dummy_data.js -erpnext/education/doctype/student_applicant/tests/test_student_applicant.js -erpnext/education/doctype/student_applicant/tests/test_student_applicant_options.js -erpnext/education/doctype/student_log/test_student_log.js -erpnext/education/doctype/student_group/test_student_group.js -erpnext/education/doctype/student_group_creation_tool/test_student_group_creation_tool.js -erpnext/education/doctype/student_leave_application/test_student_leave_application.js -erpnext/education/doctype/student_attendance_tool/test_student_attendance_tool.js -erpnext/education/doctype/student_attendance/test_student_attendance.js -erpnext/education/doctype/assessment_group/test_assessment_group.js -erpnext/education/doctype/assessment_plan/test_assessment_plan.js -erpnext/education/doctype/assessment_result/test_assessment_result.js -erpnext/education/doctype/assessment_result_tool/test_assessment_result_tool.js -erpnext/projects/doctype/task/tests/test_task_tree.js -erpnext/restaurant/doctype/restaurant/test_restaurant.js -erpnext/restaurant/doctype/restaurant_table/test_restaurant_table.js -erpnext/restaurant/doctype/restaurant_menu/test_restaurant_menu.js -erpnext/restaurant/doctype/restaurant_order_entry/restaurant_order_entry.js -erpnext/non_profit/doctype/membership_type/test_membership_type.js -erpnext/non_profit/doctype/member/test_member.js -erpnext/non_profit/doctype/volunteer_type/test_volunteer_type.js -erpnext/non_profit/doctype/volunteer/test_volunteer.js -erpnext/non_profit/doctype/donor_type/test_donor_type.js -erpnext/non_profit/doctype/donor/test_donor.js -erpnext/non_profit/doctype/grant_application/test_grant_application.js \ No newline at end of file diff --git a/erpnext/utilities/activation.py b/erpnext/utilities/activation.py index 43af0dc3c1..d2f6bd9322 100644 --- a/erpnext/utilities/activation.py +++ b/erpnext/utilities/activation.py @@ -136,24 +136,6 @@ def get_help_messages(): domain=("Services",), target=5, ), - frappe._dict( - doctype="Student", - title=_("Add Students"), - description=_("Students are at the heart of the system, add all your students"), - action=_("Create Student"), - route="List/Student", - domain=("Education",), - target=5, - ), - frappe._dict( - doctype="Student Batch", - title=_("Group your students in batches"), - description=_("Student Batches help you track attendance, assessments and fees for students"), - action=_("Create Student Batch"), - route="List/Student Batch", - domain=("Education",), - target=3, - ), frappe._dict( doctype="Employee", title=_("Create Employee Records"), From 8dcbbf1b9ebf8f0f070b30c224b59592bac8b450 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 28 Apr 2022 13:49:34 +0530 Subject: [PATCH 084/106] chore: Remove course links from training doctypes --- .../training_event/training_event.json | 1015 ++++------------- .../training_feedback/training_feedback.json | 7 +- .../includes/assessment/assessment_row.html | 19 - .../templates/includes/course/course_row.html | 18 - erpnext/templates/includes/course/macros.html | 1 - 5 files changed, 201 insertions(+), 859 deletions(-) delete mode 100644 erpnext/templates/includes/assessment/assessment_row.html delete mode 100644 erpnext/templates/includes/course/course_row.html delete mode 100644 erpnext/templates/includes/course/macros.html diff --git a/erpnext/hr/doctype/training_event/training_event.json b/erpnext/hr/doctype/training_event/training_event.json index fcf845a587..42e02ca3bf 100644 --- a/erpnext/hr/doctype/training_event/training_event.json +++ b/erpnext/hr/doctype/training_event/training_event.json @@ -1,850 +1,231 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:event_name", - "beta": 0, - "creation": "2016-08-08 04:53:58.355206", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, + "actions": [], + "allow_import": 1, + "allow_rename": 1, + "autoname": "field:event_name", + "creation": "2016-08-08 04:53:58.355206", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "event_name", + "training_program", + "event_status", + "has_certificate", + "column_break_2", + "type", + "level", + "company", + "section_break_4", + "trainer_name", + "trainer_email", + "column_break_7", + "supplier", + "contact_number", + "section_break_9", + "course", + "location", + "column_break_12", + "start_time", + "end_time", + "section_break_15", + "introduction", + "section_break_18", + "employees", + "amended_from", + "employee_emails" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "event_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Event Name", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "event_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Event Name", + "no_copy": 1, + "reqd": 1, + "unique": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "training_program", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Training Program", - "length": 0, - "no_copy": 0, - "options": "Training Program", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "training_program", + "fieldtype": "Link", + "label": "Training Program", + "options": "Training Program" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "event_status", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Event Status", - "length": 0, - "no_copy": 0, - "options": "Scheduled\nCompleted\nCancelled", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "allow_on_submit": 1, + "fieldname": "event_status", + "fieldtype": "Select", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Event Status", + "options": "Scheduled\nCompleted\nCancelled", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.type == 'Seminar' || doc.type == 'Workshop' || doc.type == 'Conference' || doc.type == 'Exam'", - "fieldname": "has_certificate", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Has Certificate", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "default": "0", + "depends_on": "eval:doc.type == 'Seminar' || doc.type == 'Workshop' || doc.type == 'Conference' || doc.type == 'Exam'", + "fieldname": "has_certificate", + "fieldtype": "Check", + "label": "Has Certificate" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_2", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "column_break_2", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "type", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Type", - "length": 0, - "no_copy": 0, - "options": "Seminar\nTheory\nWorkshop\nConference\nExam\nInternet\nSelf-Study", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "type", + "fieldtype": "Select", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Type", + "options": "Seminar\nTheory\nWorkshop\nConference\nExam\nInternet\nSelf-Study", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.type == 'Seminar' || doc.type == 'Workshop' || doc.type == 'Exam'", - "fieldname": "level", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Level", - "length": 0, - "no_copy": 0, - "options": "\nBeginner\nIntermediate\nAdvance", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "depends_on": "eval:doc.type == 'Seminar' || doc.type == 'Workshop' || doc.type == 'Exam'", + "fieldname": "level", + "fieldtype": "Select", + "label": "Level", + "options": "\nBeginner\nIntermediate\nAdvance" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "company", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Company", - "length": 0, - "no_copy": 0, - "options": "Company", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "company", + "fieldtype": "Link", + "label": "Company", + "options": "Company" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_4", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "section_break_4", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "trainer_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Trainer Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "trainer_name", + "fieldtype": "Data", + "label": "Trainer Name" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "trainer_email", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Trainer Email", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "trainer_email", + "fieldtype": "Data", + "label": "Trainer Email" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_7", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "column_break_7", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "supplier", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Supplier", - "length": 0, - "no_copy": 0, - "options": "Supplier", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "supplier", + "fieldtype": "Link", + "label": "Supplier", + "options": "Supplier" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "contact_number", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Contact Number", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "contact_number", + "fieldtype": "Data", + "label": "Contact Number" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_9", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "section_break_9", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "course", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 1, - "label": "Course", - "length": 0, - "no_copy": 0, - "options": "Course", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "course", + "fieldtype": "Data", + "in_standard_filter": 1, + "label": "Course" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "location", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Location", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "location", + "fieldtype": "Data", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Location", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_12", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "column_break_12", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "start_time", - "fieldtype": "Datetime", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Start Time", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "start_time", + "fieldtype": "Datetime", + "label": "Start Time", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "end_time", - "fieldtype": "Datetime", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "End Time", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "end_time", + "fieldtype": "Datetime", + "label": "End Time", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_15", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "section_break_15", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "introduction", - "fieldtype": "Text Editor", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Introduction", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "introduction", + "fieldtype": "Text Editor", + "label": "Introduction", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_18", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Attendees", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "section_break_18", + "fieldtype": "Section Break", + "label": "Attendees" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "employees", - "fieldtype": "Table", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Employees", - "length": 0, - "no_copy": 0, - "options": "Training Event Employee", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "allow_on_submit": 1, + "fieldname": "employees", + "fieldtype": "Table", + "label": "Employees", + "options": "Training Event Employee" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amended_from", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Amended From", - "length": 0, - "no_copy": 1, - "options": "Training Event", - "permlevel": 0, - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "amended_from", + "fieldtype": "Link", + "label": "Amended From", + "no_copy": 1, + "options": "Training Event", + "print_hide": 1, + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "employee_emails", - "fieldtype": "Small Text", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Employee Emails", - "length": 0, - "no_copy": 0, - "options": "Email", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 + "fieldname": "employee_emails", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Employee Emails", + "options": "Email" } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 1, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-03-12 10:56:29.065781", - "modified_by": "Administrator", - "module": "HR", - "name": "Training Event", - "name_case": "", - "owner": "Administrator", + ], + "is_submittable": 1, + "links": [], + "modified": "2022-04-28 13:29:35.139497", + "modified_by": "Administrator", + "module": "HR", + "name": "Training Event", + "naming_rule": "By fieldname", + "owner": "Administrator", "permissions": [ { - "amend": 1, - "apply_user_permissions": 0, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "import": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR Manager", + "share": 1, + "submit": 1, "write": 1 } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "search_fields": "event_name", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "event_name", - "track_changes": 0, - "track_seen": 0 -} + ], + "search_fields": "event_name", + "show_name_in_global_search": 1, + "sort_field": "modified", + "sort_order": "DESC", + "states": [], + "title_field": "event_name" +} \ No newline at end of file diff --git a/erpnext/hr/doctype/training_feedback/training_feedback.json b/erpnext/hr/doctype/training_feedback/training_feedback.json index ebf5a506f0..e968911776 100644 --- a/erpnext/hr/doctype/training_feedback/training_feedback.json +++ b/erpnext/hr/doctype/training_feedback/training_feedback.json @@ -1,7 +1,7 @@ { "actions": [], "autoname": "HR-TRF-.YYYY.-.#####", - "creation": "2016-08-08 06:35:34.158568", + "creation": "2022-01-27 13:14:35.935580", "doctype": "DocType", "editable_grid": 1, "engine": "InnoDB", @@ -46,9 +46,8 @@ { "fetch_from": "training_event.course", "fieldname": "course", - "fieldtype": "Link", + "fieldtype": "Data", "label": "Course", - "options": "Course", "read_only": 1 }, { @@ -101,7 +100,7 @@ ], "is_submittable": 1, "links": [], - "modified": "2022-01-18 19:32:20.805277", + "modified": "2022-04-28 13:32:29.261421", "modified_by": "Administrator", "module": "HR", "name": "Training Feedback", diff --git a/erpnext/templates/includes/assessment/assessment_row.html b/erpnext/templates/includes/assessment/assessment_row.html deleted file mode 100644 index a33ccffc36..0000000000 --- a/erpnext/templates/includes/assessment/assessment_row.html +++ /dev/null @@ -1,19 +0,0 @@ -
-
-
- {{ doc.course }} -
-
- {{ doc.room }} -
-
- {{doc.schedule_date }} -
-
- {{ doc.from_time }} -
-
- {{ doc.to_time }} -
-
-
diff --git a/erpnext/templates/includes/course/course_row.html b/erpnext/templates/includes/course/course_row.html deleted file mode 100644 index fddfc3c17a..0000000000 --- a/erpnext/templates/includes/course/course_row.html +++ /dev/null @@ -1,18 +0,0 @@ -
diff --git a/erpnext/templates/includes/course/macros.html b/erpnext/templates/includes/course/macros.html deleted file mode 100644 index 334b5ea200..0000000000 --- a/erpnext/templates/includes/course/macros.html +++ /dev/null @@ -1 +0,0 @@ -{% macro back_link(doc) %}&back-to=/courses?course={{ doc.name }}&back-to-title={{ doc.course_name }}{% endmacro %} From 389c2853eb24f7df23bde228dea8cd240d2563c6 Mon Sep 17 00:00:00 2001 From: gavin Date: Thu, 28 Apr 2022 14:57:43 +0530 Subject: [PATCH 085/106] docs: Trimmed whitespace from "Try on FCloud" button ERPNext Port of https://github.com/frappe/frappe/pull/16793/commits/b1effcab4b001c89b6b6b825976aea42e2172b02 --- .github/try-on-f-cloud-button.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/try-on-f-cloud-button.svg b/.github/try-on-f-cloud-button.svg index fe0bb2c52d..270092722e 100644 --- a/.github/try-on-f-cloud-button.svg +++ b/.github/try-on-f-cloud-button.svg @@ -1,4 +1,4 @@ - + From 848827cf5cb6f7c19632d0b6b5d0082659c48759 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 28 Apr 2022 15:11:22 +0530 Subject: [PATCH 086/106] chore: Remove references for Assessment Group --- erpnext/hooks.py | 1 - erpnext/setup/setup_wizard/operations/install_fixtures.py | 7 ------- 2 files changed, 8 deletions(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 14a2f15c17..e118c378c9 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -62,7 +62,6 @@ treeviews = [ "Supplier Group", "Sales Person", "Territory", - "Assessment Group", "Department", ] diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py index e31c12671e..90b50a01cd 100644 --- a/erpnext/setup/setup_wizard/operations/install_fixtures.py +++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py @@ -396,13 +396,6 @@ def install(country=None): {"doctype": "Offer Term", "offer_term": _("Incentives")}, {"doctype": "Print Heading", "print_heading": _("Credit Note")}, {"doctype": "Print Heading", "print_heading": _("Debit Note")}, - # Assessment Group - { - "doctype": "Assessment Group", - "assessment_group_name": _("All Assessment Groups"), - "is_group": 1, - "parent_assessment_group": "", - }, # Share Management {"doctype": "Share Type", "title": _("Equity")}, {"doctype": "Share Type", "title": _("Preference")}, From cc867fd949cf28a2c606210bfffd1faded0892e9 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 28 Apr 2022 15:51:32 +0530 Subject: [PATCH 087/106] chore: Remove Fees Doctype --- erpnext/hooks.py | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index e118c378c9..ab40f19f47 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -521,7 +521,6 @@ accounting_dimension_doctypes = [ "Loyalty Program", "Stock Reconciliation", "Travel Request", - "Fees", "POS Profile", "Opening Invoice Creation Tool", "Opening Invoice Creation Tool Item", From 44c54f69f83e28fe205eb5f0e5dc4f161a8c0bba Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 28 Apr 2022 16:16:47 +0530 Subject: [PATCH 088/106] chore: Remove references for Student doctype --- .../doctype/payment_entry/payment_entry.js | 8 ++---- .../report/general_ledger/general_ledger.py | 2 +- .../trial_balance_for_party.py | 2 -- .../operations/install_fixtures.py | 1 - .../generators/student_admission.html | 27 ------------------- erpnext/utilities/activation.py | 1 - 6 files changed, 3 insertions(+), 38 deletions(-) delete mode 100644 erpnext/templates/generators/student_admission.html diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index 403e2bdfe7..d7fae6d2a3 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -112,8 +112,6 @@ frappe.ui.form.on('Payment Entry', { var doctypes = ["Purchase Order", "Purchase Invoice", "Journal Entry"]; } else if (frm.doc.party_type == "Employee") { var doctypes = ["Expense Claim", "Journal Entry"]; - } else if (frm.doc.party_type == "Student") { - var doctypes = ["Fees"]; } else { var doctypes = ["Journal Entry"]; } @@ -755,8 +753,7 @@ frappe.ui.form.on('Payment Entry', { if( (frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") || (frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") || - (frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee") || - (frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student") + (frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee") ) { if(total_positive_outstanding > total_negative_outstanding) if (!frm.doc.paid_amount) @@ -798,8 +795,7 @@ frappe.ui.form.on('Payment Entry', { if ( (frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") || (frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") || - (frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee") || - (frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student") + (frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee") ) { if(total_positive_outstanding_including_order > paid_amount) { var remaining_outstanding = total_positive_outstanding_including_order - paid_amount; diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index 636d624506..0cbdf37e65 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -133,7 +133,7 @@ def set_account_currency(filters): else: account_currency = ( None - if filters.party_type in ["Employee", "Student", "Shareholder", "Member"] + if filters.party_type in ["Employee", "Shareholder", "Member"] else frappe.db.get_value(filters.party_type, filters.party[0], "default_currency") ) diff --git a/erpnext/accounts/report/trial_balance_for_party/trial_balance_for_party.py b/erpnext/accounts/report/trial_balance_for_party/trial_balance_for_party.py index 869f6aaf94..5fcfdff6f1 100644 --- a/erpnext/accounts/report/trial_balance_for_party/trial_balance_for_party.py +++ b/erpnext/accounts/report/trial_balance_for_party/trial_balance_for_party.py @@ -23,8 +23,6 @@ def execute(filters=None): def get_data(filters, show_party_name): if filters.get("party_type") in ("Customer", "Supplier", "Employee", "Member"): party_name_field = "{0}_name".format(frappe.scrub(filters.get("party_type"))) - elif filters.get("party_type") == "Student": - party_name_field = "first_name" elif filters.get("party_type") == "Shareholder": party_name_field = "title" else: diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py index 90b50a01cd..d979ad17da 100644 --- a/erpnext/setup/setup_wizard/operations/install_fixtures.py +++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py @@ -375,7 +375,6 @@ def install(country=None): {"doctype": "Party Type", "party_type": "Supplier", "account_type": "Payable"}, {"doctype": "Party Type", "party_type": "Employee", "account_type": "Payable"}, {"doctype": "Party Type", "party_type": "Shareholder", "account_type": "Payable"}, - {"doctype": "Party Type", "party_type": "Student", "account_type": "Receivable"}, {"doctype": "Opportunity Type", "name": _("Sales")}, {"doctype": "Opportunity Type", "name": _("Support")}, {"doctype": "Opportunity Type", "name": _("Maintenance")}, diff --git a/erpnext/templates/generators/student_admission.html b/erpnext/templates/generators/student_admission.html deleted file mode 100644 index 8cc58a0a1f..0000000000 --- a/erpnext/templates/generators/student_admission.html +++ /dev/null @@ -1,27 +0,0 @@ - -{% extends "templates/web.html" %} - -{% block breadcrumbs %} - {% include "templates/includes/breadcrumbs.html" %} -{% endblock %} - -{% block header %} - -

{{ title }}

-{% endblock %} - -{% block page_content %} - -{%- if introduction -%} -
{{ introduction }}
-{% endif %} - -{%- if doc.enable_admission_application -%} -

- - {{ _("Apply Now") }} -

-{% endif %} - -{% endblock %} diff --git a/erpnext/utilities/activation.py b/erpnext/utilities/activation.py index d2f6bd9322..cd7910ce43 100644 --- a/erpnext/utilities/activation.py +++ b/erpnext/utilities/activation.py @@ -37,7 +37,6 @@ def get_level(): "Sales Order": 2, "Sales Invoice": 2, "Stock Entry": 3, - "Student": 5, "Supplier": 5, "Task": 5, "User": 5, From 3c578a3b0b57099410d46e9fef17289e9d07548a Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 28 Apr 2022 19:54:28 +0530 Subject: [PATCH 089/106] chore: Add patch to delete education doctypes --- erpnext/patches.txt | 1 + .../v14_0/delete_education_doctypes.py | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 erpnext/patches/v14_0/delete_education_doctypes.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index d6c44cb331..558f322f34 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -333,6 +333,7 @@ erpnext.patches.v13_0.delete_bank_reconciliation_detail erpnext.patches.v13_0.enable_provisional_accounting erpnext.patches.v13_0.non_profit_deprecation_warning erpnext.patches.v13_0.enable_ksa_vat_docs #1 +erpnext.patches.v14_0.delete_education_doctypes [post_model_sync] erpnext.patches.v14_0.rename_ongoing_status_in_sla_documents diff --git a/erpnext/patches/v14_0/delete_education_doctypes.py b/erpnext/patches/v14_0/delete_education_doctypes.py new file mode 100644 index 0000000000..6b442bcb5a --- /dev/null +++ b/erpnext/patches/v14_0/delete_education_doctypes.py @@ -0,0 +1,55 @@ +import click +import frappe + + +def execute(): + if "education" in frappe.get_installed_apps(): + return + + frappe.delete_doc("Workspace", "Education", ignore_missing=True, force=True) + + pages = frappe.get_all("Page", {"module": "education"}, pluck="name") + for page in pages: + frappe.delete_doc("Page", page, ignore_missing=True, force=True) + + reports = frappe.get_all("Report", {"module": "education", "is_standard": "Yes"}, pluck="name") + for report in reports: + frappe.delete_doc("Report", report, ignore_missing=True, force=True) + + print_formats = frappe.get_all( + "Print Format", {"module": "education", "standard": "Yes"}, pluck="name" + ) + for print_format in print_formats: + frappe.delete_doc("Print Format", print_format, ignore_missing=True, force=True) + + frappe.reload_doc("website", "doctype", "website_settings") + forms = frappe.get_all("Web Form", {"module": "education", "is_standard": 1}, pluck="name") + for form in forms: + frappe.delete_doc("Web Form", form, ignore_missing=True, force=True) + + dashboards = frappe.get_all("Dashboard", {"module": "education", "is_standard": 1}, pluck="name") + for dashboard in dashboards: + frappe.delete_doc("Dashboard", dashboard, ignore_missing=True, force=True) + + dashboards = frappe.get_all( + "Dashboard Chart", {"module": "education", "is_standard": 1}, pluck="name" + ) + for dashboard in dashboards: + frappe.delete_doc("Dashboard Chart", dashboard, ignore_missing=True, force=True) + + frappe.reload_doc("desk", "doctype", "number_card") + cards = frappe.get_all("Number Card", {"module": "education", "is_standard": 1}, pluck="name") + for card in cards: + frappe.delete_doc("Number Card", card, ignore_missing=True, force=True) + + doctypes = frappe.get_all("DocType", {"module": "education", "custom": 0}, pluck="name") + for doctype in doctypes: + frappe.delete_doc("DocType", doctype, ignore_missing=True) + + frappe.delete_doc("Module Def", "Education", ignore_missing=True, force=True) + + click.secho( + "Education Module is moved to a separate app" + "Please install the app to continue using the module: https://github.com/frappe/healthcare", + fg="yellow", + ) From f25251bb70aee850fabeabb0c6394043637b561f Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 29 Apr 2022 12:42:29 +0530 Subject: [PATCH 090/106] chore: Clean up patches --- .../doctype/payment_entry/payment_entry.py | 39 +++++++------------ .../patches/v11_0/refactor_autoname_naming.py | 2 - .../patches/v11_0/refactor_naming_series.py | 2 - .../update_account_type_in_party_type.py | 1 - erpnext/portal/utils.py | 4 -- 5 files changed, 14 insertions(+), 34 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index e6a554c00a..7257e6d75f 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -183,9 +183,7 @@ class PaymentEntry(AccountsController): if not self.party: frappe.throw(_("Party is mandatory")) - _party_name = ( - "title" if self.party_type in ("Student", "Shareholder") else self.party_type.lower() + "_name" - ) + _party_name = "title" if self.party_type == "Shareholder" else self.party_type.lower() + "_name" self.party_name = frappe.db.get_value(self.party_type, self.party, _party_name) if self.party: @@ -298,9 +296,7 @@ class PaymentEntry(AccountsController): frappe.throw(_("{0} is mandatory").format(self.meta.get_label(field))) def validate_reference_documents(self): - if self.party_type == "Student": - valid_reference_doctypes = "Fees" - elif self.party_type == "Customer": + if self.party_type == "Customer": valid_reference_doctypes = ("Sales Order", "Sales Invoice", "Journal Entry", "Dunning") elif self.party_type == "Supplier": valid_reference_doctypes = ("Purchase Order", "Purchase Invoice", "Journal Entry") @@ -338,8 +334,6 @@ class PaymentEntry(AccountsController): ref_party_account = ( get_party_account_based_on_invoice_discounting(d.reference_name) or ref_doc.debit_to ) - elif self.party_type == "Student": - ref_party_account = ref_doc.receivable_account elif self.party_type == "Supplier": ref_party_account = ref_doc.credit_to elif self.party_type == "Employee": @@ -1259,20 +1253,19 @@ def get_outstanding_reference_documents(args): # Get all SO / PO which are not fully billed or against which full advance not paid orders_to_be_billed = [] - if args.get("party_type") != "Student": - orders_to_be_billed = get_orders_to_be_billed( - args.get("posting_date"), - args.get("party_type"), - args.get("party"), - args.get("company"), - party_account_currency, - company_currency, - filters=args, - ) + orders_to_be_billed = get_orders_to_be_billed( + args.get("posting_date"), + args.get("party_type"), + args.get("party"), + args.get("company"), + party_account_currency, + company_currency, + filters=args, + ) # Get negative outstanding sales /purchase invoices negative_outstanding_invoices = [] - if args.get("party_type") not in ["Student", "Employee"] and not args.get("voucher_no"): + if args.get("party_type") != "Employee" and not args.get("voucher_no"): negative_outstanding_invoices = get_negative_outstanding_invoices( args.get("party_type"), args.get("party"), @@ -1496,9 +1489,7 @@ def get_party_details(company, party_type, party, date, cost_center=None): account_currency = get_account_currency(party_account) account_balance = get_balance_on(party_account, date, cost_center=cost_center) - _party_name = ( - "title" if party_type in ("Student", "Shareholder") else party_type.lower() + "_name" - ) + _party_name = "title" if party_type == "Shareholder" else party_type.lower() + "_name" party_name = frappe.db.get_value(party_type, party, _party_name) party_balance = get_balance_on(party_type=party_type, party=party, cost_center=cost_center) if party_type in ["Customer", "Supplier"]: @@ -1560,7 +1551,7 @@ def get_company_defaults(company): def get_outstanding_on_journal_entry(name): res = frappe.db.sql( "SELECT " - 'CASE WHEN party_type IN ("Customer", "Student") ' + 'CASE WHEN party_type IN ("Customer") ' "THEN ifnull(sum(debit_in_account_currency - credit_in_account_currency), 0) " "ELSE ifnull(sum(credit_in_account_currency - debit_in_account_currency), 0) " "END as outstanding_amount " @@ -1917,8 +1908,6 @@ def set_party_type(dt): party_type = "Supplier" elif dt in ("Expense Claim", "Employee Advance", "Gratuity"): party_type = "Employee" - elif dt == "Fees": - party_type = "Student" return party_type diff --git a/erpnext/patches/v11_0/refactor_autoname_naming.py b/erpnext/patches/v11_0/refactor_autoname_naming.py index de453ccf21..fa8f4eb23e 100644 --- a/erpnext/patches/v11_0/refactor_autoname_naming.py +++ b/erpnext/patches/v11_0/refactor_autoname_naming.py @@ -69,8 +69,6 @@ doctype_series_map = { "Soil Analysis": "AG-ANA-.YY.-.MM.-.#####", "Soil Texture": "AG-TEX-.YYYY.-.#####", "Stock Ledger Entry": "MAT-SLE-.YYYY.-.#####", - "Student Leave Application": "EDU-SLA-.YYYY.-.#####", - "Student Log": "EDU-SLOG-.YYYY.-.#####", "Subscription": "ACC-SUB-.YYYY.-.#####", "Task": "TASK-.YYYY.-.#####", "Tax Rule": "ACC-TAX-RULE-.YYYY.-.#####", diff --git a/erpnext/patches/v11_0/refactor_naming_series.py b/erpnext/patches/v11_0/refactor_naming_series.py index 4945860797..cdc92fe61f 100644 --- a/erpnext/patches/v11_0/refactor_naming_series.py +++ b/erpnext/patches/v11_0/refactor_naming_series.py @@ -55,8 +55,6 @@ doctype_series_map = { "Shareholder": "ACC-SH-.YYYY.-", "Stock Entry": "MAT-STE-.YYYY.-", "Stock Reconciliation": "MAT-RECO-.YYYY.-", - "Student": "EDU-STU-.YYYY.-", - "Student Applicant": "EDU-APP-.YYYY.-", "Supplier": "SUP-.YYYY.-", "Supplier Quotation": "PUR-SQTN-.YYYY.-", "Supplier Scorecard Period": "PU-SSP-.YYYY.-", diff --git a/erpnext/patches/v11_0/update_account_type_in_party_type.py b/erpnext/patches/v11_0/update_account_type_in_party_type.py index e55f9f20cc..47252eb98f 100644 --- a/erpnext/patches/v11_0/update_account_type_in_party_type.py +++ b/erpnext/patches/v11_0/update_account_type_in_party_type.py @@ -13,7 +13,6 @@ def execute(): "Employee": "Payable", "Member": "Receivable", "Shareholder": "Payable", - "Student": "Receivable", } for party_type, account_type in party_types.items(): diff --git a/erpnext/portal/utils.py b/erpnext/portal/utils.py index 09d100708e..7be8c5df18 100644 --- a/erpnext/portal/utils.py +++ b/erpnext/portal/utils.py @@ -23,10 +23,6 @@ def set_default_role(doc, method): doc.add_roles("Customer") elif link.link_doctype == "Supplier" and "Supplier" not in roles: doc.add_roles("Supplier") - elif frappe.get_value("Student", dict(student_email_id=doc.email)) and "Student" not in roles: - doc.add_roles("Student") - elif frappe.get_value("Guardian", dict(email_address=doc.email)) and "Guardian" not in roles: - doc.add_roles("Guardian") def create_customer_or_supplier(): From a8452c2ba241a943f99ca3856985f728e11d47b1 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 29 Apr 2022 14:27:03 +0530 Subject: [PATCH 091/106] fix: Multi currency opening invoices --- .../opening_invoice_creation_tool.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py index 174b7d7f46..2d9ae9377f 100644 --- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py +++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py @@ -114,10 +114,13 @@ class OpeningInvoiceCreationTool(Document): ) or {} ) + + default_currency = frappe.db.get_value(row.party_type, row.party, "default_currency") + if company_details: invoice.update( { - "currency": company_details.get("default_currency"), + "currency": default_currency or company_details.get("default_currency"), "letter_head": company_details.get("default_letter_head"), } ) @@ -154,7 +157,6 @@ class OpeningInvoiceCreationTool(Document): "income_account" if row.party_type == "Customer" else "expense_account" ) default_uom = frappe.db.get_single_value("Stock Settings", "stock_uom") or _("Nos") - default_currency = frappe.db.get_value(row.party_type, row.party, "default_currency") rate = flt(row.outstanding_amount) / flt(row.qty) item_dict = frappe._dict( @@ -167,7 +169,6 @@ class OpeningInvoiceCreationTool(Document): "description": row.item_name or "Opening Invoice Item", income_expense_account_field: row.temporary_opening_account, "cost_center": cost_center, - "currency": default_currency, } ) From 65742947e76875598efd459f1c67d0835c009fc9 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 29 Apr 2022 15:46:00 +0530 Subject: [PATCH 092/106] fix(UX): record reason for skipping attendance or marking absent for auto attendance (#30844) --- .../employee_checkin/employee_checkin.py | 57 ++++++++++++++----- erpnext/hr/doctype/shift_type/shift_type.py | 12 +++- 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/erpnext/hr/doctype/employee_checkin/employee_checkin.py b/erpnext/hr/doctype/employee_checkin/employee_checkin.py index 64eb019b00..e07b5e5db5 100644 --- a/erpnext/hr/doctype/employee_checkin/employee_checkin.py +++ b/erpnext/hr/doctype/employee_checkin/employee_checkin.py @@ -5,7 +5,7 @@ import frappe from frappe import _ from frappe.model.document import Document -from frappe.utils import cint, get_datetime +from frappe.utils import cint, get_datetime, get_link_to_form from erpnext.hr.doctype.attendance.attendance import ( get_duplicate_attendance_record, @@ -130,14 +130,11 @@ def mark_attendance_and_link_log( """ log_names = [x.name for x in logs] employee = logs[0].employee + if attendance_status == "Skip": - frappe.db.sql( - """update `tabEmployee Checkin` - set skip_auto_attendance = %s - where name in %s""", - ("1", log_names), - ) + skip_attendance_in_checkins(log_names) return None + elif attendance_status in ("Present", "Absent", "Half Day"): employee_doc = frappe.get_doc("Employee", employee) duplicate = get_duplicate_attendance_record(employee, attendance_date, shift) @@ -159,6 +156,12 @@ def mark_attendance_and_link_log( } attendance = frappe.get_doc(doc_dict).insert() attendance.submit() + + if attendance_status == "Absent": + attendance.add_comment( + text=_("Employee was marked Absent for not meeting the working hours threshold.") + ) + frappe.db.sql( """update `tabEmployee Checkin` set attendance = %s @@ -167,13 +170,10 @@ def mark_attendance_and_link_log( ) return attendance else: - frappe.db.sql( - """update `tabEmployee Checkin` - set skip_auto_attendance = %s - where name in %s""", - ("1", log_names), - ) + skip_attendance_in_checkins(log_names) + add_comment_in_checkins(log_names, duplicate, overlapping) return None + else: frappe.throw(_("{} is an invalid Attendance Status.").format(attendance_status)) @@ -241,3 +241,34 @@ def time_diff_in_hours(start, end): def find_index_in_dict(dict_list, key, value): return next((index for (index, d) in enumerate(dict_list) if d[key] == value), None) + + +def add_comment_in_checkins(log_names, duplicate, overlapping): + if duplicate: + text = _("Auto Attendance skipped due to duplicate attendance record: {}").format( + get_link_to_form("Attendance", duplicate[0].name) + ) + else: + text = _("Auto Attendance skipped due to overlapping attendance record: {}").format( + get_link_to_form("Attendance", overlapping.name) + ) + + for name in log_names: + frappe.get_doc( + { + "doctype": "Comment", + "comment_type": "Comment", + "reference_doctype": "Employee Checkin", + "reference_name": name, + "content": text, + } + ).insert(ignore_permissions=True) + + +def skip_attendance_in_checkins(log_names): + EmployeeCheckin = frappe.qb.DocType("Employee Checkin") + ( + frappe.qb.update(EmployeeCheckin) + .set("skip_auto_attendance", 1) + .where(EmployeeCheckin.name.isin(log_names)) + ).run() diff --git a/erpnext/hr/doctype/shift_type/shift_type.py b/erpnext/hr/doctype/shift_type/shift_type.py index 5e214cf7b7..a61bb9ee5f 100644 --- a/erpnext/hr/doctype/shift_type/shift_type.py +++ b/erpnext/hr/doctype/shift_type/shift_type.py @@ -134,7 +134,17 @@ class ShiftType(Document): shift_details = get_employee_shift(employee, timestamp, True) if shift_details and shift_details.shift_type.name == self.name: - mark_attendance(employee, date, "Absent", self.name) + attendance = mark_attendance(employee, date, "Absent", self.name) + if attendance: + frappe.get_doc( + { + "doctype": "Comment", + "comment_type": "Comment", + "reference_doctype": "Attendance", + "reference_name": attendance, + "content": frappe._("Employee was marked Absent due to missing Employee Checkins."), + } + ).insert(ignore_permissions=True) def get_start_and_end_dates(self, employee): """Returns start and end dates for checking attendance and marking absent From ab94b73e9383cf7b7bca7cb8454d7c55cde0b63b Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 29 Apr 2022 18:06:13 +0530 Subject: [PATCH 093/106] fix: Cost center filter on payment reconciliation --- .../payment_reconciliation/payment_reconciliation.js | 9 +++++++++ .../payment_reconciliation/payment_reconciliation.json | 10 +++++++++- .../payment_reconciliation/payment_reconciliation.py | 3 +++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js index ad5a84094e..0b334ae076 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js @@ -38,6 +38,15 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo ] }; }); + + this.frm.set_query("cost_center", () => { + return { + "filters": { + "company": this.frm.doc.company, + "is_group": 0 + } + } + }); } refresh() { diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json index eb0c20f92d..18d3485085 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json @@ -24,6 +24,7 @@ "invoice_limit", "payment_limit", "bank_cash_account", + "cost_center", "sec_break1", "invoices", "column_break_15", @@ -178,13 +179,19 @@ { "fieldname": "column_break_11", "fieldtype": "Column Break" + }, + { + "fieldname": "cost_center", + "fieldtype": "Link", + "label": "Cost Center", + "options": "Cost Center" } ], "hide_toolbar": 1, "icon": "icon-resize-horizontal", "issingle": 1, "links": [], - "modified": "2021-10-04 20:27:11.114194", + "modified": "2022-04-29 15:37:10.246831", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Reconciliation", @@ -209,5 +216,6 @@ ], "sort_field": "modified", "sort_order": "DESC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index b596df9224..e5b942fb6e 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -332,6 +332,9 @@ class PaymentReconciliation(Document): def get_conditions(self, get_invoices=False, get_payments=False, get_return_invoices=False): condition = " and company = '{0}' ".format(self.company) + if self.get("cost_center") and (get_invoices or get_payments or get_return_invoices): + condition = " and cost_center = '{0}' ".format(self.cost_center) + if get_invoices: condition += ( " and posting_date >= {0}".format(frappe.db.escape(self.from_invoice_date)) From d746db5547fa12c4f390a487c200cd2d36f18352 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Sun, 1 May 2022 12:25:21 +0530 Subject: [PATCH 094/106] fix(minor): discount accounting patch --- erpnext/patches/v14_0/discount_accounting_separation.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/patches/v14_0/discount_accounting_separation.py b/erpnext/patches/v14_0/discount_accounting_separation.py index fd498052d8..8157982135 100644 --- a/erpnext/patches/v14_0/discount_accounting_separation.py +++ b/erpnext/patches/v14_0/discount_accounting_separation.py @@ -2,8 +2,10 @@ import frappe def execute(): - doc = frappe.get_doc("Accounts Settings") - discount_account = doc.enable_discount_accounting + data = frappe.db.sql( + 'select value from tabSingles where doctype="Accounts Settings" and field="enable_discount_accounting"' + ) + discount_account = data and data[0][0] or 0 if discount_account: for doctype in ["Buying Settings", "Selling Settings"]: frappe.db.set_value(doctype, doctype, "enable_discount_accounting", 1, update_modified=False) From be0f84a7225b7c7fb032dcd4a70ea440db060247 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 2 May 2022 09:41:12 +0530 Subject: [PATCH 095/106] fix(minor): fix create_accounting_dimensions_in_orders.py --- erpnext/patches/v14_0/discount_accounting_separation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches/v14_0/discount_accounting_separation.py b/erpnext/patches/v14_0/discount_accounting_separation.py index 8157982135..0d1349a320 100644 --- a/erpnext/patches/v14_0/discount_accounting_separation.py +++ b/erpnext/patches/v14_0/discount_accounting_separation.py @@ -5,7 +5,7 @@ def execute(): data = frappe.db.sql( 'select value from tabSingles where doctype="Accounts Settings" and field="enable_discount_accounting"' ) - discount_account = data and data[0][0] or 0 + discount_account = data and int(data[0][0]) or 0 if discount_account: for doctype in ["Buying Settings", "Selling Settings"]: frappe.db.set_value(doctype, doctype, "enable_discount_accounting", 1, update_modified=False) From b8a9f821a436e7c8c57c2cc58057b3e28e85e8d5 Mon Sep 17 00:00:00 2001 From: sersaber <93864988+sersaber@users.noreply.github.com> Date: Mon, 2 May 2022 06:59:43 +0200 Subject: [PATCH 096/106] feat: Copy task color from project template (#30857) Co-authored-by: Rucha Mahabal --- erpnext/projects/doctype/project/project.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 29f1ce455e..60e0cc3e65 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -86,6 +86,7 @@ class Project(Document): type=task_details.type, issue=task_details.issue, is_group=task_details.is_group, + color=task_details.color, ) ).insert() From f0049da2845e5d6a2f7ed648b791e306ab25f9ac Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 2 May 2022 11:52:46 +0530 Subject: [PATCH 097/106] chore: correct link --- erpnext/patches/v14_0/delete_education_doctypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches/v14_0/delete_education_doctypes.py b/erpnext/patches/v14_0/delete_education_doctypes.py index 6b442bcb5a..76b2300fd2 100644 --- a/erpnext/patches/v14_0/delete_education_doctypes.py +++ b/erpnext/patches/v14_0/delete_education_doctypes.py @@ -50,6 +50,6 @@ def execute(): click.secho( "Education Module is moved to a separate app" - "Please install the app to continue using the module: https://github.com/frappe/healthcare", + "Please install the app to continue using the module: https://github.com/frappe/education", fg="yellow", ) From dcda55641b822f62b9808c36027b59b5eaf697b3 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 2 May 2022 13:58:22 +0530 Subject: [PATCH 098/106] fix: convert default_item_manufacturer to link field (#30835) --- erpnext/patches.txt | 1 + ...change_default_item_manufacturer_fieldtype.py | 16 ++++++++++++++++ erpnext/stock/doctype/item/item.json | 7 ++++--- 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 erpnext/patches/v13_0/change_default_item_manufacturer_fieldtype.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 6e9e499959..d5b15922ec 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -366,6 +366,7 @@ erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022 erpnext.patches.v13_0.update_expense_claim_status_for_paid_advances erpnext.patches.v13_0.create_gst_custom_fields_in_quotation erpnext.patches.v13_0.copy_custom_field_filters_to_website_item +erpnext.patches.v13_0.change_default_item_manufacturer_fieldtype erpnext.patches.v14_0.discount_accounting_separation erpnext.patches.v14_0.delete_employee_transfer_property_doctype erpnext.patches.v13_0.create_accounting_dimensions_in_orders \ No newline at end of file diff --git a/erpnext/patches/v13_0/change_default_item_manufacturer_fieldtype.py b/erpnext/patches/v13_0/change_default_item_manufacturer_fieldtype.py new file mode 100644 index 0000000000..0b00188e6a --- /dev/null +++ b/erpnext/patches/v13_0/change_default_item_manufacturer_fieldtype.py @@ -0,0 +1,16 @@ +import frappe + + +def execute(): + + # Erase all default item manufacturers that dont exist. + item = frappe.qb.DocType("Item") + manufacturer = frappe.qb.DocType("Manufacturer") + + ( + frappe.qb.update(item) + .set(item.default_item_manufacturer, None) + .left_join(manufacturer) + .on(item.default_item_manufacturer == manufacturer.name) + .where(manufacturer.name.isnull() & item.default_item_manufacturer.isnotnull()) + ).run() diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json index 06da8ee9c3..4f3e842995 100644 --- a/erpnext/stock/doctype/item/item.json +++ b/erpnext/stock/doctype/item/item.json @@ -869,8 +869,9 @@ }, { "fieldname": "default_item_manufacturer", - "fieldtype": "Data", + "fieldtype": "Link", "label": "Default Item Manufacturer", + "options": "Manufacturer", "read_only": 1 }, { @@ -918,7 +919,7 @@ "image_field": "image", "index_web_pages_for_search": 1, "links": [], - "modified": "2022-03-25 06:38:55.942304", + "modified": "2022-04-28 04:52:10.272256", "modified_by": "Administrator", "module": "Stock", "name": "Item", @@ -991,4 +992,4 @@ "states": [], "title_field": "item_name", "track_changes": 1 -} +} \ No newline at end of file From 548afba8bb244adab3db87eb3bd3a475db3877fe Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 2 May 2022 15:04:26 +0530 Subject: [PATCH 099/106] fix(minor): update frappe.error_log to new API (#30864) * fix(minor): update frappe.error_log to new API * refactor: changes for updated log_error api Co-authored-by: Ankush Menat --- erpnext/accounts/deferred_revenue.py | 19 +++---------------- .../bank_statement_import.py | 2 +- .../bank_transaction_upload.py | 2 +- .../doctype/ledger_merge/ledger_merge.py | 2 +- .../opening_invoice_creation_tool.py | 9 +-------- .../doctype/subscription/subscription.py | 4 +--- .../linkedin_settings/linkedin_settings.py | 2 +- .../social_media_post/social_media_post.py | 3 +-- erpnext/e_commerce/api.py | 3 +-- erpnext/e_commerce/redisearch_utils.py | 3 +-- .../connectors/woocommerce_connection.py | 2 +- .../gocardless_settings.py | 16 +++++----------- .../doctype/mpesa_settings/mpesa_settings.py | 8 ++++---- .../doctype/plaid_settings/plaid_connector.py | 10 +++++----- .../doctype/plaid_settings/plaid_settings.py | 6 +++--- .../exotel_integration.py | 4 +--- .../stripe_integration.py | 6 +++--- .../doctype/bom_update_log/bom_update_log.py | 2 +- .../move_bank_account_swift_number_to_bank.py | 2 +- .../add_missing_fg_item_for_stock_entry.py | 3 +-- ...ebsite_item_in_item_card_group_template.py | 5 +---- .../modify_invalid_gain_loss_gl_entries.py | 5 ++++- .../rename_ongoing_status_in_sla_documents.py | 2 +- .../import_supplier_invoice.py | 6 ++---- erpnext/setup/doctype/company/company.py | 2 +- .../setup_wizard/operations/taxes_setup.py | 2 +- erpnext/setup/utils.py | 2 +- .../repost_item_valuation.py | 2 +- erpnext/stock/reorder_item.py | 6 +++--- .../pages/integrations/gocardless_checkout.py | 2 +- .../integrations/gocardless_confirmation.py | 6 +++--- erpnext/utilities/doctype/video/video.py | 6 ++---- .../doctype/video_settings/video_settings.py | 2 +- 33 files changed, 59 insertions(+), 97 deletions(-) diff --git a/erpnext/accounts/deferred_revenue.py b/erpnext/accounts/deferred_revenue.py index a8776fa344..f319003876 100644 --- a/erpnext/accounts/deferred_revenue.py +++ b/erpnext/accounts/deferred_revenue.py @@ -539,19 +539,11 @@ def make_gl_entries( frappe.db.commit() except Exception as e: if frappe.flags.in_test: - traceback = frappe.get_traceback() - frappe.log_error( - title=_("Error while processing deferred accounting for Invoice {0}").format(doc.name), - message=traceback, - ) + doc.log_error(f"Error while processing deferred accounting for Invoice {doc.name}") raise e else: frappe.db.rollback() - traceback = frappe.get_traceback() - frappe.log_error( - title=_("Error while processing deferred accounting for Invoice {0}").format(doc.name), - message=traceback, - ) + doc.log_error(f"Error while processing deferred accounting for Invoice {doc.name}") frappe.flags.deferred_accounting_error = True @@ -632,12 +624,7 @@ def book_revenue_via_journal_entry( frappe.db.commit() except Exception: frappe.db.rollback() - traceback = frappe.get_traceback() - frappe.log_error( - title=_("Error while processing deferred accounting for Invoice {0}").format(doc.name), - message=traceback, - ) - + doc.log_error(f"Error while processing deferred accounting for Invoice {doc.name}") frappe.flags.deferred_accounting_error = True diff --git a/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py b/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py index 3540f0b0e0..3f5c064f4b 100644 --- a/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py +++ b/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py @@ -136,7 +136,7 @@ def start_import( except Exception: frappe.db.rollback() data_import.db_set("status", "Error") - frappe.log_error(title=data_import.name) + data_import.log_error("Bank Statement Import failed") finally: frappe.flags.in_import = False diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py index 9f2731de55..372c53d499 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py @@ -56,7 +56,7 @@ def create_bank_entries(columns, data, bank_account): bank_transaction.submit() success += 1 except Exception: - frappe.log_error(frappe.get_traceback()) + bank_transaction.log_error("Bank entry creation failed") errors += 1 return {"success": success, "errors": errors} diff --git a/erpnext/accounts/doctype/ledger_merge/ledger_merge.py b/erpnext/accounts/doctype/ledger_merge/ledger_merge.py index c1e2975fbc..18e5a1ac85 100644 --- a/erpnext/accounts/doctype/ledger_merge/ledger_merge.py +++ b/erpnext/accounts/doctype/ledger_merge/ledger_merge.py @@ -62,7 +62,7 @@ def start_merge(docname): ) except Exception: frappe.db.rollback() - frappe.log_error(title=ledger_merge.name) + ledger_merge.log_error("Ledger merge failed") finally: if successful_merges == total: ledger_merge.db_set("status", "Success") diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py index 2d9ae9377f..99377421c5 100644 --- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py +++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py @@ -2,9 +2,6 @@ # For license information, please see license.txt -import traceback -from json import dumps - import frappe from frappe import _, scrub from frappe.model.document import Document @@ -247,11 +244,7 @@ def start_import(invoices): except Exception: errors += 1 frappe.db.rollback() - message = "\n".join( - ["Data:", dumps(d, default=str, indent=4), "--" * 50, "\nException:", traceback.format_exc()] - ) - frappe.log_error(title="Error while creating Opening Invoice", message=message) - frappe.db.commit() + doc.log_error("Opening invoice creation failed") if errors: frappe.msgprint( _("You had {} errors while creating opening invoices. Check {} for more details").format( diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py index f6dd86afa2..2243b191da 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -722,9 +722,7 @@ def process(data): frappe.db.commit() except frappe.ValidationError: frappe.db.rollback() - frappe.db.begin() - frappe.log_error(frappe.get_traceback()) - frappe.db.commit() + subscription.log_error("Subscription failed") @frappe.whitelist() diff --git a/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py b/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py index b4657a2e36..64b3a017b4 100644 --- a/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py +++ b/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py @@ -72,7 +72,7 @@ class LinkedInSettings(Document): if media_id: return self.post_text(text, title, media_id=media_id) else: - frappe.log_error("Failed to upload media.", "LinkedIn Upload Error") + self.log_error("LinkedIn: Failed to upload media") def upload_image(self, media): media = get_file_path(media) diff --git a/erpnext/crm/doctype/social_media_post/social_media_post.py b/erpnext/crm/doctype/social_media_post/social_media_post.py index 2fd003e463..55db29a627 100644 --- a/erpnext/crm/doctype/social_media_post/social_media_post.py +++ b/erpnext/crm/doctype/social_media_post/social_media_post.py @@ -70,8 +70,7 @@ class SocialMediaPost(Document): except Exception: self.db_set("post_status", "Error") - title = _("Error while POSTING {0}").format(self.name) - frappe.log_error(message=frappe.get_traceback(), title=title) + self.log_error("Social posting failed") def process_scheduled_social_media_posts(): diff --git a/erpnext/e_commerce/api.py b/erpnext/e_commerce/api.py index 179829c2b7..bfada0faa7 100644 --- a/erpnext/e_commerce/api.py +++ b/erpnext/e_commerce/api.py @@ -56,8 +56,7 @@ def get_product_filter_data(query_args=None): attribute_filters, field_filters, search_term=search, start=start, item_group=item_group ) except Exception: - traceback = frappe.get_traceback() - frappe.log_error(traceback, frappe._("Product Engine Error")) + frappe.log_error("Product query with filter failed") return {"exc": "Something went wrong!"} # discount filter data diff --git a/erpnext/e_commerce/redisearch_utils.py b/erpnext/e_commerce/redisearch_utils.py index f2dd796f2c..61b4b9ee1f 100644 --- a/erpnext/e_commerce/redisearch_utils.py +++ b/erpnext/e_commerce/redisearch_utils.py @@ -245,8 +245,7 @@ def get_fields_indexed(): def raise_redisearch_error(): "Create an Error Log and raise error." - traceback = frappe.get_traceback() - log = frappe.log_error(traceback, frappe._("Redisearch Error")) + log = frappe.log_error("Redisearch Error") log_link = frappe.utils.get_link_to_form("Error Log", log.name) frappe.throw( diff --git a/erpnext/erpnext_integrations/connectors/woocommerce_connection.py b/erpnext/erpnext_integrations/connectors/woocommerce_connection.py index 46a4d3c69e..6d977e022f 100644 --- a/erpnext/erpnext_integrations/connectors/woocommerce_connection.py +++ b/erpnext/erpnext_integrations/connectors/woocommerce_connection.py @@ -32,7 +32,7 @@ def order(*args, **kwargs): error_message = ( frappe.get_traceback() + "\n\n Request Data: \n" + json.loads(frappe.request.data).__str__() ) - frappe.log_error(error_message, "WooCommerce Error") + frappe.log_error("WooCommerce Error", error_message) raise diff --git a/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.py b/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.py index e1972ae3d3..55517e4828 100644 --- a/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.py +++ b/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.py @@ -107,7 +107,7 @@ class GoCardlessSettings(Document): return self.create_charge_on_gocardless() except Exception: - frappe.log_error(frappe.get_traceback()) + frappe.log_error("Gocardless payment reqeust failed") return { "redirect_to": frappe.redirect_to_message( _("Server Error"), @@ -163,21 +163,15 @@ class GoCardlessSettings(Document): or payment.status == "charged_back" ): self.integration_request.db_set("status", "Cancelled", update_modified=False) - frappe.log_error( - _("Payment Cancelled. Please check your GoCardless Account for more details"), - "GoCardless Payment Error", - ) + frappe.log_error("Gocardless payment cancelled") self.integration_request.db_set("error", payment.status, update_modified=False) else: self.integration_request.db_set("status", "Failed", update_modified=False) - frappe.log_error( - _("Payment Failed. Please check your GoCardless Account for more details"), - "GoCardless Payment Error", - ) + frappe.log_error("Gocardless payment failed") self.integration_request.db_set("error", payment.status, update_modified=False) except Exception as e: - frappe.log_error(e, "GoCardless Payment Error") + frappe.log_error("GoCardless Payment Error") if self.flags.status_changed_to == "Completed": status = "Completed" @@ -188,7 +182,7 @@ class GoCardlessSettings(Document): self.data.get("reference_doctype"), self.data.get("reference_docname") ).run_method("on_payment_authorized", self.flags.status_changed_to) except Exception: - frappe.log_error(frappe.get_traceback()) + frappe.log_error("Gocardless redirect failed") if custom_redirect_to: redirect_to = custom_redirect_to diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py b/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py index 78a598ce98..e389980726 100644 --- a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py +++ b/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py @@ -152,7 +152,7 @@ def generate_stk_push(**kwargs): return response except Exception: - frappe.log_error(title=_("Mpesa Express Transaction Error")) + frappe.log_error("Mpesa Express Transaction Error") frappe.throw( _("Issue detected with Mpesa configuration, check the error logs for more details"), title=_("Mpesa Express Error"), @@ -203,7 +203,7 @@ def verify_transaction(**kwargs): integration_request.handle_success(transaction_response) except Exception: integration_request.handle_failure(transaction_response) - frappe.log_error(frappe.get_traceback()) + frappe.log_error("Mpesa: Failed to verify transaction") else: integration_request.handle_failure(transaction_response) @@ -275,7 +275,7 @@ def get_account_balance(request_payload): ) return response except Exception: - frappe.log_error(title=_("Account Balance Processing Error")) + frappe.log_error("Mpesa: Failed to get account balance") frappe.throw(_("Please check your configuration and try again"), title=_("Error")) @@ -315,7 +315,7 @@ def process_balance_info(**kwargs): except Exception: request.handle_failure(account_balance_response) frappe.log_error( - title=_("Mpesa Account Balance Processing Error"), message=account_balance_response + title="Mpesa Account Balance Processing Error", message=account_balance_response ) else: request.handle_failure(account_balance_response) diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py index 625dd3110e..38d69932f2 100644 --- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py +++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py @@ -23,7 +23,7 @@ class PlaidConnector: def get_access_token(self, public_token): if public_token is None: - frappe.log_error(_("Public token is missing for this bank"), _("Plaid public token error")) + frappe.log_error("Plaid: Public token is missing") response = self.client.Item.public_token.exchange(public_token) access_token = response["access_token"] return access_token @@ -61,10 +61,10 @@ class PlaidConnector: try: response = self.client.LinkToken.create(token_request) except InvalidRequestError: - frappe.log_error(frappe.get_traceback(), _("Plaid invalid request error")) + frappe.log_error("Plaid: Invalid request error") frappe.msgprint(_("Please check your Plaid client ID and secret values")) except APIError as e: - frappe.log_error(frappe.get_traceback(), _("Plaid authentication error")) + frappe.log_error("Plaid: Authentication error") frappe.throw(_(str(e)), title=_("Authentication Failed")) else: return response["link_token"] @@ -81,7 +81,7 @@ class PlaidConnector: except requests.Timeout: pass except Exception as e: - frappe.log_error(frappe.get_traceback(), _("Plaid authentication error")) + frappe.log_error("Plaid: Authentication error") frappe.throw(_(str(e)), title=_("Authentication Failed")) def get_transactions(self, start_date, end_date, account_id=None): @@ -102,4 +102,4 @@ class PlaidConnector: except ItemError as e: raise e except Exception: - frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error")) + frappe.log_error("Plaid: Transactions sync error") diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py index ce65f6c0ff..62ea85fc5d 100644 --- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py +++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py @@ -54,7 +54,7 @@ def add_institution(token, response): ) bank.insert() except Exception: - frappe.log_error(frappe.get_traceback(), title=_("Plaid Link Error")) + frappe.log_error("Plaid Link Error") else: bank = frappe.get_doc("Bank", response["institution"]["name"]) bank.plaid_access_token = access_token @@ -113,7 +113,7 @@ def add_bank_accounts(response, bank, company): _("Bank account {0} already exists and could not be created again").format(account["name"]) ) except Exception: - frappe.log_error(frappe.get_traceback(), title=_("Plaid Link Error")) + frappe.log_error("Plaid Link Error") frappe.throw( _("There was an error creating Bank Account while linking with Plaid."), title=_("Plaid Link Failed"), @@ -135,7 +135,7 @@ def add_bank_accounts(response, bank, company): existing_account.save() result.append(existing_bank_account) except Exception: - frappe.log_error(frappe.get_traceback(), title=_("Plaid Link Error")) + frappe.log_error("Plaid Link Error") frappe.throw( _("There was an error updating Bank Account {} while linking with Plaid.").format( existing_bank_account diff --git a/erpnext/erpnext_integrations/exotel_integration.py b/erpnext/erpnext_integrations/exotel_integration.py index 522de9ead8..fd9f74e8c9 100644 --- a/erpnext/erpnext_integrations/exotel_integration.py +++ b/erpnext/erpnext_integrations/exotel_integration.py @@ -1,6 +1,5 @@ import frappe import requests -from frappe import _ # api/method/erpnext.erpnext_integrations.exotel_integration.handle_incoming_call # api/method/erpnext.erpnext_integrations.exotel_integration.handle_end_call @@ -26,8 +25,7 @@ def handle_incoming_call(**kwargs): update_call_log(call_payload, call_log=call_log) except Exception as e: frappe.db.rollback() - frappe.log_error(title=_("Error in Exotel incoming call")) - frappe.db.commit() + exotel_settings.log_error("Error in Exotel incoming call") @frappe.whitelist(allow_guest=True) diff --git a/erpnext/erpnext_integrations/stripe_integration.py b/erpnext/erpnext_integrations/stripe_integration.py index b12adc1d3d..2d7e8a5d31 100644 --- a/erpnext/erpnext_integrations/stripe_integration.py +++ b/erpnext/erpnext_integrations/stripe_integration.py @@ -22,7 +22,7 @@ def create_stripe_subscription(gateway_controller, data): return create_subscription_on_stripe(stripe_settings) except Exception: - frappe.log_error(frappe.get_traceback()) + stripe_settings.log_error("Unable to create Stripe subscription") return { "redirect_to": frappe.redirect_to_message( _("Server Error"), @@ -55,9 +55,9 @@ def create_subscription_on_stripe(stripe_settings): else: stripe_settings.integration_request.db_set("status", "Failed", update_modified=False) - frappe.log_error("Subscription N°: " + subscription.id, "Stripe Payment not completed") + frappe.log_error(f"Stripe Subscription ID {subscription.id}: Payment failed") except Exception: stripe_settings.integration_request.db_set("status", "Failed", update_modified=False) - frappe.log_error(frappe.get_traceback()) + stripe_settings.log_error("Unable to create Stripe subscription") return stripe_settings.finalize_request() diff --git a/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py b/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py index 139dcbcdd9..c0770fac90 100644 --- a/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py +++ b/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py @@ -154,7 +154,7 @@ def run_bom_job( except Exception: frappe.db.rollback() - error_log = frappe.log_error(message=frappe.get_traceback(), title=_("BOM Update Tool Error")) + error_log = doc.log_error("BOM Update Tool Error") doc.db_set("status", "Failed") doc.db_set("error_log", error_log.name) diff --git a/erpnext/patches/v12_0/move_bank_account_swift_number_to_bank.py b/erpnext/patches/v12_0/move_bank_account_swift_number_to_bank.py index c069c24cfa..671dfd116d 100644 --- a/erpnext/patches/v12_0/move_bank_account_swift_number_to_bank.py +++ b/erpnext/patches/v12_0/move_bank_account_swift_number_to_bank.py @@ -17,7 +17,7 @@ def execute(): """ ) except Exception as e: - frappe.log_error(e, title="Patch Migration Failed") + frappe.log_error("Bank to Bank Account patch migration failed") frappe.reload_doc("accounts", "doctype", "bank_account") frappe.reload_doc("accounts", "doctype", "payment_request") diff --git a/erpnext/patches/v13_0/add_missing_fg_item_for_stock_entry.py b/erpnext/patches/v13_0/add_missing_fg_item_for_stock_entry.py index 517a14a830..ddbb7fd0f1 100644 --- a/erpnext/patches/v13_0/add_missing_fg_item_for_stock_entry.py +++ b/erpnext/patches/v13_0/add_missing_fg_item_for_stock_entry.py @@ -96,8 +96,7 @@ def repost_stock_entry(doc): make_sl_entries(sl_entries, True) except Exception: print(f"SLE entries not posted for the stock entry {doc.name}") - traceback = frappe.get_traceback() - frappe.log_error(traceback) + doc.log_error("Stock respost failed") def get_sle_for_target_warehouse(doc, sl_entries, finished_item_row): diff --git a/erpnext/patches/v13_0/convert_to_website_item_in_item_card_group_template.py b/erpnext/patches/v13_0/convert_to_website_item_in_item_card_group_template.py index 020521d5b9..1bac0fdbf0 100644 --- a/erpnext/patches/v13_0/convert_to_website_item_in_item_card_group_template.py +++ b/erpnext/patches/v13_0/convert_to_website_item_in_item_card_group_template.py @@ -56,8 +56,5 @@ def make_new_website_item(item: str) -> Union[str, None]: web_item = make_website_item(doc) # returns [website_item.name, item_name] return web_item[0] except Exception: - title = f"{item}: Error while converting to Website Item " - frappe.log_error( - title + "for Item Card Group Template" + "\n\n" + frappe.get_traceback(), title=title - ) + doc.log_error("Website Item creation failed") return None diff --git a/erpnext/patches/v13_0/modify_invalid_gain_loss_gl_entries.py b/erpnext/patches/v13_0/modify_invalid_gain_loss_gl_entries.py index 492e0403ec..6c64ef6559 100644 --- a/erpnext/patches/v13_0/modify_invalid_gain_loss_gl_entries.py +++ b/erpnext/patches/v13_0/modify_invalid_gain_loss_gl_entries.py @@ -40,7 +40,10 @@ def execute(): ) if purchase_invoices + sales_invoices: - frappe.log_error(json.dumps(purchase_invoices + sales_invoices, indent=2), title="Patch Log") + frappe.log_error( + "Fix invalid gain / loss patch log", + message=json.dumps(purchase_invoices + sales_invoices, indent=2), + ) acc_frozen_upto = frappe.db.get_value("Accounts Settings", None, "acc_frozen_upto") if acc_frozen_upto: diff --git a/erpnext/patches/v14_0/rename_ongoing_status_in_sla_documents.py b/erpnext/patches/v14_0/rename_ongoing_status_in_sla_documents.py index 2eb6becb09..8ea96abd30 100644 --- a/erpnext/patches/v14_0/rename_ongoing_status_in_sla_documents.py +++ b/erpnext/patches/v14_0/rename_ongoing_status_in_sla_documents.py @@ -18,4 +18,4 @@ def execute(): ).run() except Exception: - frappe.log_error(title="Failed to Patch SLA Status") + frappe.log_error("Failed to Patch SLA Status") diff --git a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py index 77c4d7c6ca..34701c140d 100644 --- a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py +++ b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py @@ -160,7 +160,7 @@ def get_file_content(file_name, zip_file_object): try: content = encoded_content.decode("utf-16") except UnicodeDecodeError as e: - frappe.log_error(message=e, title="UTF-16 encoding error for File Name: " + file_name) + frappe.log_error("UTF-16 encoding error for File Name: " + file_name) return content @@ -390,9 +390,7 @@ def create_purchase_invoice(supplier_name, file_name, args, name): return pi.name except Exception as e: frappe.db.set_value("Import Supplier Invoice", name, "status", "Error") - frappe.log_error( - message=e, title="Create Purchase Invoice: " + args.get("bill_no") + "File Name: " + file_name - ) + pi.log_error("Unable to create Puchase Invoice") return None diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index c11645822f..9bde6e2c47 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -528,7 +528,7 @@ def install_country_fixtures(company, country): except ImportError: pass except Exception: - frappe.log_error() + frappe.log_error("Unable to set country fixtures") frappe.throw( _("Failed to setup defaults for country {0}. Please contact support.").format( frappe.bold(country) diff --git a/erpnext/setup/setup_wizard/operations/taxes_setup.py b/erpnext/setup/setup_wizard/operations/taxes_setup.py index 39dc7e3327..2f77dd6ae5 100644 --- a/erpnext/setup/setup_wizard/operations/taxes_setup.py +++ b/erpnext/setup/setup_wizard/operations/taxes_setup.py @@ -116,7 +116,7 @@ def update_regional_tax_settings(country, company): frappe.get_attr(module_name)(country, company) except Exception as e: # Log error and ignore if failed to setup regional tax settings - frappe.log_error() + frappe.log_error("Unable to setup regional tax settings") pass diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py index 2200e6cd1d..e848dfebdc 100644 --- a/erpnext/setup/utils.py +++ b/erpnext/setup/utils.py @@ -112,7 +112,7 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No cache.setex(name=key, time=21600, value=flt(value)) return flt(value) except Exception: - frappe.log_error(title="Get Exchange Rate") + frappe.log_error("Unable to fetch exchange rate") frappe.msgprint( _( "Unable to find exchange rate for {0} to {1} for key date {2}. Please create a Currency Exchange record manually" diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py index eb0be460d8..236b944c3a 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py @@ -135,7 +135,7 @@ def repost(doc): except Exception: frappe.db.rollback() traceback = frappe.get_traceback() - frappe.log_error(traceback) + doc.log_error("Unable to repost item valuation") message = frappe.message_log.pop() if frappe.message_log else "" if traceback: diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py index ee151b7517..4763b472c2 100644 --- a/erpnext/stock/reorder_item.py +++ b/erpnext/stock/reorder_item.py @@ -136,14 +136,14 @@ def create_material_request(material_requests): mr_list = [] exceptions_list = [] - def _log_exception(): + def _log_exception(mr): if frappe.local.message_log: exceptions_list.extend(frappe.local.message_log) frappe.local.message_log = [] else: exceptions_list.append(frappe.get_traceback()) - frappe.log_error(frappe.get_traceback()) + mr.log_error("Unable to create material request") for request_type in material_requests: for company in material_requests[request_type]: @@ -207,7 +207,7 @@ def create_material_request(material_requests): mr_list.append(mr) except Exception: - _log_exception() + _log_exception(mr) if mr_list: if getattr(frappe.local, "reorder_email_notify", None) is None: diff --git a/erpnext/templates/pages/integrations/gocardless_checkout.py b/erpnext/templates/pages/integrations/gocardless_checkout.py index 280f67f16b..655be52c55 100644 --- a/erpnext/templates/pages/integrations/gocardless_checkout.py +++ b/erpnext/templates/pages/integrations/gocardless_checkout.py @@ -96,5 +96,5 @@ def check_mandate(data, reference_doctype, reference_docname): return {"redirect_to": redirect_flow.redirect_url} except Exception as e: - frappe.log_error(e, "GoCardless Payment Error") + frappe.log_error("GoCardless Payment Error") return {"redirect_to": "/integrations/payment-failed"} diff --git a/erpnext/templates/pages/integrations/gocardless_confirmation.py b/erpnext/templates/pages/integrations/gocardless_confirmation.py index cab532a530..559aa4806d 100644 --- a/erpnext/templates/pages/integrations/gocardless_confirmation.py +++ b/erpnext/templates/pages/integrations/gocardless_confirmation.py @@ -60,7 +60,7 @@ def confirm_payment(redirect_flow_id, reference_doctype, reference_docname): try: create_mandate(data) except Exception as e: - frappe.log_error(e, "GoCardless Mandate Registration Error") + frappe.log_error("GoCardless Mandate Registration Error") gateway_controller = get_gateway_controller(reference_docname) frappe.get_doc("GoCardless Settings", gateway_controller).create_payment_request(data) @@ -68,7 +68,7 @@ def confirm_payment(redirect_flow_id, reference_doctype, reference_docname): return {"redirect_to": confirmation_url} except Exception as e: - frappe.log_error(e, "GoCardless Payment Error") + frappe.log_error("GoCardless Payment Error") return {"redirect_to": "/integrations/payment-failed"} @@ -103,4 +103,4 @@ def create_mandate(data): ).insert(ignore_permissions=True) except Exception: - frappe.log_error(frappe.get_traceback()) + frappe.log_error("Gocardless: Unable to create mandate") diff --git a/erpnext/utilities/doctype/video/video.py b/erpnext/utilities/doctype/video/video.py index 330812dc27..a39d0a95eb 100644 --- a/erpnext/utilities/doctype/video/video.py +++ b/erpnext/utilities/doctype/video/video.py @@ -36,8 +36,7 @@ class Video(Document): self.comment_count = video_stats.get("commentCount") except Exception: - title = "Failed to Update YouTube Statistics for Video: {0}".format(self.name) - frappe.log_error(title + "\n\n" + frappe.get_traceback(), title=title) + self.log_error("Unable to update YouTube statistics") def is_tracking_enabled(): @@ -109,8 +108,7 @@ def batch_update_youtube_data(): video_stats = video.items return video_stats except Exception: - title = "Failed to Update YouTube Statistics" - frappe.log_error(title + "\n\n" + frappe.get_traceback(), title=title) + frappe.log_error("Unable to update YouTube statistics") def prepare_and_set_data(video_list): video_ids = get_formatted_ids(video_list) diff --git a/erpnext/utilities/doctype/video_settings/video_settings.py b/erpnext/utilities/doctype/video_settings/video_settings.py index 97fbc41934..9bc7972bb3 100644 --- a/erpnext/utilities/doctype/video_settings/video_settings.py +++ b/erpnext/utilities/doctype/video_settings/video_settings.py @@ -18,5 +18,5 @@ class VideoSettings(Document): build("youtube", "v3", developerKey=self.api_key) except Exception: title = _("Failed to Authenticate the API key.") - frappe.log_error(title + "\n\n" + frappe.get_traceback(), title=title) + self.log_error("Failed to authenticate API key") frappe.throw(title + " Please check the error logs.", title=_("Invalid Credentials")) From 59a50908436040d6fcb6d9cce1336197a00fe0bb Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 2 May 2022 15:11:14 +0530 Subject: [PATCH 100/106] fix(UX): misleading stock entry lables (#30870) * fix(UX): misleading stock entry lables * chore: field labels [skip ci] Co-authored-by: Marica Co-authored-by: Marica --- erpnext/stock/doctype/stock_entry/stock_entry.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.json b/erpnext/stock/doctype/stock_entry/stock_entry.json index c38dfaa1c8..f56e059f81 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.json +++ b/erpnext/stock/doctype/stock_entry/stock_entry.json @@ -46,9 +46,9 @@ "items", "get_stock_and_rate", "section_break_19", - "total_incoming_value", - "column_break_22", "total_outgoing_value", + "column_break_22", + "total_incoming_value", "value_difference", "additional_costs_section", "additional_costs", @@ -374,7 +374,7 @@ { "fieldname": "total_incoming_value", "fieldtype": "Currency", - "label": "Total Incoming Value", + "label": "Total Incoming Value (Receipt)", "options": "Company:company:default_currency", "print_hide": 1, "read_only": 1 @@ -386,7 +386,7 @@ { "fieldname": "total_outgoing_value", "fieldtype": "Currency", - "label": "Total Outgoing Value", + "label": "Total Outgoing Value (Consumption)", "options": "Company:company:default_currency", "print_hide": 1, "read_only": 1 @@ -394,7 +394,7 @@ { "fieldname": "value_difference", "fieldtype": "Currency", - "label": "Total Value Difference (Out - In)", + "label": "Total Value Difference (Incoming - Outgoing)", "options": "Company:company:default_currency", "print_hide_if_no_value": 1, "read_only": 1 @@ -619,7 +619,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2022-02-07 12:55:14.614077", + "modified": "2022-05-02 05:21:39.060501", "modified_by": "Administrator", "module": "Stock", "name": "Stock Entry", From b440dabe12adfa29c7c61d83a7e145b0c3882cf9 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 2 May 2022 16:09:48 +0530 Subject: [PATCH 101/106] test: Add test for payment reconciliation --- .../test_payment_reconciliation.py | 91 ++++++++++++++++++- 1 file changed, 89 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py index 2271f48a2b..d2374b77a6 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py @@ -1,9 +1,96 @@ # Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors # See license.txt -# import frappe import unittest +import frappe +from frappe.utils import add_days, getdate + +from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice + class TestPaymentReconciliation(unittest.TestCase): - pass + @classmethod + def setUpClass(cls): + make_customer() + make_invoice_and_payment() + + def test_payment_reconciliation(self): + payment_reco = frappe.get_doc("Payment Reconciliation") + payment_reco.company = "_Test Company" + payment_reco.party_type = "Customer" + payment_reco.party = "_Test Payment Reco Customer" + payment_reco.receivable_payable_account = "Debtors - _TC" + payment_reco.from_invoice_date = add_days(getdate(), -1) + payment_reco.to_invoice_date = getdate() + payment_reco.from_payment_date = add_days(getdate(), -1) + payment_reco.to_payment_date = getdate() + payment_reco.maximum_invoice_amount = 1000 + payment_reco.maximum_payment_amount = 1000 + payment_reco.invoice_limit = 10 + payment_reco.payment_limit = 10 + payment_reco.bank_cash_account = "_Test Bank - _TC" + payment_reco.cost_center = "_Test Cost Center - _TC" + payment_reco.get_unreconciled_entries() + + self.assertEqual(len(payment_reco.get("invoices")), 1) + self.assertEqual(len(payment_reco.get("payments")), 1) + + payment_entry = payment_reco.get("payments")[0].reference_name + invoice = payment_reco.get("invoices")[0].invoice_number + + payment_reco.allocate_entries( + { + "payments": [payment_reco.get("payments")[0].as_dict()], + "invoices": [payment_reco.get("invoices")[0].as_dict()], + } + ) + payment_reco.reconcile() + + payment_entry_doc = frappe.get_doc("Payment Entry", payment_entry) + self.assertEqual(payment_entry_doc.get("references")[0].reference_name, invoice) + + +def make_customer(): + if not frappe.db.get_value("Customer", "_Test Payment Reco Customer"): + frappe.get_doc( + { + "doctype": "Customer", + "customer_name": "_Test Payment Reco Customer", + "customer_type": "Individual", + "customer_group": "_Test Customer Group", + "territory": "_Test Territory", + } + ).insert() + + +def make_invoice_and_payment(): + si = create_sales_invoice( + customer="_Test Payment Reco Customer", qty=1, rate=690, do_not_save=True + ) + si.cost_center = "_Test Cost Center - _TC" + si.save() + si.submit() + + pe = frappe.get_doc( + { + "doctype": "Payment Entry", + "payment_type": "Receive", + "party_type": "Customer", + "party": "_Test Payment Reco Customer", + "company": "_Test Company", + "paid_from_account_currency": "INR", + "paid_to_account_currency": "INR", + "source_exchange_rate": 1, + "target_exchange_rate": 1, + "reference_no": "1", + "reference_date": getdate(), + "received_amount": 690, + "paid_amount": 690, + "paid_from": "Debtors - _TC", + "paid_to": "_Test Bank - _TC", + "cost_center": "_Test Cost Center - _TC", + } + ) + pe.insert() + pe.submit() From a31f577c9e5fcbb5c947699a2c5af3db2c99a70d Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sat, 30 Apr 2022 22:01:05 +0530 Subject: [PATCH 102/106] fix: Vat Audit report fixes (cherry picked from commit d5319a48269a4277818486e7ed74468e9107b8f4) --- .../vat_audit_report/vat_audit_report.py | 49 +++++++++++-------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/erpnext/regional/report/vat_audit_report/vat_audit_report.py b/erpnext/regional/report/vat_audit_report/vat_audit_report.py index 6e5982465c..70f2c0a333 100644 --- a/erpnext/regional/report/vat_audit_report/vat_audit_report.py +++ b/erpnext/regional/report/vat_audit_report/vat_audit_report.py @@ -95,10 +95,9 @@ class VATAuditReport(object): as_dict=1, ) for d in items: - if d.item_code not in self.invoice_items.get(d.parent, {}): - self.invoice_items.setdefault(d.parent, {}).setdefault(d.item_code, {"net_amount": 0.0}) - self.invoice_items[d.parent][d.item_code]["net_amount"] += d.get("base_net_amount", 0) - self.invoice_items[d.parent][d.item_code]["is_zero_rated"] = d.is_zero_rated + self.invoice_items.setdefault(d.parent, {}).setdefault(d.item_code, {"net_amount": 0.0}) + self.invoice_items[d.parent][d.item_code]["net_amount"] += d.get("base_net_amount", 0) + self.invoice_items[d.parent][d.item_code]["is_zero_rated"] = d.is_zero_rated def get_items_based_on_tax_rate(self, doctype): self.items_based_on_tax_rate = frappe._dict() @@ -110,7 +109,7 @@ class VATAuditReport(object): self.tax_details = frappe.db.sql( """ SELECT - parent, account_head, item_wise_tax_detail, base_tax_amount_after_discount_amount + parent, account_head, item_wise_tax_detail FROM `tab%s` WHERE @@ -123,7 +122,7 @@ class VATAuditReport(object): tuple([doctype] + list(self.invoices.keys())), ) - for parent, account, item_wise_tax_detail, tax_amount in self.tax_details: + for parent, account, item_wise_tax_detail in self.tax_details: if item_wise_tax_detail: try: if account in self.sa_vat_accounts: @@ -135,7 +134,7 @@ class VATAuditReport(object): # to skip items with non-zero tax rate in multiple rows if taxes[0] == 0 and not is_zero_rated: continue - tax_rate, item_amount_map = self.get_item_amount_map(parent, item_code, taxes) + tax_rate = self.get_item_amount_map(parent, item_code, taxes) if tax_rate is not None: rate_based_dict = self.items_based_on_tax_rate.setdefault(parent, {}).setdefault( @@ -151,16 +150,22 @@ class VATAuditReport(object): tax_rate = taxes[0] tax_amount = taxes[1] gross_amount = net_amount + tax_amount - item_amount_map = self.item_tax_rate.setdefault(parent, {}).setdefault(item_code, []) - amount_dict = { - "tax_rate": tax_rate, - "gross_amount": gross_amount, - "tax_amount": tax_amount, - "net_amount": net_amount, - } - item_amount_map.append(amount_dict) - return tax_rate, item_amount_map + self.item_tax_rate.setdefault(parent, {}).setdefault( + item_code, + { + "tax_rate": tax_rate, + "gross_amount": 0.0, + "tax_amount": 0.0, + "net_amount": 0.0, + }, + ) + + self.item_tax_rate[parent][item_code]["net_amount"] += net_amount + self.item_tax_rate[parent][item_code]["tax_amount"] += tax_amount + self.item_tax_rate[parent][item_code]["gross_amount"] += gross_amount + + return tax_rate def get_conditions(self): conditions = "" @@ -205,9 +210,10 @@ class VATAuditReport(object): for inv, inv_data in self.invoices.items(): if self.items_based_on_tax_rate.get(inv): for rate, items in self.items_based_on_tax_rate.get(inv).items(): + row = {"tax_amount": 0.0, "gross_amount": 0.0, "net_amount": 0.0} + consolidated_data_map.setdefault(rate, {"data": []}) for item in items: - row = {} item_details = self.item_tax_rate.get(inv).get(item) row["account"] = inv_data.get("account") row["posting_date"] = formatdate(inv_data.get("posting_date"), "dd-mm-yyyy") @@ -216,10 +222,11 @@ class VATAuditReport(object): row["party_type"] = "Customer" if doctype == "Sales Invoice" else "Supplier" row["party"] = inv_data.get("party") row["remarks"] = inv_data.get("remarks") - row["gross_amount"] = item_details[0].get("gross_amount") - row["tax_amount"] = item_details[0].get("tax_amount") - row["net_amount"] = item_details[0].get("net_amount") - consolidated_data_map[rate]["data"].append(row) + row["gross_amount"] += item_details.get("gross_amount") + row["tax_amount"] += item_details.get("tax_amount") + row["net_amount"] += item_details.get("net_amount") + + consolidated_data_map[rate]["data"].append(row) return consolidated_data_map From d7cb269e0c569eaf4e9793a44a313830983d4ee5 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 2 May 2022 19:23:43 +0530 Subject: [PATCH 103/106] fix: Supply type for overseas invoices with payment of tax --- erpnext/regional/india/e_invoice/utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py index 0f73c5f9bc..aaf850c5c6 100644 --- a/erpnext/regional/india/e_invoice/utils.py +++ b/erpnext/regional/india/e_invoice/utils.py @@ -129,7 +129,10 @@ def get_transaction_details(invoice): elif invoice.gst_category == "SEZ": supply_type = "SEZWOP" elif invoice.gst_category == "Overseas": - supply_type = "EXPWOP" + if invoice.export_type == "Without Payment of Tax": + supply_type = "EXPWOP" + else: + supply_type = "EXPWP" elif invoice.gst_category == "Deemed Export": supply_type = "DEXP" From c8aa77285e9498250d290152d501e5349715177f Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Mon, 2 May 2022 21:15:54 +0530 Subject: [PATCH 104/106] fix: supply type for sez invoices with payment of tax --- erpnext/regional/india/e_invoice/utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py index aaf850c5c6..0aff495f27 100644 --- a/erpnext/regional/india/e_invoice/utils.py +++ b/erpnext/regional/india/e_invoice/utils.py @@ -127,7 +127,10 @@ def get_transaction_details(invoice): if invoice.gst_category == "Registered Regular": supply_type = "B2B" elif invoice.gst_category == "SEZ": - supply_type = "SEZWOP" + if invoice.export_type == "Without Payment of Tax": + supply_type = "SEZWOP" + else: + supply_type = "SEZWP" elif invoice.gst_category == "Overseas": if invoice.export_type == "Without Payment of Tax": supply_type = "EXPWOP" From 80a13c38bc5ecb763c8de46c2f39fc602665ce5e Mon Sep 17 00:00:00 2001 From: maharshivpatel <39730881+maharshivpatel@users.noreply.github.com> Date: Mon, 2 May 2022 21:51:27 +0530 Subject: [PATCH 105/106] fix(india): e-invoice generation for registered composition gst category type (#30814) --- erpnext/regional/india/e_invoice/utils.py | 10 +++++++--- erpnext/regional/india/setup.py | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py index 0aff495f27..df3981a5e9 100644 --- a/erpnext/regional/india/e_invoice/utils.py +++ b/erpnext/regional/india/e_invoice/utils.py @@ -57,6 +57,7 @@ def validate_eligibility(doc): invalid_company = not frappe.db.get_value("E Invoice User", {"company": doc.get("company")}) invalid_supply_type = doc.get("gst_category") not in [ "Registered Regular", + "Registered Composition", "SEZ", "Overseas", "Deemed Export", @@ -124,7 +125,9 @@ def read_json(name): def get_transaction_details(invoice): supply_type = "" - if invoice.gst_category == "Registered Regular": + if ( + invoice.gst_category == "Registered Regular" or invoice.gst_category == "Registered Composition" + ): supply_type = "B2B" elif invoice.gst_category == "SEZ": if invoice.export_type == "Without Payment of Tax": @@ -140,14 +143,15 @@ def get_transaction_details(invoice): supply_type = "DEXP" if not supply_type: - rr, sez, overseas, export = ( + rr, rc, sez, overseas, export = ( bold("Registered Regular"), + bold("Registered Composition"), bold("SEZ"), bold("Overseas"), bold("Deemed Export"), ) frappe.throw( - _("GST category should be one of {}, {}, {}, {}").format(rr, sez, overseas, export), + _("GST category should be one of {}, {}, {}, {}, {}").format(rr, rc, sez, overseas, export), title=_("Invalid Supply Type"), ) diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index 062c2ef5c5..e41cd34c72 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -762,7 +762,7 @@ def get_custom_fields(): insert_after="customer", no_copy=1, print_hide=1, - depends_on='eval:in_list(["Registered Regular", "SEZ", "Overseas", "Deemed Export"], doc.gst_category) && doc.irn_cancelled === 0', + depends_on='eval:in_list(["Registered Regular", "Registered Composition", "SEZ", "Overseas", "Deemed Export"], doc.gst_category) && doc.irn_cancelled === 0', ), dict( fieldname="irn_cancelled", From 924cf7763e864b143da463f91f348d2ff5ac07e0 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Tue, 3 May 2022 11:27:25 +0530 Subject: [PATCH 106/106] fix: payment days calculation for employees joining/leaving mid-month (#30863) --- .../doctype/salary_slip/salary_slip.py | 14 +++- .../doctype/salary_slip/test_salary_slip.py | 78 +++++++++++++++++-- 2 files changed, 82 insertions(+), 10 deletions(-) diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.py b/erpnext/payroll/doctype/salary_slip/salary_slip.py index 192232949a..6a7f72b013 100644 --- a/erpnext/payroll/doctype/salary_slip/salary_slip.py +++ b/erpnext/payroll/doctype/salary_slip/salary_slip.py @@ -375,13 +375,19 @@ class SalarySlip(TransactionBase): if joining_date and (getdate(self.start_date) < joining_date <= getdate(self.end_date)): start_date = joining_date unmarked_days = self.get_unmarked_days_based_on_doj_or_relieving( - unmarked_days, include_holidays_in_total_working_days, self.start_date, joining_date + unmarked_days, + include_holidays_in_total_working_days, + self.start_date, + add_days(joining_date, -1), ) if relieving_date and (getdate(self.start_date) <= relieving_date < getdate(self.end_date)): end_date = relieving_date unmarked_days = self.get_unmarked_days_based_on_doj_or_relieving( - unmarked_days, include_holidays_in_total_working_days, relieving_date, self.end_date + unmarked_days, + include_holidays_in_total_working_days, + add_days(relieving_date, 1), + self.end_date, ) # exclude days for which attendance has been marked @@ -407,10 +413,10 @@ class SalarySlip(TransactionBase): from erpnext.hr.doctype.employee.employee import is_holiday if include_holidays_in_total_working_days: - unmarked_days -= date_diff(end_date, start_date) + unmarked_days -= date_diff(end_date, start_date) + 1 else: # exclude only if not holidays - for days in range(date_diff(end_date, start_date)): + for days in range(date_diff(end_date, start_date) + 1): date = add_days(end_date, -days) if not is_holiday(self.employee, date): unmarked_days -= 1 diff --git a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py index 869ea83f27..1bc3741922 100644 --- a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py +++ b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py @@ -128,6 +128,72 @@ class TestSalarySlip(unittest.TestCase): }, ) def test_payment_days_for_mid_joinee_including_holidays(self): + no_of_days = self.get_no_of_days() + month_start_date, month_end_date = get_first_day(nowdate()), get_last_day(nowdate()) + + new_emp_id = make_employee("test_payment_days_based_on_joining_date@salary.com") + joining_date, relieving_date = add_days(month_start_date, 3), add_days(month_end_date, -5) + + for days in range(date_diff(month_end_date, month_start_date) + 1): + date = add_days(month_start_date, days) + mark_attendance(new_emp_id, date, "Present", ignore_validate=True) + + # Case 1: relieving in mid month + frappe.db.set_value( + "Employee", + new_emp_id, + {"date_of_joining": month_start_date, "relieving_date": relieving_date, "status": "Active"}, + ) + + new_ss = make_employee_salary_slip( + "test_payment_days_based_on_joining_date@salary.com", + "Monthly", + "Test Payment Based On Attendence", + ) + self.assertEqual(new_ss.payment_days, no_of_days[0] - 5) + + # Case 2: joining in mid month + frappe.db.set_value( + "Employee", + new_emp_id, + {"date_of_joining": joining_date, "relieving_date": month_end_date, "status": "Active"}, + ) + + frappe.delete_doc("Salary Slip", new_ss.name, force=True) + new_ss = make_employee_salary_slip( + "test_payment_days_based_on_joining_date@salary.com", + "Monthly", + "Test Payment Based On Attendence", + ) + self.assertEqual(new_ss.payment_days, no_of_days[0] - 3) + + # Case 3: joining and relieving in mid-month + frappe.db.set_value( + "Employee", + new_emp_id, + {"date_of_joining": joining_date, "relieving_date": relieving_date, "status": "Left"}, + ) + + frappe.delete_doc("Salary Slip", new_ss.name, force=True) + new_ss = make_employee_salary_slip( + "test_payment_days_based_on_joining_date@salary.com", + "Monthly", + "Test Payment Based On Attendence", + ) + + self.assertEqual(new_ss.total_working_days, no_of_days[0]) + self.assertEqual(new_ss.payment_days, no_of_days[0] - 8) + + @change_settings( + "Payroll Settings", + { + "payroll_based_on": "Attendance", + "consider_unmarked_attendance_as": "Absent", + "include_holidays_in_total_working_days": True, + }, + ) + def test_payment_days_for_mid_joinee_including_holidays_and_unmarked_days(self): + # tests mid month joining and relieving along with unmarked days from erpnext.hr.doctype.holiday_list.holiday_list import is_holiday no_of_days = self.get_no_of_days() @@ -135,12 +201,6 @@ class TestSalarySlip(unittest.TestCase): new_emp_id = make_employee("test_payment_days_based_on_joining_date@salary.com") joining_date, relieving_date = add_days(month_start_date, 3), add_days(month_end_date, -5) - frappe.db.set_value( - "Employee", - new_emp_id, - {"date_of_joining": joining_date, "relieving_date": relieving_date, "status": "Left"}, - ) - holidays = 0 for days in range(date_diff(relieving_date, joining_date) + 1): @@ -150,6 +210,12 @@ class TestSalarySlip(unittest.TestCase): else: holidays += 1 + frappe.db.set_value( + "Employee", + new_emp_id, + {"date_of_joining": joining_date, "relieving_date": relieving_date, "status": "Left"}, + ) + new_ss = make_employee_salary_slip( "test_payment_days_based_on_joining_date@salary.com", "Monthly",