add the fee schedule in config
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index d39fd20..e663983 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -403,9 +403,9 @@
"against": against_account,
"account_currency": self.party_account_currency
})
-
+
dr_or_cr = "credit" if self.party_type in ["Customer", "Student"] else "debit"
-
+
for d in self.get("references"):
gle = party_gl_dict.copy()
gle.update({
@@ -530,7 +530,7 @@
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"), party_account_currency, company_currency)
-
+
return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency):
diff --git a/erpnext/config/schools.py b/erpnext/config/schools.py
index b984578..dbdcd35 100644
--- a/erpnext/config/schools.py
+++ b/erpnext/config/schools.py
@@ -156,6 +156,10 @@
},
{
"type": "doctype",
+ "name": "Fee Schedule"
+ },
+ {
+ "type": "doctype",
"name": "Fee Structure"
},
{
diff --git a/erpnext/schools/doctype/fee_schedule/fee_schedule.js b/erpnext/schools/doctype/fee_schedule/fee_schedule.js
index 9e5a156..757355d 100644
--- a/erpnext/schools/doctype/fee_schedule/fee_schedule.js
+++ b/erpnext/schools/doctype/fee_schedule/fee_schedule.js
@@ -3,9 +3,16 @@
frappe.ui.form.on('Fee Schedule', {
setup: function(frm) {
- frm.add_fetch("company", "default_receivable_account", "debit_to");
- frm.add_fetch("company", "default_income_account", "against_income_account");
- frm.add_fetch("company", "cost_center", "cost_center");
+ frm.add_fetch("fee_structure", "default_receivable_account", "debit_to");
+ frm.add_fetch("fee_structure", "default_income_account", "against_income_account");
+ frm.add_fetch("fee_structure", "cost_center", "cost_center");
+
+ frm.set_query("student_group", "student_groups", function() {
+ return {
+ "program": frm.doc.program,
+ "academic_year": frm.doc.academic_year
+ };
+ });
},
refresh: function(frm) {
@@ -47,20 +54,20 @@
}
});
-frappe.ui.form.on("Fee Component", {
- refresh: function(frm) {
- frm.set_read_only();
- }
-});
-
frappe.ui.form.on("Fee Schedule Student Group", {
- onload: function(frm) {
- frm.set_query("student_group",function(){
- return{
- "filters":{
- "group_based_on": "Batch"
+ student_group: function(frm, cdt, cdn) {
+ var row = locals[cdt][cdn];
+ frappe.call({
+ method: "erpnext.schools.doctype.fee_schedule.fee_schedule.get_total_students",
+ args: {
+ "student_group": row.student_group,
+ "student_category": frm.doc.student_category
+ },
+ callback: function(r) {
+ if(!r.exc) {
+ frappe.model.set_value(cdt, cdn, "total_students", r.message);
}
- };
- });
+ }
+ })
}
-});
+})
\ No newline at end of file
diff --git a/erpnext/schools/doctype/fee_schedule/fee_schedule.json b/erpnext/schools/doctype/fee_schedule/fee_schedule.json
index c1fb2ec..7215603 100644
--- a/erpnext/schools/doctype/fee_schedule/fee_schedule.json
+++ b/erpnext/schools/doctype/fee_schedule/fee_schedule.json
@@ -171,6 +171,68 @@
"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": 0,
+ "in_list_view": 0,
+ "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": 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": "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": 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": "academic_year",
"fieldtype": "Link",
"hidden": 0,
@@ -188,7 +250,7 @@
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -219,7 +281,7 @@
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -315,7 +377,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 0,
+ "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -937,7 +999,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-08-23 15:58:34.051237",
+ "modified": "2017-09-07 12:36:02.678355",
"modified_by": "Administrator",
"module": "Schools",
"name": "Fee Schedule",
diff --git a/erpnext/schools/doctype/fee_schedule/fee_schedule.py b/erpnext/schools/doctype/fee_schedule/fee_schedule.py
index 80165f4..822a62d 100644
--- a/erpnext/schools/doctype/fee_schedule/fee_schedule.py
+++ b/erpnext/schools/doctype/fee_schedule/fee_schedule.py
@@ -34,7 +34,7 @@
no_of_students = 0
for d in self.student_groups:
# if not d.total_students:
- d.total_students = get_total_students(d.student_group)
+ d.total_students = get_total_students(d.student_group, self.student_category)
no_of_students += cint(d.total_students)
self.grand_total = no_of_students*self.total_amount
self.grand_total_in_words = money_in_words(self.grand_total)
@@ -44,7 +44,7 @@
self.fee_creation_status = "In Process"
enqueue(generate_fee, queue='default', timeout=6000, event='generate_fee',
fee_schedule=self.name)
- frappe.msgprint(_("Fee generation started"))
+ frappe.msgprint(_("Fee records will be created in the background. In case of any error, the error message will be updated in the Schedule, check after refresh in 5 minutes."))
def generate_fee(fee_schedule):
@@ -84,7 +84,6 @@
frappe.db.set_value("Fee Schedule", fee_schedule, "error_log", err_msg)
else:
- frappe.db.commit()
frappe.db.set_value("Fee Schedule", fee_schedule, "fee_creation_status", "Successful")
frappe.db.set_value("Fee Schedule", fee_schedule, "error_log", None)
@@ -98,7 +97,17 @@
return fee_request
@frappe.whitelist()
-def get_total_students(student_group):
- students = frappe.get_all("Student Group Student",
- filters={"parent": student_group, "parenttype": "Student Group", "active": 1}) or []
- return len(students)
\ No newline at end of file
+def get_total_students(student_group, student_category=None):
+ conditions = ""
+ if student_category:
+ conditions = " and s.student_category='{}'".format(frappe.db.escape(student_category))
+
+ return frappe.db.sql("""
+ select count(s.name)
+ from `tabStudent` s, `tabStudent Group Student` sgs
+ where
+ s.name = sgs.student
+ and sgs.parent = %s
+ and sgs.active = 1
+ {conditions}
+ """.format(conditions=conditions), student_group)[0][0]
diff --git a/erpnext/schools/doctype/fee_structure/fee_structure.js b/erpnext/schools/doctype/fee_structure/fee_structure.js
index 7619cf5..78b8588 100644
--- a/erpnext/schools/doctype/fee_structure/fee_structure.js
+++ b/erpnext/schools/doctype/fee_structure/fee_structure.js
@@ -16,6 +16,21 @@
}
};
});
+ },
+
+ refresh: function(frm) {
+ if(frm.doc.docstatus === 1) {
+ frm.add_custom_button(__("Make Fee Schedule"), function() {
+ frm.events.make_fee_schedule(frm);
+ });
+ }
+ },
+
+ make_fee_schedule: function(frm) {
+ frappe.model.open_mapped_doc({
+ method: "erpnext.schools.doctype.fee_structure.fee_structure.make_fee_schedule",
+ frm: frm
+ });
}
});
diff --git a/erpnext/schools/doctype/fee_structure/fee_structure.json b/erpnext/schools/doctype/fee_structure/fee_structure.json
index da8d7c9..c3df7bb6 100644
--- a/erpnext/schools/doctype/fee_structure/fee_structure.json
+++ b/erpnext/schools/doctype/fee_structure/fee_structure.json
@@ -564,6 +564,36 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
+ },
+ {
+ "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": "Fee Structure",
+ "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
}
],
"has_web_view": 0,
@@ -573,12 +603,12 @@
"idx": 0,
"image_view": 0,
"in_create": 0,
- "is_submittable": 0,
+ "is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2017-08-02 16:31:35.861158",
+ "modified": "2017-09-07 12:04:14.807690",
"modified_by": "Administrator",
"module": "Schools",
"name": "Fee Structure",
@@ -586,15 +616,15 @@
"owner": "Administrator",
"permissions": [
{
- "amend": 0,
+ "amend": 1,
"apply_user_permissions": 0,
- "cancel": 0,
+ "cancel": 1,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
- "import": 0,
+ "import": 1,
"permlevel": 0,
"print": 1,
"read": 1,
@@ -602,7 +632,7 @@
"role": "Academics User",
"set_user_permissions": 0,
"share": 1,
- "submit": 0,
+ "submit": 1,
"write": 1
}
],
diff --git a/erpnext/schools/doctype/fee_structure/fee_structure.py b/erpnext/schools/doctype/fee_structure/fee_structure.py
index b71c507..781382b 100644
--- a/erpnext/schools/doctype/fee_structure/fee_structure.py
+++ b/erpnext/schools/doctype/fee_structure/fee_structure.py
@@ -5,6 +5,8 @@
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
+from frappe.model.mapper import get_mapped_doc
+
class FeeStructure(Document):
def validate(self):
@@ -16,3 +18,17 @@
for d in self.components:
self.total_amount += d.amount
+
+@frappe.whitelist()
+def make_fee_schedule(source_name, target_doc=None):
+ return get_mapped_doc("Fee Structure", source_name, {
+ "Fee Structure": {
+ "doctype": "Fee Schedule",
+ "validation": {
+ "docstatus": ["=", 1],
+ }
+ },
+ "Fee Component": {
+ "doctype": "Fee Component"
+ }
+ }, target_doc)
\ No newline at end of file
diff --git a/erpnext/schools/doctype/fee_structure/test_fee_structure.js b/erpnext/schools/doctype/fee_structure/test_fee_structure.js
new file mode 100644
index 0000000..61f4135
--- /dev/null
+++ b/erpnext/schools/doctype/fee_structure/test_fee_structure.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Fee Structure", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Fee Structure
+ () => frappe.tests.make('Fee Structure', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/schools/doctype/fees/fees.py b/erpnext/schools/doctype/fees/fees.py
index 2e1a49b..ac5564e 100644
--- a/erpnext/schools/doctype/fees/fees.py
+++ b/erpnext/schools/doctype/fees/fees.py
@@ -10,7 +10,6 @@
from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request
from frappe.utils.csvutils import getlink
from erpnext.controllers.accounts_controller import AccountsController
-from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
from erpnext.accounts.general_ledger import delete_gl_entries