From 7bc6f3843ad43d30cb0690555e4ade413cf398fb Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Tue, 13 Nov 2018 16:54:54 +0530 Subject: [PATCH 01/10] Fix for accounts Receivable Summary Showing zero values --- .../accounts_receivable.html | 2 +- .../accounts_receivable_summary.py | 98 ++++++++++++++++--- 2 files changed, 84 insertions(+), 16 deletions(-) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html index f26cd33b18..dfcf64c797 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html @@ -230,7 +230,7 @@ {% } %} {%= format_currency(data[i][("total_invoiced_amt")], data[i]["currency"]) %} {%= format_currency(data[i][("total_paid_amt")], data[i]["currency"]) %} - {%= report.report_name === "Accounts Receivable Summary" ? format_currency(data[i][__("Credit Note Amt")], data[i]["currency"]) : format_currency(data[i][__("Debit Note Amt")], data[i]["currency"]) %} + {%= report.report_name === "Accounts Receivable Summary" ? format_currency(data[i][__("credit_note_amt")], data[i]["currency"]) : format_currency(data[i][__("debit_note_amt")], data[i]["currency"]) %} {%= format_currency(data[i][("total_outstanding_amt")], data[i]["currency"]) %} {% } %} {% } %} 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 c56ae0d9ff..7b0072cd15 100644 --- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py +++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import frappe -from frappe import _ +from frappe import _, scrub from frappe.utils import flt from erpnext.accounts.report.accounts_receivable.accounts_receivable import ReceivablePayableReport @@ -21,24 +21,92 @@ class AccountsReceivableSummary(ReceivablePayableReport): if party_naming_by == "Naming Series": columns += [ args.get("party_type") + " Name::140"] - credit_debit_label = _("Credit Note Amt") if args.get('party_type') == 'Customer' else _("Debit Note Amt") + credit_debit_label = "Credit Note Amt" if args.get('party_type') == 'Customer' else "Debit Note Amt" + + columns += [{ + "label": _("Total Invoiced Amt"), + "fieldname": "total_invoiced_amt", + "fieldtype": "Currency", + "options": "currency", + "width": 100 + }, + { + "label": _("Total Paid Amt"), + "fieldname": "total_paid_amt", + "fieldtype": "Currency", + "options": "currency", + "width": 100 + }] + columns += [ - _("Total Invoiced Amt") + ":Currency/currency:140", - _("Total Paid Amt") + ":Currency/currency:140", - credit_debit_label + ":Currency/currency:140", - _("Total Outstanding Amt") + ":Currency/currency:160", - "0-" + str(self.filters.range1) + ":Currency/currency:100", - str(self.filters.range1) + "-" + str(self.filters.range2) + ":Currency/currency:100", - str(self.filters.range2) + "-" + str(self.filters.range3) + ":Currency/currency:100", - str(self.filters.range3) + _("-Above") + ":Currency/currency:100"] + { + "label": _(credit_debit_label), + "fieldname": scrub(credit_debit_label), + "fieldtype": "Currency", + "options": "currency", + "width": 140 + }, + { + "label": _("Total Outstanding Amt"), + "fieldname": "total_outstanding_amt", + "fieldtype": "Currency", + "options": "currency", + "width": 160 + }, + { + "label": _("0-" + str(self.filters.range1)), + "fieldname": scrub("0-" + str(self.filters.range1)), + "fieldtype": "Currency", + "options": "currency", + "width": 160 + }, + { + "label": _(str(self.filters.range1) + "-" + str(self.filters.range2)), + "fieldname": scrub(str(self.filters.range1) + "-" + str(self.filters.range2)), + "fieldtype": "Currency", + "options": "currency", + "width": 160 + }, + { + "label": _(str(self.filters.range2) + "-" + str(self.filters.range3)), + "fieldname": scrub(str(self.filters.range2) + "-" + str(self.filters.range3)), + "fieldtype": "Currency", + "options": "currency", + "width": 160 + }, + { + "label": _(str(self.filters.range3) + _("-Above")), + "fieldname": scrub(str(self.filters.range3) + _("-Above")), + "fieldtype": "Currency", + "options": "currency", + "width": 160 + } + ] if args.get("party_type") == "Customer": - columns += [ - _("Territory") + ":Link/Territory:80", - _("Customer Group") + ":Link/Customer Group:120" - ] + columns += [{ + "label": _("Territory"), + "fieldname": "territory", + "fieldtype": "Link", + "options": "Territory", + "width": 80 + }, + { + "label": _("Customer Group"), + "fieldname": "customer_group", + "fieldtype": "Link", + "options": "Customer Group", + "width": 80 + }] + if args.get("party_type") == "Supplier": - columns += [_("Supplier Group") + ":Link/Supplier Group:80"] + columns += [{ + "label": _("Supplier Group"), + "fieldname": "supplier_group", + "fieldtype": "Link", + "options": "Supplier Group", + "width": 80 + }] columns.append({ "fieldname": "currency", From 047a7123eb0308ce64dbd5b48b81a88c518f7346 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 14 Nov 2018 13:20:00 +0530 Subject: [PATCH 02/10] Claimed amount is not reset on cancel --- erpnext/hr/doctype/employee_advance/employee_advance.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.py b/erpnext/hr/doctype/employee_advance/employee_advance.py index 29aae05ba3..c90e5dbbde 100644 --- a/erpnext/hr/doctype/employee_advance/employee_advance.py +++ b/erpnext/hr/doctype/employee_advance/employee_advance.py @@ -58,10 +58,9 @@ class EmployeeAdvance(Document): select sum(ifnull(allocated_amount, 0)) from `tabExpense Claim Advance` where employee_advance = %s and docstatus=1 and allocated_amount > 0 - """, self.name)[0][0] + """, self.name)[0][0] or 0 - if claimed_amount: - frappe.db.set_value("Employee Advance", self.name, "claimed_amount", claimed_amount) + frappe.db.set_value("Employee Advance", self.name, "claimed_amount", claimed_amount) @frappe.whitelist() def make_bank_entry(dt, dn): From d168a71cfb2279b690e5b24d51ca2168091eccfb Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Wed, 14 Nov 2018 18:58:30 +0530 Subject: [PATCH 03/10] perf(patch): Use INSERT with ON DUPLICATE KEY UPDATE update_total_qty_field patch was using UPDATE statement with CASE Now use INSERT INTO with ON DUPLICATE KEY UPDATE clause which allows this query to use indexes and update multiple rows per query. --- .../patches/v11_0/update_total_qty_field.py | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/erpnext/patches/v11_0/update_total_qty_field.py b/erpnext/patches/v11_0/update_total_qty_field.py index 5c7663d5aa..8f086992b6 100644 --- a/erpnext/patches/v11_0/update_total_qty_field.py +++ b/erpnext/patches/v11_0/update_total_qty_field.py @@ -9,12 +9,12 @@ def execute(): frappe.reload_doc('stock', 'doctype', 'purchase_receipt') frappe.reload_doc('accounts', 'doctype', 'sales_invoice') frappe.reload_doc('accounts', 'doctype', 'purchase_invoice') - + doctypes = ["Sales Order", "Sales Invoice", "Delivery Note",\ "Purchase Order", "Purchase Invoice", "Purchase Receipt", "Quotation", "Supplier Quotation"] for doctype in doctypes: - total_qty = frappe.db.sql(''' + total_qty = frappe.db.sql(''' SELECT parent, SUM(qty) as qty FROM @@ -22,14 +22,25 @@ def execute(): GROUP BY parent ''' % (doctype), as_dict = True) - when_then = [] - for d in total_qty: - when_then.append(""" - when dt.name = '{0}' then {1} - """.format(frappe.db.escape(d.get("parent")), d.get("qty"))) + # Query to update total_qty might become too big, Update in batches + # batch_size is chosen arbitrarily, Don't try too hard to reason about it + batch_size = 100000 + for i in range(0, len(total_qty), batch_size): + batch_transactions = total_qty[i:i + batch_size] - if when_then: - frappe.db.sql(''' - UPDATE - `tab%s` dt SET dt.total_qty = CASE %s ELSE 0.0 END - ''' % (doctype, " ".join(when_then))) \ No newline at end of file + # UPDATE with CASE for some reason cannot use PRIMARY INDEX, + # causing all rows to be examined, leading to a very slow update + + # UPDATE with WHERE clause uses PRIMARY INDEX, but will lead to too many queries + + # INSERT with ON DUPLICATE KEY UPDATE uses PRIMARY INDEX + # and can perform multiple updates per query + # This is probably never used anywhere else as of now, but should be + values = [] + for d in batch_transactions: + values.append("('{}', {})".format(d.parent, d.qty)) + conditions = ",".join(values) + frappe.db.sql(""" + INSERT INTO `tab{}` (name, total_qty) VALUES {} + ON DUPLICATE KEY UPDATE name = VALUES(name), total_qty = VALUES(total_qty) + """.format(doctype, conditions)) From 43920530a1b9fa2c4c06512049fcd7970b84d54d Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 15 Nov 2018 12:20:27 +0530 Subject: [PATCH 04/10] [Minor] Patch fixes --- erpnext/patches/v11_0/set_missing_gst_hsn_code.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/patches/v11_0/set_missing_gst_hsn_code.py b/erpnext/patches/v11_0/set_missing_gst_hsn_code.py index 9d28a4a3f3..3c2cea2230 100644 --- a/erpnext/patches/v11_0/set_missing_gst_hsn_code.py +++ b/erpnext/patches/v11_0/set_missing_gst_hsn_code.py @@ -36,8 +36,8 @@ def execute(): where dt_item.name in ({rows_name}) """.format(dt=dt, rows_name=", ".join(['%s']*len(transaction_rows_name))), tuple(transaction_rows_name)) - for t in transactions: - print(t.name) - trans_doc = frappe.get_doc(dt, t.name) + parent = set([d.name for d in transactions]) + for t in list(parent): + trans_doc = frappe.get_doc(dt, t) hsnwise_tax = get_itemised_tax_breakup_html(trans_doc) - frappe.db.set_value(dt, t.name, "other_charges_calculation", hsnwise_tax, update_modified=False) \ No newline at end of file + frappe.db.set_value(dt, t, "other_charges_calculation", hsnwise_tax, update_modified=False) \ No newline at end of file From 9d0f90975b4b40c4a93f6bb585ad38da9d263566 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 15 Nov 2018 12:55:20 +0530 Subject: [PATCH 05/10] [Fix] Consolidated financial statement report currency conversion issue --- .../consolidated_financial_statement.py | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py index 383d4c09ed..10940c351f 100644 --- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py +++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py @@ -331,31 +331,36 @@ def set_gl_entries_by_account(from_date, to_date, root_lft, root_rgt, filters, g filters.get('company'), ["lft", "rgt"]) additional_conditions = get_additional_conditions(from_date, ignore_closing_entries, filters) - - gl_entries = frappe.db.sql("""select gl.posting_date, gl.account, gl.debit, gl.credit, gl.is_opening, gl.company, - gl.fiscal_year, gl.debit_in_account_currency, gl.credit_in_account_currency, gl.account_currency, - acc.account_name, acc.account_number - from `tabGL Entry` gl, `tabAccount` acc where acc.name = gl.account and gl.company in - (select name from `tabCompany` where lft >= %(company_lft)s and rgt <= %(company_rgt)s) - {additional_conditions} and gl.posting_date <= %(to_date)s and acc.lft >= %(lft)s and acc.rgt <= %(rgt)s - order by gl.account, gl.posting_date""".format(additional_conditions=additional_conditions), - { - "from_date": from_date, - "to_date": to_date, - "lft": root_lft, - "rgt": root_rgt, + companies = frappe.db.sql_list(""" select name from `tabCompany` + where lft >= %(company_lft)s and rgt <= %(company_rgt)s""", { "company_lft": company_lft, "company_rgt": company_rgt, - }, - as_dict=True) + }) - if filters and filters.get('presentation_currency'): - convert_to_presentation_currency(gl_entries, get_currency(filters)) + for company in companies: + gl_entries = frappe.db.sql("""select gl.posting_date, gl.account, gl.debit, gl.credit, gl.is_opening, gl.company, + gl.fiscal_year, gl.debit_in_account_currency, gl.credit_in_account_currency, gl.account_currency, + acc.account_name, acc.account_number + from `tabGL Entry` gl, `tabAccount` acc where acc.name = gl.account and gl.company = %(company)s + {additional_conditions} and gl.posting_date <= %(to_date)s and acc.lft >= %(lft)s and acc.rgt <= %(rgt)s + order by gl.account, gl.posting_date""".format(additional_conditions=additional_conditions), + { + "from_date": from_date, + "to_date": to_date, + "lft": root_lft, + "rgt": root_rgt, + "company": company + }, + as_dict=True) - for entry in gl_entries: - key = entry.account_number or entry.account_name - validate_entries(key, entry, accounts_by_name) - gl_entries_by_account.setdefault(key, []).append(entry) + if filters and filters.get('presentation_currency'): + filters['company'] = company + convert_to_presentation_currency(gl_entries, get_currency(filters)) + + for entry in gl_entries: + key = entry.account_number or entry.account_name + validate_entries(key, entry, accounts_by_name) + gl_entries_by_account.setdefault(key, []).append(entry) return gl_entries_by_account From 704796b1cbb715756facbfac48e073a40d7affbd Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 15 Nov 2018 13:46:18 +0530 Subject: [PATCH 06/10] Code optimization for consolidated financial statement report --- .../consolidated_financial_statement.py | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py index 10940c351f..b9aebd83f9 100644 --- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py +++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py @@ -331,13 +331,18 @@ def set_gl_entries_by_account(from_date, to_date, root_lft, root_rgt, filters, g filters.get('company'), ["lft", "rgt"]) additional_conditions = get_additional_conditions(from_date, ignore_closing_entries, filters) - companies = frappe.db.sql_list(""" select name from `tabCompany` + companies = frappe.db.sql(""" select name, default_currency from `tabCompany` where lft >= %(company_lft)s and rgt <= %(company_rgt)s""", { "company_lft": company_lft, "company_rgt": company_rgt, - }) + }, as_dict=1) - for company in companies: + currency_info = frappe._dict({ + 'report_date': to_date, + 'presentation_currency': filters.get('presentation_currency') + }) + + for d in companies: gl_entries = frappe.db.sql("""select gl.posting_date, gl.account, gl.debit, gl.credit, gl.is_opening, gl.company, gl.fiscal_year, gl.debit_in_account_currency, gl.credit_in_account_currency, gl.account_currency, acc.account_name, acc.account_number @@ -349,13 +354,14 @@ def set_gl_entries_by_account(from_date, to_date, root_lft, root_rgt, filters, g "to_date": to_date, "lft": root_lft, "rgt": root_rgt, - "company": company + "company": d.name }, as_dict=True) - if filters and filters.get('presentation_currency'): - filters['company'] = company - convert_to_presentation_currency(gl_entries, get_currency(filters)) + if filters and filters.get('presentation_currency') != d.default_currency: + currency_info['company'] = d.name + currency_info['company_currency'] = d.default_currency + convert_to_presentation_currency(gl_entries, currency_info) for entry in gl_entries: key = entry.account_number or entry.account_name From 2426d00dd68b504404a35bf37cce4ecd936f59bd Mon Sep 17 00:00:00 2001 From: Frappe Bot Date: Thu, 15 Nov 2018 09:04:14 +0000 Subject: [PATCH 07/10] bumped to version 10.1.72 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 981ca9a510..d6bb2d7aab 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '10.1.71' +__version__ = '10.1.72' def get_default_company(user=None): '''Get default company for user''' From a4fe9123821b6e2fef1b3e352b507ade4a9be4b2 Mon Sep 17 00:00:00 2001 From: Frappe Bot Date: Thu, 15 Nov 2018 09:19:18 +0000 Subject: [PATCH 08/10] bumped to version 11.0.3-beta.23 --- erpnext/hooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 6947c02618..0c07c8a227 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -12,7 +12,7 @@ app_license = "GNU General Public License (v3)" source_link = "https://github.com/frappe/erpnext" develop_version = '12.x.x-develop' -staging_version = '11.0.3-beta.22' +staging_version = '11.0.3-beta.23' error_report_email = "support@erpnext.com" From ef745b0197323a41e7e5be0f8e181d9f07ea4cbe Mon Sep 17 00:00:00 2001 From: Frappe Bot Date: Thu, 15 Nov 2018 09:19:18 +0000 Subject: [PATCH 09/10] bumped to version 11.0.3-beta.23 --- erpnext/hooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 6947c02618..0c07c8a227 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -12,7 +12,7 @@ app_license = "GNU General Public License (v3)" source_link = "https://github.com/frappe/erpnext" develop_version = '12.x.x-develop' -staging_version = '11.0.3-beta.22' +staging_version = '11.0.3-beta.23' error_report_email = "support@erpnext.com" From d9dccaefba9a34c976f50cdd2b9d0d8baad55dc7 Mon Sep 17 00:00:00 2001 From: Frappe Bot Date: Thu, 15 Nov 2018 09:42:35 +0000 Subject: [PATCH 10/10] bumped to version 11.0.3-beta.24 --- erpnext/hooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 0c07c8a227..43afa2ae28 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -12,7 +12,7 @@ app_license = "GNU General Public License (v3)" source_link = "https://github.com/frappe/erpnext" develop_version = '12.x.x-develop' -staging_version = '11.0.3-beta.23' +staging_version = '11.0.3-beta.24' error_report_email = "support@erpnext.com"