From f5b6ee9ae7b1444435c1b23e625a4a97accb1e37 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Tue, 28 May 2019 12:15:56 +0530 Subject: [PATCH] fix: Multiple fixes in accounting doctype --- .../accounting_dimension.js | 12 ++ .../accounting_dimension.json | 23 ++-- .../accounting_dimension.py | 41 ++++-- erpnext/accounts/doctype/gl_entry/gl_entry.py | 19 +++ .../report/general_ledger/general_ledger.js | 126 +++++++++--------- erpnext/public/js/financial_statements.js | 62 ++++----- 6 files changed, 167 insertions(+), 116 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js index 00a9d72bde..4f4876a6dc 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js @@ -21,4 +21,16 @@ frappe.ui.form.on('Accounting Dimension', { } }); }, + + disabled: function(frm) { + frappe.call({ + method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.disable_dimension", + args: { + doc: frm.doc + }, + callback: function() { + frappe.msgprint(_("{0} dimension disabled", [frm.doc.label])); + } + }); + } }); diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json index 9405e73a03..1e2bb925a1 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json @@ -9,7 +9,8 @@ "document_type", "label", "fieldname", - "is_mandatory", + "mandatory_for_bs", + "mandatory_for_pl", "disabled" ], "fields": [ @@ -33,20 +34,26 @@ "options": "DocType", "reqd": 1 }, - { - "default": "0", - "fieldname": "is_mandatory", - "fieldtype": "Check", - "label": "Is Mandatory" - }, { "default": "0", "fieldname": "disabled", "fieldtype": "Check", "label": "Disable" + }, + { + "default": "0", + "fieldname": "mandatory_for_bs", + "fieldtype": "Check", + "label": "Mandatory For Balance Sheet" + }, + { + "default": "0", + "fieldname": "mandatory_for_pl", + "fieldtype": "Check", + "label": "Mandatory For Profit and Loss Account" } ], - "modified": "2019-05-25 19:18:11.718209", + "modified": "2019-05-27 18:18:17.792726", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting Dimension", diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py index d51bd7f5c7..47bdc943a4 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py @@ -12,9 +12,6 @@ from frappe.utils import cstr from frappe.utils.background_jobs import enqueue class AccountingDimension(Document): - def on_update(self): - frappe.enqueue(disable_dimension, doc=self) - def before_insert(self): self.set_fieldname_and_label() frappe.enqueue(make_dimension_in_accounting_doctypes, doc=self) @@ -33,11 +30,6 @@ def make_dimension_in_accounting_doctypes(doc): doclist = get_doclist() doc_count = len(get_accounting_dimensions()) - if doc.is_mandatory: - df.update({ - "reqd": 1 - }) - for doctype in doclist: if (doc_count + 1) % 2 == 0: @@ -81,7 +73,19 @@ def make_dimension_in_accounting_doctypes(doc): }).insert(ignore_permissions=True) frappe.clear_cache(doctype=doctype) else: - create_custom_field(doctype, df) + if frappe.db.has_column(doctype, doc.fieldname) and (doc.mandatory_for_pl or doc.mandatory_for_bs): + frappe.get_doc({ + "doctype": "Property Setter", + "doctype_or_field": "DocField", + "doc_type": doctype, + "field_name": doc.fieldname, + "property": "hidden", + "property_type": "Check", + "value": 0 + }).insert(ignore_permissions=True) + else: + create_custom_field(doctype, df) + frappe.clear_cache(doctype=doctype) def delete_accounting_dimension(doc): @@ -109,8 +113,14 @@ def delete_accounting_dimension(doc): for doctype in doclist: frappe.clear_cache(doctype=doctype) +@frappe.whitelist() def disable_dimension(doc): - if doc.disabled: + frappe.enqueue(start_dimension_disabling, doc=doc) + +def start_dimension_disabling(doc): + doc = json.loads(doc) + + if doc.get('disabled'): df = {"read_only": 1} else: df = {"read_only": 0} @@ -118,7 +128,7 @@ def disable_dimension(doc): doclist = get_doclist() for doctype in doclist: - field = frappe.db.get_value("Custom Field", {"dt": doctype, "fieldname": doc.fieldname}) + field = frappe.db.get_value("Custom Field", {"dt": doctype, "fieldname": doc.get('fieldname')}) if field: custom_field = frappe.get_doc("Custom Field", field) custom_field.update(df) @@ -136,7 +146,10 @@ def get_doclist(): return doclist -def get_accounting_dimensions(): - accounting_dimensions = frappe.get_all("Accounting Dimension", fields=["fieldname"]) +def get_accounting_dimensions(as_list=True): + accounting_dimensions = frappe.get_all("Accounting Dimension", fields=["label", "fieldname", "mandatory_for_pl", "mandatory_for_bs", "disabled"]) - return [d.fieldname for d in accounting_dimensions] + if as_list: + return [d.fieldname for d in accounting_dimensions] + else: + return accounting_dimensions diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index 3ced9a39eb..cd4f794b6c 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -12,6 +12,7 @@ from erpnext.accounts.party import validate_party_gle_currency, validate_party_f from erpnext.accounts.utils import get_account_currency from erpnext.accounts.utils import get_fiscal_year from erpnext.exceptions import InvalidAccountCurrency +from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions exclude_from_linked_with = True class GLEntry(Document): @@ -28,6 +29,7 @@ class GLEntry(Document): self.validate_and_set_fiscal_year() self.pl_must_have_cost_center() self.validate_cost_center() + self.validate_dimensions_for_pl_and_bs() if not self.flags.from_repost: self.check_pl_account() @@ -80,6 +82,23 @@ class GLEntry(Document): if self.project: self.project = None + def validate_dimensions_for_pl_and_bs(self): + + for dimension in get_accounting_dimensions(as_list=False): + + if frappe.db.get_value("Account", self.account, "report_type") == "Profit and Loss" \ + and dimension.mandatory_for_pl and not dimension.disabled: + if not self.get(dimension.fieldname): + frappe.throw(_("{0} is required for 'Profit and Loss' account {1}.") + .format(dimension.label, self.account)) + + if frappe.db.get_value("Account", self.account, "report_type") == "Balance Sheet" \ + and dimension.mandatory_for_bs and not dimension.disabled: + if not self.get(dimension.fieldname): + frappe.throw(_("{0} is required for 'Balance Sheet' account {1}.") + .format(dimension.label, self.account)) + + def check_pl_account(self): if self.is_opening=='Yes' and \ frappe.db.get_value("Account", self.account, "report_type")=="Profit and Loss" and \ diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js index d999a1bb26..4235b7f60d 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.js +++ b/erpnext/accounts/report/general_ledger/general_ledger.js @@ -56,67 +56,6 @@ frappe.query_reports["General Ledger"] = { frappe.query_report.set_filter_value('group_by', ""); } }, - { - "fieldname":"cost_center", - "label": __("Cost Center"), - "fieldtype": "MultiSelect", - get_data: function() { - var cost_centers = frappe.query_report.get_filter_value("cost_center") || ""; - - const values = cost_centers.split(/\s*,\s*/).filter(d => d); - const txt = cost_centers.match(/[^,\s*]*$/)[0] || ''; - let data = []; - - frappe.call({ - type: "GET", - method:'frappe.desk.search.search_link', - async: false, - no_spinner: true, - args: { - doctype: "Cost Center", - txt: txt, - filters: { - "company": frappe.query_report.get_filter_value("company"), - "name": ["not in", values] - } - }, - callback: function(r) { - data = r.results; - } - }); - return data; - } - }, - { - "fieldname":"project", - "label": __("Project"), - "fieldtype": "MultiSelect", - get_data: function() { - var projects = frappe.query_report.get_filter_value("project") || ""; - - const values = projects.split(/\s*,\s*/).filter(d => d); - const txt = projects.match(/[^,\s*]*$/)[0] || ''; - let data = []; - - frappe.call({ - type: "GET", - method:'frappe.desk.search.search_link', - async: false, - no_spinner: true, - args: { - doctype: "Project", - txt: txt, - filters: { - "name": ["not in", values] - } - }, - callback: function(r) { - data = r.results; - } - }); - return data; - } - }, { "fieldtype": "Break", }, @@ -212,11 +151,72 @@ frappe.query_reports["General Ledger"] = { "fieldtype": "Select", "options": erpnext.get_presentation_currency_list() }, + { + "fieldname":"cost_center", + "label": __("Cost Center"), + "fieldtype": "MultiSelect", + get_data: function() { + var cost_centers = frappe.query_report.get_filter_value("cost_center") || ""; + + const values = cost_centers.split(/\s*,\s*/).filter(d => d); + const txt = cost_centers.match(/[^,\s*]*$/)[0] || ''; + let data = []; + + frappe.call({ + type: "GET", + method:'frappe.desk.search.search_link', + async: false, + no_spinner: true, + args: { + doctype: "Cost Center", + txt: txt, + filters: { + "company": frappe.query_report.get_filter_value("company"), + "name": ["not in", values] + } + }, + callback: function(r) { + data = r.results; + } + }); + return data; + } + }, + { + "fieldname":"project", + "label": __("Project"), + "fieldtype": "MultiSelect", + get_data: function() { + var projects = frappe.query_report.get_filter_value("project") || ""; + + const values = projects.split(/\s*,\s*/).filter(d => d); + const txt = projects.match(/[^,\s*]*$/)[0] || ''; + let data = []; + + frappe.call({ + type: "GET", + method:'frappe.desk.search.search_link', + async: false, + no_spinner: true, + args: { + doctype: "Project", + txt: txt, + filters: { + "name": ["not in", values] + } + }, + callback: function(r) { + data = r.results; + } + }); + return data; + } + }, { "fieldname": "show_opening_entries", "label": __("Show Opening Entries"), "fieldtype": "Check" - } + }, ] } @@ -224,7 +224,7 @@ let dimension_filters = erpnext.get_dimension_filters(); dimension_filters.then((dimensions) => { dimensions.forEach((dimension) => { - frappe.query_reports["General Ledger"].filters.push({ + frappe.query_reports["General Ledger"].filters.splice(15, 0 ,{ "fieldname": dimension["fieldname"], "label": __(dimension["label"]), "fieldtype": "Link", diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js index 2e4b8f28db..e1ce9bccea 100644 --- a/erpnext/public/js/financial_statements.js +++ b/erpnext/public/js/financial_statements.js @@ -78,37 +78,6 @@ function get_filters(){ "fieldtype": "Link", "options": "Finance Book" }, - { - "fieldname":"cost_center", - "label": __("Cost Center"), - "fieldtype": "MultiSelect", - get_data: function() { - var cost_centers = frappe.query_report.get_filter_value("cost_center") || ""; - - const values = cost_centers.split(/\s*,\s*/).filter(d => d); - const txt = cost_centers.match(/[^,\s*]*$/)[0] || ''; - let data = []; - - frappe.call({ - type: "GET", - method:'frappe.desk.search.search_link', - async: false, - no_spinner: true, - args: { - doctype: "Cost Center", - txt: txt, - filters: { - "company": frappe.query_report.get_filter_value("company"), - "name": ["not in", values] - } - }, - callback: function(r) { - data = r.results; - } - }); - return data; - } - }, { "fieldname":"from_fiscal_year", "label": __("Start Year"), @@ -147,6 +116,37 @@ function get_filters(){ "label": __("Currency"), "fieldtype": "Select", "options": erpnext.get_presentation_currency_list() + }, + { + "fieldname":"cost_center", + "label": __("Cost Center"), + "fieldtype": "MultiSelect", + get_data: function() { + var cost_centers = frappe.query_report.get_filter_value("cost_center") || ""; + + const values = cost_centers.split(/\s*,\s*/).filter(d => d); + const txt = cost_centers.match(/[^,\s*]*$/)[0] || ''; + let data = []; + + frappe.call({ + type: "GET", + method:'frappe.desk.search.search_link', + async: false, + no_spinner: true, + args: { + doctype: "Cost Center", + txt: txt, + filters: { + "company": frappe.query_report.get_filter_value("company"), + "name": ["not in", values] + } + }, + callback: function(r) { + data = r.results; + } + }); + return data; + } } ]