diff --git a/erpnext/__init__.py b/erpnext/__init__.py index d50b5bf5609..92efe8e302f 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''' diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html index f26cd33b18a..dfcf64c7972 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 c56ae0d9ff5..7b0072cd152 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", 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 383d4c09edc..b9aebd83f93 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,42 @@ 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(""" 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=True) + }, as_dict=1) - if filters and filters.get('presentation_currency'): - convert_to_presentation_currency(gl_entries, get_currency(filters)) + currency_info = frappe._dict({ + 'report_date': to_date, + 'presentation_currency': filters.get('presentation_currency') + }) - 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) + 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 + 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": d.name + }, + as_dict=True) + + 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 + validate_entries(key, entry, accounts_by_name) + gl_entries_by_account.setdefault(key, []).append(entry) return gl_entries_by_account diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 6947c02618e..43afa2ae28d 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.24' error_report_email = "support@erpnext.com" diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.py b/erpnext/hr/doctype/employee_advance/employee_advance.py index 62355b80a11..1c8b5f96626 100644 --- a/erpnext/hr/doctype/employee_advance/employee_advance.py +++ b/erpnext/hr/doctype/employee_advance/employee_advance.py @@ -13,7 +13,7 @@ class EmployeeAdvanceOverPayment(frappe.ValidationError): class EmployeeAdvance(Document): def onload(self): - self.get("__onload").make_payment_via_journal_entry = frappe.db.get_single_value('Accounts Settings', + self.get("__onload").make_payment_via_journal_entry = frappe.db.get_single_value('Accounts Settings', 'make_payment_via_journal_entry') def validate(self): @@ -47,7 +47,7 @@ class EmployeeAdvance(Document): paid_amount = frappe.db.sql(""" select ifnull(sum(debit_in_account_currency), 0) as paid_amount from `tabGL Entry` - where against_voucher_type = 'Employee Advance' + where against_voucher_type = 'Employee Advance' and against_voucher = %s and party_type = 'Employee' and party = %s @@ -67,7 +67,7 @@ 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", flt(claimed_amount)) 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 9d28a4a3f3b..3c2cea22306 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 diff --git a/erpnext/patches/v11_0/update_total_qty_field.py b/erpnext/patches/v11_0/update_total_qty_field.py index 5c7663d5aa2..8f086992b63 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))