diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 1065d6bee1..734c8e8ca2 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import frappe -__version__ = '8.0.16' +__version__ = '8.0.17' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index b9b8fc2968..34d9de7064 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -514,7 +514,7 @@ class JournalEntry(AccountsController): def update_expense_claim(self): for d in self.accounts: - if d.reference_type=="Expense Claim" and d.party: + if d.reference_type=="Expense Claim" and d.reference_name: doc = frappe.get_doc("Expense Claim", d.reference_name) update_reimbursed_amount(doc) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js index 9bc5c2f2c1..f98d0378ed 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js @@ -16,6 +16,21 @@ frappe.query_reports["Accounts Receivable"] = { "fieldtype": "Link", "options": "Customer" }, + { + "fieldname":"customer_group", + "label": __("Customer Group"), + "fieldtype": "Link", + "options": "Customer Group" + }, + { + "fieldname":"credit_days_based_on", + "label": __("Credit Days Based On"), + "fieldtype": "Select", + "options": "" + NEWLINE + "Fixed Days" + NEWLINE + "Last Day of the Next Month" + }, + { + "fieldtype": "Break", + }, { "fieldname":"report_date", "label": __("As on Date"), @@ -29,9 +44,6 @@ frappe.query_reports["Accounts Receivable"] = { "options": 'Posting Date' + NEWLINE + 'Due Date', "default": "Posting Date" }, - { - "fieldtype": "Break", - }, { "fieldname":"range1", "label": __("Ageing Range 1"), diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index 6d1e1686d1..62d0d5a167 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -71,7 +71,10 @@ class ReceivablePayableReport(object): "width": 100 }) if args.get("party_type") == "Customer": - columns += [_("Territory") + ":Link/Territory:80"] + columns += [ + _("Territory") + ":Link/Territory:80", + _("Customer Group") + ":Link/Customer Group:120" + ] if args.get("party_type") == "Supplier": columns += [_("Supplier Type") + ":Link/Supplier Type:80"] @@ -139,7 +142,7 @@ class ReceivablePayableReport(object): # customer territory / supplier type if args.get("party_type") == "Customer": - row += [self.get_territory(gle.party)] + row += [self.get_territory(gle.party), self.get_customer_group(gle.party)] if args.get("party_type") == "Supplier": row += [self.get_supplier_type(gle.party)] @@ -186,6 +189,9 @@ class ReceivablePayableReport(object): def get_territory(self, party_name): return self.get_party_map("Customer").get(party_name, {}).get("territory") or "" + + def get_customer_group(self, party_name): + return self.get_party_map("Customer").get(party_name, {}).get("customer_group") or "" def get_supplier_type(self, party_name): return self.get_party_map("Supplier").get(party_name, {}).get("supplier_type") or "" @@ -193,12 +199,12 @@ class ReceivablePayableReport(object): def get_party_map(self, party_type): if not hasattr(self, "party_map"): if party_type == "Customer": - self.party_map = dict(((r.name, r) for r in frappe.db.sql("""select {0}, {1}, {2} from `tab{3}`""" - .format("name", "customer_name", "territory", party_type), as_dict=True))) - + select_fields = "name, customer_name, territory, customer_group" elif party_type == "Supplier": - self.party_map = dict(((r.name, r) for r in frappe.db.sql("""select {0}, {1}, {2} from `tab{3}`""" - .format("name", "supplier_name", "supplier_type", party_type), as_dict=True))) + select_fields = "name, supplier_name, supplier_type" + + self.party_map = dict(((r.name, r) for r in frappe.db.sql("select {0} from `tab{1}`" + .format(select_fields, party_type), as_dict=True))) return self.party_map @@ -251,6 +257,19 @@ class ReceivablePayableReport(object): conditions.append("party=%s") values.append(self.filters.get(party_type_field)) + if party_type_field=="customer": + if self.filters.get("customer_group"): + lft, rgt = frappe.db.get_value("Customer Group", + self.filters.get("customer_group"), ["lft", "rgt"]) + + conditions.append("""party in (select name from tabCustomer + where exists(select name from `tabCustomer Group` where lft >= {0} and rgt <= {1} + and name=tabCustomer.customer_group))""".format(lft, rgt)) + + if self.filters.get("credit_days_based_on"): + conditions.append("party in (select name from tabCustomer where credit_days_based_on=%s)") + values.append(self.filters.get("credit_days_based_on")) + return " and ".join(conditions), values def get_gl_entries_for(self, party, party_type, against_voucher_type, against_voucher): diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js index 5cc0566717..a18c1a7e79 100644 --- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js +++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js @@ -16,6 +16,21 @@ frappe.query_reports["Accounts Receivable Summary"] = { "fieldtype": "Link", "options": "Customer" }, + { + "fieldname":"customer_group", + "label": __("Customer Group"), + "fieldtype": "Link", + "options": "Customer Group" + }, + { + "fieldname":"credit_days_based_on", + "label": __("Credit Days Based On"), + "fieldtype": "Select", + "options": "" + NEWLINE + "Fixed Days" + NEWLINE + "Last Day of the Next Month" + }, + { + "fieldtype": "Break", + }, { "fieldname":"report_date", "label": __("Date"), @@ -29,9 +44,6 @@ frappe.query_reports["Accounts Receivable Summary"] = { "options": 'Posting Date' + NEWLINE + 'Due Date', "default": "Posting Date" }, - { - "fieldtype": "Break", - }, { "fieldname":"range1", "label": __("Ageing Range 1"), diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py index 8c627b659d..81bcccb281 100644 --- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py +++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py @@ -27,7 +27,10 @@ class AccountsReceivableSummary(ReceivablePayableReport): str(self.filters.range3) + _("-Above") + ":Currency/currency:100"] if args.get("party_type") == "Customer": - columns += [_("Territory") + ":Link/Territory:80"] + columns += [ + _("Territory") + ":Link/Territory:80", + _("Customer Group") + ":Link/Customer Group:120" + ] if args.get("party_type") == "Supplier": columns += [_("Supplier Type") + ":Link/Supplier Type:80"] @@ -58,7 +61,7 @@ class AccountsReceivableSummary(ReceivablePayableReport): ] if args.get("party_type") == "Customer": - row += [self.get_territory(party)] + row += [self.get_territory(party), self.get_customer_group(party)] if args.get("party_type") == "Supplier": row += [self.get_supplier_type(party)] @@ -107,7 +110,7 @@ class AccountsReceivableSummary(ReceivablePayableReport): if args.get("party_type") == "Supplier": cols += ["supplier_type", "remarks"] if args.get("party_type") == "Customer": - cols += ["territory", "remarks"] + cols += ["territory", "customer_group", "remarks"] return self.make_data_dict(cols, voucherwise_data) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 854f302274..2c1448c8b3 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -4,13 +4,13 @@ from __future__ import unicode_literals import frappe +import frappe.defaults from frappe.utils import nowdate, cstr, flt, cint, now, getdate from frappe import throw, _ -from frappe.utils import formatdate +from frappe.utils import formatdate, get_number_format_info # imported to enable erpnext.accounts.utils.get_account_currency from erpnext.accounts.doctype.account.account import get_account_currency -import frappe.defaults from erpnext.accounts.report.financial_statements import sort_root_accounts class FiscalYearError(frappe.ValidationError): pass @@ -537,15 +537,14 @@ def get_stock_and_account_difference(account_list=None, posting_date=None): return difference -def get_currency_precision(currency=None): - if not currency: - currency = frappe.db.get_value("Company", - frappe.db.get_default("Company"), "default_currency", cache=True) - currency_format = frappe.db.get_value("Currency", currency, "number_format", cache=True) - - from frappe.utils import get_number_format_info - return get_number_format_info(currency_format)[2] - +def get_currency_precision(): + precision = cint(frappe.db.get_default("currency_precision")) + if not precision: + number_format = frappe.db.get_default("number_format") or "#,###.##" + precision = get_number_format_info(number_format)[2] + + return precision + def get_stock_rbnb_difference(posting_date, company): stock_items = frappe.db.sql_list("""select distinct item_code from `tabStock Ledger Entry` where company=%s""", company) diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json index 0037745817..b269cb8019 100755 --- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json +++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json @@ -800,7 +800,7 @@ "oldfieldtype": "Currency", "options": "Company:company:default_currency", "permlevel": 0, - "precision": "9", + "precision": "", "print_hide": 1, "print_hide_if_no_value": 0, "print_width": "100px", @@ -1659,7 +1659,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2017-04-18 18:49:08.604055", + "modified": "2017-04-25 18:49:08.604055", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order Item", diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js index 496120888d..95877cf032 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.js +++ b/erpnext/hr/doctype/expense_claim/expense_claim.js @@ -18,14 +18,20 @@ erpnext.hr.ExpenseClaimController = frappe.ui.form.Controller.extend({ }); }, - expense_type: function(frm, cdt, cdn) { + expense_type: function(doc, cdt, cdn) { var d = locals[cdt][cdn]; + if(!doc.company) { + d.expense_type = ""; + frappe.msgprint(__("Please set the Company")); + this.frm.refresh_fields() + return; + } return frappe.call({ method: "erpnext.hr.doctype.expense_claim.expense_claim.get_expense_claim_account", args: { "expense_claim_type": d.expense_type, - "company": frm.company + "company": doc.company }, callback: function(r) { if (r.message) { diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 111cd65dc2..d68a1d82a5 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -389,3 +389,4 @@ erpnext.patches.v8_0.rename_is_sample_item_to_allow_zero_valuation_rate erpnext.patches.v8_0.set_null_to_serial_nos_for_disabled_sales_invoices erpnext.patches.v8_0.enable_booking_asset_depreciation_automatically erpnext.patches.v8_0.set_project_copied_from +erpnext.patches.v8_0.update_status_as_paid_for_completed_expense_claim diff --git a/erpnext/patches/v8_0/update_status_as_paid_for_completed_expense_claim.py b/erpnext/patches/v8_0/update_status_as_paid_for_completed_expense_claim.py new file mode 100644 index 0000000000..644b8cd035 --- /dev/null +++ b/erpnext/patches/v8_0/update_status_as_paid_for_completed_expense_claim.py @@ -0,0 +1,17 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + """ set status as Paid in Expense Claim if total_sactioned_amount + and total_amount_reimbursed is equal """ + + frappe.db.sql(""" + update + `tabExpense Claim` + set status = 'Paid' + where + total_sanctioned_amount = total_amount_reimbursed + """) \ No newline at end of file diff --git a/erpnext/public/css/erpnext.css b/erpnext/public/css/erpnext.css index 7b6e5a1e99..fd240064ca 100644 --- a/erpnext/public/css/erpnext.css +++ b/erpnext/public/css/erpnext.css @@ -297,6 +297,9 @@ body[data-route="pos"] .item-list { body[data-route="pos"] .item-list .image-field { height: 140px; } +body[data-route="pos"] .item-list .image-field .placeholder-text { + font-size: 50px; +} body[data-route="pos"] .item-list .pos-item-wrapper { position: relative; } diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less index c06bdf9e69..0431848f86 100644 --- a/erpnext/public/less/erpnext.less +++ b/erpnext/public/less/erpnext.less @@ -351,6 +351,10 @@ body[data-route="pos"] { .image-field { height: 140px; + + .placeholder-text { + font-size: 50px; + } } .pos-item-wrapper { diff --git a/erpnext/schools/doctype/assessment_plan/assessment_plan.js b/erpnext/schools/doctype/assessment_plan/assessment_plan.js index cafe3a10e8..b1e87687ff 100644 --- a/erpnext/schools/doctype/assessment_plan/assessment_plan.js +++ b/erpnext/schools/doctype/assessment_plan/assessment_plan.js @@ -11,7 +11,8 @@ frappe.ui.form.on("Assessment Plan", { if (frm.doc.docstatus == 1) { frm.add_custom_button(__("Assessment Result"), function() { frappe.route_options = { - assessment_plan: frm.doc.name + assessment_plan: frm.doc.name, + student_batch: frm.doc.student_batch } frappe.set_route("Form", "Assessment Result Tool"); }); diff --git a/erpnext/schools/doctype/assessment_plan/assessment_plan.json b/erpnext/schools/doctype/assessment_plan/assessment_plan.json index a5bcc705c5..042bdaf774 100644 --- a/erpnext/schools/doctype/assessment_plan/assessment_plan.json +++ b/erpnext/schools/doctype/assessment_plan/assessment_plan.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 0, "autoname": "field:assessment_name", @@ -13,6 +14,7 @@ "engine": "InnoDB", "fields": [ { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -42,36 +44,7 @@ "unique": 0 }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "assessment_code", - "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 Code", - "length": 0, - "no_copy": 0, - "options": "Assessment Code", - "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, @@ -102,209 +75,7 @@ "unique": 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_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": 1, - "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": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "maximum_assessment_score", - "fieldtype": "Float", - "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": "Maximum Assessment 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 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "grading_scale", - "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": "Grading Scale", - "length": 0, - "no_copy": 0, - "options": "Grading Scale", - "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": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_10", - "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_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": 1, - "in_list_view": 1, - "in_standard_filter": 1, - "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": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_10", - "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, @@ -335,6 +106,159 @@ "unique": 0 }, { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "student_group", + "fieldtype": "Link", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 1, + "in_list_view": 1, + "in_standard_filter": 1, + "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": 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": "course", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 1, + "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": 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": "maximum_assessment_score", + "fieldtype": "Float", + "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": "Maximum Assessment 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 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "grading_scale", + "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": "Grading Scale", + "length": 0, + "no_copy": 0, + "options": "Grading Scale", + "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, @@ -366,6 +290,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -396,6 +321,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -426,6 +352,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -456,6 +383,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -485,6 +413,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -513,6 +442,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -542,6 +472,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -571,6 +502,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -601,6 +533,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -630,6 +563,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -658,6 +592,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -688,6 +623,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -717,18 +653,18 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "idx": 0, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 1, "issingle": 0, "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2017-02-13 19:34:09.724549", + "modified": "2017-04-25 12:23:32.528982", "modified_by": "Administrator", "module": "Schools", "name": "Assessment Plan", diff --git a/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js index 6967a7d293..213111ac4d 100644 --- a/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js +++ b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js @@ -1,3 +1,4 @@ + // Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt @@ -5,19 +6,16 @@ cur_frm.add_fetch("assessment_plan", "student_group", "student_group"); cur_frm.add_fetch("assessment_plan", "student_batch", "student_batch"); frappe.ui.form.on('Assessment Result Tool', { - - onload: function(frm) { + refresh: function(frm) { if (frappe.route_options) { - frm.doc.assessment_plan = frappe.route_options.assessment_plan; + frm.set_value("student_batch", frappe.route_options.student_batch); + frm.set_value("assessment_plan", frappe.route_options.assessment_plan); frappe.route_options = null; } + frm.disable_save(); + frm.page.clear_indicator(); }, - refresh: function(frm) { - frm.disable_save(); - frm.page.clear_indicator(); - }, - assessment_plan: function(frm) { if(!(frm.doc.student_batch || frm.doc.student_group)) return; frappe.call({ diff --git a/erpnext/schools/doctype/course_schedule/course_schedule.py b/erpnext/schools/doctype/course_schedule/course_schedule.py index 7550ab1c47..d12ae9dfbf 100644 --- a/erpnext/schools/doctype/course_schedule/course_schedule.py +++ b/erpnext/schools/doctype/course_schedule/course_schedule.py @@ -13,7 +13,6 @@ class CourseSchedule(Document): self.set_title() self.validate_mandatory() self.validate_course() - self.set_student_batch() self.validate_date() self.validate_overlap() diff --git a/erpnext/schools/doctype/course_schedule/test_course_schedule.py b/erpnext/schools/doctype/course_schedule/test_course_schedule.py index 795486a888..6a3456fefc 100644 --- a/erpnext/schools/doctype/course_schedule/test_course_schedule.py +++ b/erpnext/schools/doctype/course_schedule/test_course_schedule.py @@ -24,28 +24,28 @@ class TestCourseSchedule(unittest.TestCase): 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="TC1-TP2--2014-2015-2014-2015 (_Test Academic Term)", room="RM0002", do_not_save= 1) + student_group="Course-TC101-2014-2015 (_Test Academic Term)", room="RM0002", 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="TC1-TP2--2014-2015-2014-2015 (_Test Academic Term)", instructor="_T-Instructor-00002", do_not_save= 1) + student_group="Course-TC101-2014-2015 (_Test Academic Term)", instructor="_T-Instructor-00002", 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="TC1-TP2-2014-2015-2014-2015 (_Test Academic Term)", instructor="_T-Instructor-00002", room="RM0002") + student_group="Course-TC102-2014-2015 (_Test Academic Term)", instructor="_T-Instructor-00002", room="RM0002") 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 "TC-TP1-2014-2015-2014-2015 (_Test Academic Term)" - course_schedule.course = args.course or "TC100" + 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 "_T-Instructor-00001" course_schedule.room = args.room or "RM0001" diff --git a/erpnext/schools/doctype/student_batch_name/test_records.json b/erpnext/schools/doctype/student_batch_name/test_records.json new file mode 100644 index 0000000000..bf365c638a --- /dev/null +++ b/erpnext/schools/doctype/student_batch_name/test_records.json @@ -0,0 +1,8 @@ +[ + { + "batch_name": "_Batch 1" + }, + { + "batch_name": "_Batch 2" + } +] \ No newline at end of file diff --git a/erpnext/schools/doctype/student_group/student_group.js b/erpnext/schools/doctype/student_group/student_group.js index 595fa08d9d..2068644ea0 100644 --- a/erpnext/schools/doctype/student_group/student_group.js +++ b/erpnext/schools/doctype/student_group/student_group.js @@ -1,19 +1,23 @@ 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) + } + }; + }); + }, + refresh: function(frm) { if (!frm.doc.__islocal) { frm.add_custom_button(__("Course Schedule"), function() { - frappe.route_options = { - student_group: frm.doc.name - } frappe.set_route("List", "Course Schedule"); }); frm.add_custom_button(__("Assessment Plan"), function() { - frappe.route_options = { - student_group: frm.doc.name - } frappe.set_route("List", "Assessment Plan"); }); frm.add_custom_button(__("Update Email Group"), function() { @@ -30,19 +34,84 @@ frappe.ui.form.on("Student Group", { }); } }, + + group_based_on: function(frm) { + if (frm.doc.group_based_on == "Batch") { + frm.doc.course = null; + } + else if (frm.doc.group_based_on == "Course") { + frm.doc.program = null; + frm.doc.batch = null; + } + frm.trigger("set_name"); + }, - onload: function(frm) { - frm.set_query("academic_term", function() { - return { - "filters": { - "academic_year": (frm.doc.academic_year) + set_name: function(frm) { + var name; + if (frm.doc.group_based_on == "Course") { + name = "Course-" + frm.doc.course + "-" + (frm.doc.academic_term?frm.doc.academic_term:frm.doc.academic_year); + } else if (frm.doc.group_based_on == "Batch") { + name = "Batch-" + frm.doc.program + "-" + frm.doc.batch + "-" + + (frm.doc.academic_term?frm.doc.academic_term:frm.doc.academic_year); + } else if (frm.doc.group_based_on == "Activity") { + name = "Activity" + "-" + (frm.doc.academic_term?frm.doc.academic_term:frm.doc.academic_year); + } + frm.set_value("student_group_name", name); + }, + + program:function(frm) { + frm.trigger("set_name"); + }, + + batch:function(frm) { + frm.trigger("set_name"); + }, + + course:function(frm) { + frm.trigger("set_name"); + }, + + get_students: function(frm) { + if (frm.doc.group_based_on != "Activity") { + 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; } - }; - }); + }); + frappe.call({ + method: "erpnext.schools.doctype.student_group.student_group.get_students", + args: { + "academic_year": frm.doc.academic_year, + "group_based_on": frm.doc.group_based_on, + "program": frm.doc.program, + "batch" : frm.doc.batch, + "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; + } + }); + frm.save(); + } else { + frappe.msgprint(__("Student Group is already updated.")) + } + } + }) + } else { + frappe.msgprint(__("Select students manually for the Activity based Group")); + } } -}); -//If Student Batch is entered, deduce program, academic_year and academic term from it -cur_frm.add_fetch("student_batch", "program", "program"); -cur_frm.add_fetch("student_batch", "academic_term", "academic_term"); -cur_frm.add_fetch("student_batch", "academic_year", "academic_year"); \ No newline at end of file +}); \ No newline at end of file diff --git a/erpnext/schools/doctype/student_group/student_group.json b/erpnext/schools/doctype/student_group/student_group.json index cf42e2437f..59c5eab053 100644 --- a/erpnext/schools/doctype/student_group/student_group.json +++ b/erpnext/schools/doctype/student_group/student_group.json @@ -1,8 +1,9 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 1, - "autoname": "", + "autoname": "field:student_group_name", "beta": 0, "creation": "2015-09-07 12:55:52.072792", "custom": 0, @@ -13,36 +14,7 @@ "engine": "InnoDB", "fields": [ { - "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": 1, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Student Batch", - "length": 0, - "no_copy": 0, - "options": "Student Batch", - "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, @@ -54,7 +26,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 1, + "in_list_view": 0, "in_standard_filter": 1, "label": "Academic Year", "length": 0, @@ -73,111 +45,24 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "academic_term", - "fieldtype": "Link", + "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": 1, - "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": 1, - "unique": 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, + "label": "Group Based on", "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_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": 1, - "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": 1, - "unique": 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": 1, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Course", - "length": 0, - "no_copy": 0, - "options": "Course", + "options": "\nBatch\nCourse\nActivity", "permlevel": 0, "precision": "", "print_hide": 0, @@ -191,6 +76,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -221,11 +107,200 @@ "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_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": 1, + "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": 1, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.group_based_on == 'Batch'", + "fieldname": "program", + "fieldtype": "Link", + "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": "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": 1, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.group_based_on == 'Batch'", + "fieldname": "batch", + "fieldtype": "Link", + "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": "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": 1, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.group_based_on == 'Course'", + "fieldname": "course", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 1, + "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": 1, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "group_based_on", + "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": 0, + "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": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "collapsible_depends_on": "", "columns": 0, + "depends_on": "eval:!doc.__islocal", "fieldname": "section_break_6", "fieldtype": "Section Break", "hidden": 0, @@ -251,6 +326,37 @@ "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": 1, "bold": 0, "collapsible": 0, @@ -281,12 +387,13 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "amended_from", - "fieldtype": "Link", + "fieldname": "section_break_12", + "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -294,14 +401,45 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Amended From", + "label": "Instructors", "length": 0, - "no_copy": 1, - "options": "Student Group", + "no_copy": 0, "permlevel": 0, - "print_hide": 1, + "precision": "", + "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 1, + "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": "instructors", + "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": "Instructors", + "length": 0, + "no_copy": 0, + "options": "Student Group 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": 0, @@ -310,18 +448,18 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "idx": 0, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 0, "issingle": 0, "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2017-02-17 17:16:31.682311", + "modified": "2017-04-24 15:53:35.593913", "modified_by": "Administrator", "module": "Schools", "name": "Student Group", @@ -372,7 +510,7 @@ "quick_entry": 0, "read_only": 0, "read_only_onload": 0, - "search_fields": "program, course", + "search_fields": "program, batch, course", "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", diff --git a/erpnext/schools/doctype/student_group/student_group.py b/erpnext/schools/doctype/student_group/student_group.py index 996f518813..dba8c925a7 100644 --- a/erpnext/schools/doctype/student_group/student_group.py +++ b/erpnext/schools/doctype/student_group/student_group.py @@ -10,47 +10,59 @@ from erpnext.schools.utils import validate_duplicate_student from erpnext.schools.api import get_student_batch_students class StudentGroup(Document): - def autoname(self): - self.name = frappe.db.get_value("Course", self.course, "course_abbreviation") - if not self.name: - self.name = self.course - if self.student_batch: - self.name += "-" + self.student_batch - else: - prog_abb = frappe.db.get_value("Program", self.program, "program_abbreviation") - if not prog_abb: - prog_abb = self.program - if prog_abb: - self.name += "-" + prog_abb - if self.academic_year: - self.name += "-" + self.academic_year - if self.academic_term: - self.name += "-" + self.academic_term - def validate(self): + self.validate_mandatory_fields() self.validate_strength() - self.validate_student_name() - self.validate_name() - if self.student_batch: - self.validate_student_batch() + self.validate_students() 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")) + elif self.group_based_on == "Batch" and (not self.program or not self.batch): + frappe.throw(_("Please select Program and Batch")) + def validate_strength(self): 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_student_name(self): + def validate_students(self): + program_enrollment = get_program_enrollment(self.academic_year, self.group_based_on, self.program, self.batch, self.course) + students = [d.student for d in program_enrollment] if program_enrollment else None for d in self.students: - d.student_name = frappe.db.get_value("Student", d.student, "title") - - def validate_name(self): - if frappe.db.exists("Student Batch", self.name): - frappe.throw(_("""Student Batch exists with same name""")) + if self.group_based_on != "Activity" and d.student not in students: + frappe.throw(_("{0} - {1} is not enrolled in the given {2}".format(d.student, d.student_name, self.group_based_on))) + if not frappe.db.get_value("Student", d.student, "enabled") and d.active: + d.active = 0 + frappe.throw(_("{0} - {1} is inactive student".format(d.student, d.student_name))) - def validate_student_batch(self): - student_batch_students = [] - for d in get_student_batch_students(self.student_batch): - student_batch_students.append(d.student) - for d in self.students: - if d.student not in student_batch_students: - frappe.throw(_("""Student {0}: {1} does not belong to Student Batch {2}""".format(d.student, d.student_name, self.student_batch))) \ No newline at end of file +@frappe.whitelist() +def get_students(academic_year, group_based_on, program=None, batch=None, course=None): + enrolled_students = get_program_enrollment(academic_year, group_based_on, program, batch, 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 + +def get_program_enrollment(academic_year, group_based_on, program=None, batch=None, course=None): + if group_based_on == "Batch": + return frappe.db.sql('''select student, student_name from `tabProgram Enrollment` where academic_year = %s + and program = %s and student_batch_name = %s order by student_name asc''',(academic_year, program, batch), as_dict=1) + + elif group_based_on == "Course": + return frappe.db.sql(''' + select + pe.student, pe.student_name + from + `tabProgram Enrollment` pe, `tabProgram Enrollment Course` pec + where + pe.name = pec.parent and pec.course = %s + order by + pe.student_name asc + ''', (course), as_dict=1) \ No newline at end of file diff --git a/erpnext/schools/doctype/student_group/test_records.json b/erpnext/schools/doctype/student_group/test_records.json index 06cb086c20..c36c9b297c 100644 --- a/erpnext/schools/doctype/student_group/test_records.json +++ b/erpnext/schools/doctype/student_group/test_records.json @@ -1,14 +1,30 @@ [ { + "student_group_name": "Batch-_TP1-_Batch 1-2014-2015 (_Test Academic Term)", + "group_based_on": "Batch", "program": "_TP1", - "course": "TC100", + "batch": "_Batch 1", "academic_year": "2014-2015", "academic_term": "2014-2015 (_Test Academic Term)" }, { - "program": "_TP2", + "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)" + }, + { + "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)" + }, + { + "student_group_name": "Activity-2014-2015 (_Test Academic Term)", + "group_based_on": "Activity", + "academic_year": "2014-2015", + "academic_term": "2014-2015 (_Test Academic Term)" } ] \ No newline at end of file diff --git a/erpnext/schools/doctype/student_group_instructor/__init__.py b/erpnext/schools/doctype/student_group_instructor/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/schools/doctype/student_group_instructor/student_group_instructor.json b/erpnext/schools/doctype/student_group_instructor/student_group_instructor.json new file mode 100644 index 0000000000..541e9b336b --- /dev/null +++ b/erpnext/schools/doctype/student_group_instructor/student_group_instructor.json @@ -0,0 +1,129 @@ +{ + "allow_copy": 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_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, + "unique": 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_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "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": "instructor.instructor_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 + } + ], + "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-04-17 16:06:05.792863", + "modified_by": "Administrator", + "module": "Schools", + "name": "Student Group Instructor", + "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": 0, + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/schools/doctype/student_group_instructor/student_group_instructor.py b/erpnext/schools/doctype/student_group_instructor/student_group_instructor.py new file mode 100644 index 0000000000..b6cc588b67 --- /dev/null +++ b/erpnext/schools/doctype/student_group_instructor/student_group_instructor.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class StudentGroupInstructor(Document): + pass diff --git a/erpnext/schools/doctype/student_group_student/student_group_student.json b/erpnext/schools/doctype/student_group_student/student_group_student.json index 5ca7b66c35..5fc434adf4 100644 --- a/erpnext/schools/doctype/student_group_student/student_group_student.json +++ b/erpnext/schools/doctype/student_group_student/student_group_student.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, "beta": 0, @@ -21,6 +22,7 @@ "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", @@ -39,33 +41,6 @@ "set_only_once": 0, "unique": 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_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_on_submit": 0, "bold": 0, @@ -77,6 +52,7 @@ "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", @@ -94,6 +70,63 @@ "set_only_once": 0, "unique": 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_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, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -106,6 +139,7 @@ "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", @@ -124,17 +158,17 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "idx": 0, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 0, "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2017-01-27 14:49:54.533005", + "modified": "2017-04-12 14:56:07.532226", "modified_by": "Administrator", "module": "Schools", "name": "Student Group Student", @@ -144,6 +178,7 @@ "quick_entry": 0, "read_only": 0, "read_only_onload": 0, + "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", "track_changes": 0, diff --git a/erpnext/schools/doctype/student_group_student/student_group_student.py b/erpnext/schools/doctype/student_group_student/student_group_student.py index 1fe4ea1dc3..820e30118d 100644 --- a/erpnext/schools/doctype/student_group_student/student_group_student.py +++ b/erpnext/schools/doctype/student_group_student/student_group_student.py @@ -7,4 +7,4 @@ import frappe from frappe.model.document import Document class StudentGroupStudent(Document): - pass + pass \ No newline at end of file diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json index 3a7342738a..fe747ec4f8 100644 --- a/erpnext/selling/doctype/quotation_item/quotation_item.json +++ b/erpnext/selling/doctype/quotation_item/quotation_item.json @@ -14,6 +14,7 @@ "engine": "InnoDB", "fields": [ { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 1, "collapsible": 0, @@ -47,6 +48,7 @@ "width": "150px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -75,6 +77,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -102,6 +105,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -134,6 +138,7 @@ "width": "150px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 1, @@ -163,6 +168,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -195,6 +201,7 @@ "width": "300px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -223,6 +230,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -252,6 +260,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -282,6 +291,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -310,6 +320,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 1, "collapsible": 0, @@ -342,6 +353,7 @@ "width": "100px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -375,6 +387,7 @@ "width": "100px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -402,6 +415,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -432,6 +446,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -461,6 +476,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -490,6 +506,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -518,6 +535,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -551,6 +569,7 @@ "width": "100px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -584,6 +603,7 @@ "width": "100px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 1, @@ -613,6 +633,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -646,6 +667,7 @@ "width": "100px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -674,6 +696,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -705,6 +728,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -735,6 +759,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -765,6 +790,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -792,6 +818,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 1, "collapsible": 0, @@ -813,7 +840,7 @@ "oldfieldtype": "Currency", "options": "currency", "permlevel": 0, - "precision": "9", + "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, "print_width": "100px", @@ -827,6 +854,7 @@ "width": "100px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -856,6 +884,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -889,6 +918,7 @@ "width": "100px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -919,6 +949,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -946,6 +977,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -979,6 +1011,7 @@ "width": "100px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1008,6 +1041,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1041,6 +1075,7 @@ "width": "100px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1071,6 +1106,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1100,6 +1136,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 1, @@ -1130,6 +1167,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1160,6 +1198,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1188,6 +1227,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1217,6 +1257,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1247,6 +1288,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1276,6 +1318,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1304,6 +1347,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1337,6 +1381,7 @@ "width": "150px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1370,6 +1415,7 @@ "width": "150px" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1400,6 +1446,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1427,6 +1474,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 1, "bold": 0, "collapsible": 0, @@ -1457,6 +1505,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1489,6 +1538,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1533,7 +1583,7 @@ "istable": 1, "max_attachments": 0, "menu_index": 0, - "modified": "2017-04-18 18:47:26.869235", + "modified": "2017-04-25 10:34:17.987184", "modified_by": "Administrator", "module": "Selling", "name": "Quotation Item", diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py index a7dfa7cb31..b66fd4d0e4 100644 --- a/erpnext/setup/doctype/email_digest/email_digest.py +++ b/erpnext/setup/doctype/email_digest/email_digest.py @@ -10,7 +10,7 @@ from datetime import timedelta from dateutil.relativedelta import relativedelta from frappe.core.doctype.user.user import STANDARD_USERS import frappe.desk.notifications -from erpnext.accounts.utils import get_balance_on, get_count_on, get_currency_precision +from erpnext.accounts.utils import get_balance_on, get_count_on user_specific_content = ["calendar_events", "todo_list"] diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index a6459c53ec..66ab6aceb6 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -405,7 +405,7 @@ def get_bin_details_and_serial_nos(item_code, warehouse, stock_qty=None, serial_ @frappe.whitelist() def get_batch_qty(batch_no, warehouse, item_code): - from frappe.stock.doctype.batch import batch + from erpnext.stock.doctype.batch import batch if batch_no: return {'actual_batch_qty': batch.get_batch_qty(batch_no, warehouse)}