From d7db8ed12ef8b1c394b4d81ba6f7c89eeb737db9 Mon Sep 17 00:00:00 2001 From: Akash Krishna Date: Tue, 9 Aug 2022 17:41:02 +0530 Subject: [PATCH 01/27] Tds report (#31801) * fix: TDS Computation Summary Report not loading, too many values to unpack (cherry picked from commit 32b30bc5de0347a0c5614ccb7b05262e5877cbc1) --- .../report/tds_computation_summary/tds_computation_summary.py | 4 ++-- .../report/tds_payable_monthly/tds_payable_monthly.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py index 08d20086823..db3d5d44a0c 100644 --- a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py +++ b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py @@ -14,9 +14,9 @@ def execute(filters=None): filters.naming_series = frappe.db.get_single_value("Buying Settings", "supp_master_name") columns = get_columns(filters) - tds_docs, tds_accounts, tax_category_map = get_tds_docs(filters) + tds_docs, tds_accounts, tax_category_map, journal_entry_party_map = get_tds_docs(filters) - res = get_result(filters, tds_docs, tds_accounts, tax_category_map) + res = get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map) final_result = group_by_supplier_and_category(res) return columns, final_result diff --git a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py index 16e0ac1de60..f2809a99c55 100644 --- a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py +++ b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py @@ -26,7 +26,6 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_ supplier_map = get_supplier_pan_map() tax_rate_map = get_tax_rate_map(filters) gle_map = get_gle_map(tds_docs) - print(journal_entry_party_map) out = [] for name, details in gle_map.items(): From 735a60807ae1f540056330a19723f6ce2d5ec15b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 9 Aug 2022 19:06:57 +0530 Subject: [PATCH 02/27] fix: limited options for no-of-employees in crm (cherry picked from commit 7ecd67605f660523cec6122da83dbc2515646d0c) --- erpnext/crm/doctype/lead/lead.json | 6 +++--- erpnext/crm/doctype/opportunity/opportunity.json | 4 ++-- erpnext/crm/doctype/prospect/prospect.json | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/erpnext/crm/doctype/lead/lead.json b/erpnext/crm/doctype/lead/lead.json index c946ae49994..99c00ad6e69 100644 --- a/erpnext/crm/doctype/lead/lead.json +++ b/erpnext/crm/doctype/lead/lead.json @@ -340,8 +340,8 @@ "fieldname": "no_of_employees", "fieldtype": "Select", "label": "No of Employees", - "options": "1-10\n11-20\n21-30\n31-100\n11-50\n51-200\n201-500\n101-500\n500-1000\n501-1000\n>1000\n1000+" - }, + "options": "1-10\n11-50\n51-200\n201-500\n501-1000\n1000+" + }, { "fieldname": "column_break_22", "fieldtype": "Column Break" @@ -514,7 +514,7 @@ "idx": 5, "image_field": "image", "links": [], - "modified": "2022-07-22 15:55:03.176094", + "modified": "2022-08-09 18:26:17.101521", "modified_by": "Administrator", "module": "CRM", "name": "Lead", diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json index 68a2156981f..fed0c7c79a2 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.json +++ b/erpnext/crm/doctype/opportunity/opportunity.json @@ -463,7 +463,7 @@ "fieldname": "no_of_employees", "fieldtype": "Select", "label": "No of Employees", - "options": "1-10\n11-20\n21-30\n31-100\n11-50\n51-200\n201-500\n101-500\n500-1000\n501-1000\n>1000\n1000+" + "options": "1-10\n11-50\n51-200\n201-500\n501-1000\n1000+" }, { "fieldname": "annual_revenue", @@ -622,7 +622,7 @@ "icon": "fa fa-info-sign", "idx": 195, "links": [], - "modified": "2022-07-22 18:46:32.858696", + "modified": "2022-08-09 18:26:37.235964", "modified_by": "Administrator", "module": "CRM", "name": "Opportunity", diff --git a/erpnext/crm/doctype/prospect/prospect.json b/erpnext/crm/doctype/prospect/prospect.json index 7f33c08c132..820a6c72ea1 100644 --- a/erpnext/crm/doctype/prospect/prospect.json +++ b/erpnext/crm/doctype/prospect/prospect.json @@ -82,7 +82,7 @@ "fieldname": "no_of_employees", "fieldtype": "Select", "label": "No. of Employees", - "options": "1-10\n11-20\n21-30\n31-100\n11-50\n51-200\n201-500\n101-500\n500-1000\n501-1000\n>1000\n1000+" + "options": "1-10\n11-50\n51-200\n201-500\n501-1000\n1000+" }, { "fieldname": "annual_revenue", @@ -218,7 +218,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2022-06-22 15:10:26.887502", + "modified": "2022-08-09 18:26:56.950185", "modified_by": "Administrator", "module": "CRM", "name": "Prospect", From 35e9bfca388b3c8f50e5e65d357dd735822bba8b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 9 Aug 2022 19:28:26 +0530 Subject: [PATCH 03/27] fix: map old data as per new options of no-of-employees (cherry picked from commit 909945c0ac214b3ad613ae944509e8bdec47c940) --- erpnext/patches.txt | 3 ++- .../patches/v14_0/fix_crm_no_of_employees.py | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 erpnext/patches/v14_0/fix_crm_no_of_employees.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index c7dc27e2944..e5beacde2b4 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -309,4 +309,5 @@ erpnext.patches.v14_0.migrate_gl_to_payment_ledger erpnext.patches.v14_0.crm_ux_cleanup erpnext.patches.v14_0.remove_india_localisation # 14-07-2022 erpnext.patches.v13_0.fix_number_and_frequency_for_monthly_depreciation -erpnext.patches.v14_0.remove_hr_and_payroll_modules # 20-07-2022 \ No newline at end of file +erpnext.patches.v14_0.remove_hr_and_payroll_modules # 20-07-2022 +erpnext.patches.v14_0.fix_crm_no_of_employees \ No newline at end of file diff --git a/erpnext/patches/v14_0/fix_crm_no_of_employees.py b/erpnext/patches/v14_0/fix_crm_no_of_employees.py new file mode 100644 index 00000000000..268eb95732e --- /dev/null +++ b/erpnext/patches/v14_0/fix_crm_no_of_employees.py @@ -0,0 +1,26 @@ +import frappe + + +def execute(): + options = { + "11-20": "11-50", + "21-30": "11-50", + "31-100": "51-200", + "101-500": "201-500", + "500-1000": "501-1000", + ">1000": "1000+", + } + + for doctype in ("Lead", "Opportunity", "Prospect"): + frappe.reload_doctype(doctype) + for key, value in options.items(): + frappe.db.sql( + """ + update `tab{doctype}` + set no_of_employees = %s + where no_of_employees = %s + """.format( + doctype=doctype + ), + (value, key), + ) From 66e5202642dcdf8fd80571f0b05d8076b7c0c0f9 Mon Sep 17 00:00:00 2001 From: Abhinav Raut Date: Mon, 8 Aug 2022 16:29:13 +0530 Subject: [PATCH 04/27] fix: process loan interest accrual (cherry picked from commit 9ef8d5c5c314ec03f46e982ce8aa36487dbb7559) --- .../doctype/loan_interest_accrual/loan_interest_accrual.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py index 0aeb4489184..730d33752ee 100644 --- a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py +++ b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py @@ -135,7 +135,11 @@ def calculate_accrual_amount_for_demand_loans( def make_accrual_interest_entry_for_demand_loans( posting_date, process_loan_interest, open_loans=None, loan_type=None, accrual_type="Regular" ): - query_filters = {"status": ("in", ["Disbursed", "Partially Disbursed"]), "docstatus": 1} + query_filters = { + "status": ("in", ["Disbursed", "Partially Disbursed"]), + "docstatus": 1, + "is_term_loan": 0, + } if loan_type: query_filters.update({"loan_type": loan_type}) From 8fdbbf374df6e8b00b8d11c7812d28a719fb394f Mon Sep 17 00:00:00 2001 From: Abhinav Raut Date: Mon, 8 Aug 2022 17:35:31 +0530 Subject: [PATCH 05/27] fix: term loan interest calculation (cherry picked from commit 534d7ce64b47c6c9272f7bedf79f4cdce825e0f2) --- .../doctype/loan_interest_accrual/loan_interest_accrual.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py index 730d33752ee..4978f1fcb89 100644 --- a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py +++ b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py @@ -233,6 +233,7 @@ def get_term_loans(date, term_loan=None, loan_type=None): AND l.is_term_loan =1 AND rs.payment_date <= %s AND rs.is_accrued=0 {0} + AND rs.interest_amount > 0 AND l.status = 'Disbursed' ORDER BY rs.payment_date""".format( condition From 1aa96defda1c34b99e3362692d2936c78d76a195 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 11 Aug 2022 19:31:31 +0530 Subject: [PATCH 06/27] fix: Unable to make payment entry against Fees using education app (cherry picked from commit 79ac50d0f7503cc053e7e58a382d81a705b7afbf) --- .../doctype/payment_entry/payment_entry.py | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index af5a5e249d2..94b6ecb66e6 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -181,7 +181,11 @@ class PaymentEntry(AccountsController): frappe.throw(_("Party is mandatory")) _party_name = "title" if self.party_type == "Shareholder" else self.party_type.lower() + "_name" - self.party_name = frappe.db.get_value(self.party_type, self.party, _party_name) + + if frappe.db.has_column(self.party_type, _party_name): + self.party_name = frappe.db.get_value(self.party_type, self.party, _party_name) + else: + self.party_name = frappe.db.get_value(self.party_type, self.party, "name") if self.party: if not self.party_balance: @@ -295,6 +299,9 @@ class PaymentEntry(AccountsController): def validate_reference_documents(self): valid_reference_doctypes = self.get_valid_reference_doctypes() + if not valid_reference_doctypes: + return + for d in self.get("references"): if not d.allocated_amount: continue @@ -362,7 +369,7 @@ class PaymentEntry(AccountsController): if not d.allocated_amount: continue - if d.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Fees"): + if d.reference_doctype in ("Sales Invoice", "Purchase Invoice"): outstanding_amount, is_return = frappe.get_cached_value( d.reference_doctype, d.reference_name, ["outstanding_amount", "is_return"] ) @@ -1200,7 +1207,7 @@ def get_outstanding_reference_documents(args): party_account_currency = get_account_currency(args.get("party_account")) company_currency = frappe.get_cached_value("Company", args.get("company"), "default_currency") - # Get positive outstanding sales /purchase invoices/ Fees + # Get positive outstanding sales /purchase invoices condition = "" if args.get("voucher_type") and args.get("voucher_no"): condition = " and voucher_type={0} and voucher_no={1}".format( @@ -1595,10 +1602,11 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre elif reference_doctype != "Journal Entry": if not total_amount: if party_account_currency == company_currency: - total_amount = ref_doc.base_grand_total + # for handling cases that don't have multi-currency (base field) + total_amount = ref_doc.get("grand_total") or ref_doc.get("base_grand_total") exchange_rate = 1 else: - total_amount = ref_doc.grand_total + total_amount = ref_doc.get("grand_total") if not exchange_rate: # Get the exchange rate from the original ref doc # or get it based on the posting date of the ref doc. @@ -1609,7 +1617,7 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre if reference_doctype in ("Sales Invoice", "Purchase Invoice"): outstanding_amount = ref_doc.get("outstanding_amount") else: - outstanding_amount = flt(total_amount) - flt(ref_doc.advance_paid) + outstanding_amount = flt(total_amount) - flt(ref_doc.get("advance_paid")) else: # Get the exchange rate based on the posting date of the ref doc. @@ -1627,16 +1635,23 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre @frappe.whitelist() -def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=None): +def get_payment_entry( + dt, dn, party_amount=None, bank_account=None, bank_amount=None, party_type=None, payment_type=None +): reference_doc = None doc = frappe.get_doc(dt, dn) if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0: frappe.throw(_("Can only make payment against unbilled {0}").format(dt)) - party_type = set_party_type(dt) + if not party_type: + party_type = set_party_type(dt) + party_account = set_party_account(dt, dn, doc, party_type) party_account_currency = set_party_account_currency(dt, party_account, doc) - payment_type = set_payment_type(dt, doc) + + if not payment_type: + payment_type = set_payment_type(dt, doc) + grand_total, outstanding_amount = set_grand_total_and_outstanding_amount( party_amount, dt, party_account_currency, doc ) @@ -1786,8 +1801,6 @@ def set_party_account(dt, dn, doc, party_type): party_account = get_party_account_based_on_invoice_discounting(dn) or doc.debit_to elif dt == "Purchase Invoice": party_account = doc.credit_to - elif dt == "Fees": - party_account = doc.receivable_account else: party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company) return party_account @@ -1803,8 +1816,7 @@ def set_party_account_currency(dt, party_account, doc): def set_payment_type(dt, doc): if ( - dt == "Sales Order" - or (dt in ("Sales Invoice", "Fees", "Dunning") and doc.outstanding_amount > 0) + dt == "Sales Order" or (dt in ("Sales Invoice", "Dunning") and doc.outstanding_amount > 0) ) or (dt == "Purchase Invoice" and doc.outstanding_amount < 0): payment_type = "Receive" else: @@ -1822,18 +1834,15 @@ def set_grand_total_and_outstanding_amount(party_amount, dt, party_account_curre else: grand_total = doc.rounded_total or doc.grand_total outstanding_amount = doc.outstanding_amount - elif dt == "Fees": - grand_total = doc.grand_total - outstanding_amount = doc.outstanding_amount elif dt == "Dunning": grand_total = doc.grand_total outstanding_amount = doc.grand_total else: if party_account_currency == doc.company_currency: - grand_total = flt(doc.get("base_rounded_total") or doc.base_grand_total) + grand_total = flt(doc.get("base_rounded_total") or doc.get("base_grand_total")) else: - grand_total = flt(doc.get("rounded_total") or doc.grand_total) - outstanding_amount = grand_total - flt(doc.advance_paid) + grand_total = flt(doc.get("rounded_total") or doc.get("grand_total")) + outstanding_amount = doc.get("outstanding_amount") or (grand_total - flt(doc.advance_paid)) return grand_total, outstanding_amount From ae5c05081d30277a50723a9c2fb6e24f70341b74 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 18 Aug 2022 17:41:01 +0530 Subject: [PATCH 07/27] chore: remove unwanted field "provisional_expense_account" from SCR (backport #31847) (#31886) chore: remove unwanted field "provisional_expense_account" from SCR (#31847) (cherry picked from commit 7e88eb549f7059e494455c642e966bb72d0dc5e7) Co-authored-by: Sagar Sharma --- .../subcontracting_receipt.json | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json index 94304865603..cb5b8c06ddd 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json @@ -51,8 +51,6 @@ "in_words", "bill_no", "bill_date", - "accounting_details_section", - "provisional_expense_account", "more_info", "status", "column_break_39", @@ -524,19 +522,6 @@ "options": "Company", "read_only": 1 }, - { - "collapsible": 1, - "fieldname": "accounting_details_section", - "fieldtype": "Section Break", - "label": "Accounting Details" - }, - { - "fieldname": "provisional_expense_account", - "fieldtype": "Link", - "hidden": 1, - "label": "Provisional Expense Account", - "options": "Account" - }, { "default": "0", "fieldname": "is_return", @@ -599,7 +584,7 @@ ], "is_submittable": 1, "links": [], - "modified": "2022-08-15 14:30:29.447307", + "modified": "2022-08-16 09:56:41.199435", "modified_by": "Administrator", "module": "Subcontracting", "name": "Subcontracting Receipt", From 6656d23e45261c6a32750aa3652510e3e40a8650 Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Thu, 18 Aug 2022 15:31:20 +0000 Subject: [PATCH 08/27] perf: use `create_custom_fields` (#31853) * perf: use `create_custom_fields` * fix: default must be a string (cherry picked from commit aafb7352830342ddef3e0cc8cf520b885957098f) --- .../tally_migration/tally_migration.py | 41 ++++++++------ .../woocommerce_settings.py | 41 +++++++------- erpnext/setup/install.py | 55 +++++++++---------- 3 files changed, 68 insertions(+), 69 deletions(-) diff --git a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py index 7d676e42359..cd4aaee2c45 100644 --- a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py +++ b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py @@ -12,7 +12,9 @@ from decimal import Decimal import frappe from bs4 import BeautifulSoup as bs from frappe import _ -from frappe.custom.doctype.custom_field.custom_field import create_custom_field +from frappe.custom.doctype.custom_field.custom_field import ( + create_custom_fields as _create_custom_fields, +) from frappe.model.document import Document from frappe.utils.data import format_datetime @@ -577,22 +579,25 @@ class TallyMigration(Document): new_year.save() oldest_year = new_year - def create_custom_fields(doctypes): - tally_guid_df = { - "fieldtype": "Data", - "fieldname": "tally_guid", - "read_only": 1, - "label": "Tally GUID", - } - tally_voucher_no_df = { - "fieldtype": "Data", - "fieldname": "tally_voucher_no", - "read_only": 1, - "label": "Tally Voucher Number", - } - for df in [tally_guid_df, tally_voucher_no_df]: - for doctype in doctypes: - create_custom_field(doctype, df) + def create_custom_fields(): + _create_custom_fields( + { + ("Journal Entry", "Purchase Invoice", "Sales Invoice"): [ + { + "fieldtype": "Data", + "fieldname": "tally_guid", + "read_only": 1, + "label": "Tally GUID", + }, + { + "fieldtype": "Data", + "fieldname": "tally_voucher_no", + "read_only": 1, + "label": "Tally Voucher Number", + }, + ] + } + ) def create_price_list(): frappe.get_doc( @@ -628,7 +633,7 @@ class TallyMigration(Document): create_fiscal_years(vouchers) create_price_list() - create_custom_fields(["Journal Entry", "Purchase Invoice", "Sales Invoice"]) + create_custom_fields() total = len(vouchers) is_last = False diff --git a/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.py b/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.py index 2e18776a927..4aa98aab56b 100644 --- a/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.py +++ b/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.py @@ -6,7 +6,7 @@ from urllib.parse import urlparse import frappe from frappe import _ -from frappe.custom.doctype.custom_field.custom_field import create_custom_field +from frappe.custom.doctype.custom_field.custom_field import create_custom_fields from frappe.model.document import Document from frappe.utils.nestedset import get_root_of @@ -19,27 +19,24 @@ class WoocommerceSettings(Document): def create_delete_custom_fields(self): if self.enable_sync: - custom_fields = {} - # create - for doctype in ["Customer", "Sales Order", "Item", "Address"]: - df = dict( - fieldname="woocommerce_id", - label="Woocommerce ID", - fieldtype="Data", - read_only=1, - print_hide=1, - ) - create_custom_field(doctype, df) - - for doctype in ["Customer", "Address"]: - df = dict( - fieldname="woocommerce_email", - label="Woocommerce Email", - fieldtype="Data", - read_only=1, - print_hide=1, - ) - create_custom_field(doctype, df) + create_custom_fields( + { + ("Customer", "Sales Order", "Item", "Address"): dict( + fieldname="woocommerce_id", + label="Woocommerce ID", + fieldtype="Data", + read_only=1, + print_hide=1, + ), + ("Customer", "Address"): dict( + fieldname="woocommerce_email", + label="Woocommerce Email", + fieldtype="Data", + read_only=1, + print_hide=1, + ), + } + ) if not frappe.get_value("Item Group", {"name": _("WooCommerce Products")}): item_group = frappe.new_doc("Item Group") diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py index 7d7e6b5e076..2076dde5199 100644 --- a/erpnext/setup/install.py +++ b/erpnext/setup/install.py @@ -4,7 +4,7 @@ import frappe from frappe import _ -from frappe.custom.doctype.custom_field.custom_field import create_custom_field +from frappe.custom.doctype.custom_field.custom_field import create_custom_fields from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to from frappe.utils import cint @@ -83,35 +83,32 @@ def setup_currency_exchange(): def create_print_setting_custom_fields(): - create_custom_field( - "Print Settings", + create_custom_fields( { - "label": _("Compact Item Print"), - "fieldname": "compact_item_print", - "fieldtype": "Check", - "default": 1, - "insert_after": "with_letterhead", - }, - ) - create_custom_field( - "Print Settings", - { - "label": _("Print UOM after Quantity"), - "fieldname": "print_uom_after_quantity", - "fieldtype": "Check", - "default": 0, - "insert_after": "compact_item_print", - }, - ) - create_custom_field( - "Print Settings", - { - "label": _("Print taxes with zero amount"), - "fieldname": "print_taxes_with_zero_amount", - "fieldtype": "Check", - "default": 0, - "insert_after": "allow_print_for_cancelled", - }, + "Print Settings": [ + { + "label": _("Compact Item Print"), + "fieldname": "compact_item_print", + "fieldtype": "Check", + "default": "1", + "insert_after": "with_letterhead", + }, + { + "label": _("Print UOM after Quantity"), + "fieldname": "print_uom_after_quantity", + "fieldtype": "Check", + "default": "0", + "insert_after": "compact_item_print", + }, + { + "label": _("Print taxes with zero amount"), + "fieldname": "print_taxes_with_zero_amount", + "fieldtype": "Check", + "default": "0", + "insert_after": "allow_print_for_cancelled", + }, + ] + } ) From da69cc5477c0648a026f1eef1c2d38d7e0a82a6e Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Thu, 18 Aug 2022 16:45:11 +0530 Subject: [PATCH 09/27] fix: additional-cost in items table (cherry picked from commit d7ed4093d8f494affb9929f7ad86cc954e48a8e1) --- .../subcontracting_order.py | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py index 71cdc94a3ae..1fd07464617 100644 --- a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py +++ b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py @@ -83,23 +83,23 @@ class SubcontractingOrder(SubcontractingController): self.set_missing_values_in_items() def set_missing_values_in_additional_costs(self): - if self.get("additional_costs"): - self.total_additional_costs = sum(flt(item.amount) for item in self.get("additional_costs")) + self.total_additional_costs = sum(flt(item.amount) for item in self.get("additional_costs")) - if self.total_additional_costs: - if self.distribute_additional_costs_based_on == "Amount": - total_amt = sum(flt(item.amount) for item in self.get("items")) - for item in self.items: - item.additional_cost_per_qty = ( - (item.amount * self.total_additional_costs) / total_amt - ) / item.qty - else: - total_qty = sum(flt(item.qty) for item in self.get("items")) - additional_cost_per_qty = self.total_additional_costs / total_qty - for item in self.items: - item.additional_cost_per_qty = additional_cost_per_qty + if self.total_additional_costs: + if self.distribute_additional_costs_based_on == "Amount": + total_amt = sum(flt(item.amount) for item in self.get("items")) + for item in self.items: + item.additional_cost_per_qty = ( + (item.amount * self.total_additional_costs) / total_amt + ) / item.qty + else: + total_qty = sum(flt(item.qty) for item in self.get("items")) + additional_cost_per_qty = self.total_additional_costs / total_qty + for item in self.items: + item.additional_cost_per_qty = additional_cost_per_qty else: - self.total_additional_costs = 0 + for item in self.items: + item.additional_cost_per_qty = 0 def set_missing_values_in_service_items(self): for idx, item in enumerate(self.get("service_items")): From d48487ada2c733ed9e88900f0244069a4ba8d0ef Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Thu, 18 Aug 2022 17:16:29 +0530 Subject: [PATCH 10/27] fix: base_amount and exchange_rate in additional-cost table (cherry picked from commit eabd3135f0f9d0ca788729c9391fd72ee8a6f871) --- erpnext/stock/landed_taxes_and_charges_common.js | 2 +- .../subcontracting_order/subcontracting_order.js | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/landed_taxes_and_charges_common.js b/erpnext/stock/landed_taxes_and_charges_common.js index ff8a69fb033..78bfd5dd1ac 100644 --- a/erpnext/stock/landed_taxes_and_charges_common.js +++ b/erpnext/stock/landed_taxes_and_charges_common.js @@ -1,4 +1,4 @@ -let document_list = ['Landed Cost Voucher', 'Stock Entry']; +let document_list = ['Landed Cost Voucher', 'Stock Entry', 'Subcontracting Order']; document_list.forEach((doctype) => { frappe.ui.form.on(doctype, { diff --git a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js index dbd337afd43..c20f8ab6653 100644 --- a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js +++ b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js @@ -3,6 +3,8 @@ frappe.provide('erpnext.buying'); +{% include 'erpnext/stock/landed_taxes_and_charges_common.js' %}; + frappe.ui.form.on('Subcontracting Order', { setup: (frm) => { frm.get_field("items").grid.cannot_add_rows = true; @@ -136,6 +138,16 @@ frappe.ui.form.on('Subcontracting Order', { } }); +frappe.ui.form.on('Landed Cost Taxes and Charges', { + amount: function (frm, cdt, cdn) { + frm.events.set_base_amount(frm, cdt, cdn); + }, + + expense_account: function (frm, cdt, cdn) { + frm.events.set_account_currency(frm, cdt, cdn); + } +}); + erpnext.buying.SubcontractingOrderController = class SubcontractingOrderController { setup() { this.frm.custom_make_buttons = { From 7ff54145711a68399f36fdb84aace052c6625db2 Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Thu, 18 Aug 2022 17:20:22 +0530 Subject: [PATCH 11/27] chore: move "set_missing_values_in_additional_costs" from SCO to SC" (cherry picked from commit ea82fe5bc20e4a06c40b9840c2ec536208c3fc3b) --- .../controllers/subcontracting_controller.py | 19 +++++++++++++++++++ .../subcontracting_order.py | 19 ------------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/erpnext/controllers/subcontracting_controller.py b/erpnext/controllers/subcontracting_controller.py index 2a2f8f562e7..a944cb8fcf7 100644 --- a/erpnext/controllers/subcontracting_controller.py +++ b/erpnext/controllers/subcontracting_controller.py @@ -720,6 +720,25 @@ class SubcontractingController(StockController): sco_doc = frappe.get_doc("Subcontracting Order", sco) sco_doc.update_status() + def set_missing_values_in_additional_costs(self): + self.total_additional_costs = sum(flt(item.amount) for item in self.get("additional_costs")) + + if self.total_additional_costs: + if self.distribute_additional_costs_based_on == "Amount": + total_amt = sum(flt(item.amount) for item in self.get("items")) + for item in self.items: + item.additional_cost_per_qty = ( + (item.amount * self.total_additional_costs) / total_amt + ) / item.qty + else: + total_qty = sum(flt(item.qty) for item in self.get("items")) + additional_cost_per_qty = self.total_additional_costs / total_qty + for item in self.items: + item.additional_cost_per_qty = additional_cost_per_qty + else: + for item in self.items: + item.additional_cost_per_qty = 0 + @frappe.whitelist() def get_current_stock(self): if self.doctype in ["Purchase Receipt", "Subcontracting Receipt"]: diff --git a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py index 1fd07464617..0495fb41749 100644 --- a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py +++ b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py @@ -82,25 +82,6 @@ class SubcontractingOrder(SubcontractingController): self.set_missing_values_in_supplied_items() self.set_missing_values_in_items() - def set_missing_values_in_additional_costs(self): - self.total_additional_costs = sum(flt(item.amount) for item in self.get("additional_costs")) - - if self.total_additional_costs: - if self.distribute_additional_costs_based_on == "Amount": - total_amt = sum(flt(item.amount) for item in self.get("items")) - for item in self.items: - item.additional_cost_per_qty = ( - (item.amount * self.total_additional_costs) / total_amt - ) / item.qty - else: - total_qty = sum(flt(item.qty) for item in self.get("items")) - additional_cost_per_qty = self.total_additional_costs / total_qty - for item in self.items: - item.additional_cost_per_qty = additional_cost_per_qty - else: - for item in self.items: - item.additional_cost_per_qty = 0 - def set_missing_values_in_service_items(self): for idx, item in enumerate(self.get("service_items")): self.items[idx].service_cost_per_qty = item.amount / self.items[idx].qty From 9e60dd32e863d286b51b144faeb0b55e5c34a9de Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Thu, 18 Aug 2022 19:50:00 +0530 Subject: [PATCH 12/27] fix: recalculate rate of items based on "Recalculate Rate" checkbox (cherry picked from commit 2fc683368403cf6341bf09fcfbd367f9777efa94) --- .../subcontracting_receipt/subcontracting_receipt.py | 2 +- .../subcontracting_receipt_item.json | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py index 0c4ec6fb76f..51007c56358 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py @@ -125,7 +125,7 @@ class SubcontractingReceipt(SubcontractingController): item.rm_cost_per_qty = item.rm_supp_cost / item.qty rm_supp_cost.pop(item.name) - if self.is_new() and item.rm_supp_cost > 0: + if item.recalculate_rate: item.rate = ( item.rm_cost_per_qty + (item.service_cost_per_qty or 0) + item.additional_cost_per_qty ) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json index 437fc41f5e4..dcde6359929 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json +++ b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json @@ -29,6 +29,7 @@ "rate_and_amount", "rate", "amount", + "recalculate_rate", "column_break_19", "rm_cost_per_qty", "service_cost_per_qty", @@ -460,12 +461,18 @@ "fieldname": "accounting_details_section", "fieldtype": "Section Break", "label": "Accounting Details" + }, + { + "default": "1", + "fieldname": "recalculate_rate", + "fieldtype": "Check", + "label": "Recalculate Rate" } ], "idx": 1, "istable": 1, "links": [], - "modified": "2022-08-15 14:51:10.613347", + "modified": "2022-08-18 19:42:24.313449", "modified_by": "Administrator", "module": "Subcontracting", "name": "Subcontracting Receipt Item", From 3b222339b84ba9d8e0d1f4ea8798ea419f623d71 Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Thu, 18 Aug 2022 20:26:34 +0530 Subject: [PATCH 13/27] chore: add additional-cost table in SCR (cherry picked from commit 256b4245d51d28cccbca2d0c0037961b0a16112f) # Conflicts: # erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json --- .../stock/landed_taxes_and_charges_common.js | 2 +- .../subcontracting_receipt.js | 12 +++++++ .../subcontracting_receipt.json | 36 +++++++++++++++++++ .../subcontracting_receipt.py | 1 + 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/landed_taxes_and_charges_common.js b/erpnext/stock/landed_taxes_and_charges_common.js index 78bfd5dd1ac..1d76a3d95a1 100644 --- a/erpnext/stock/landed_taxes_and_charges_common.js +++ b/erpnext/stock/landed_taxes_and_charges_common.js @@ -1,4 +1,4 @@ -let document_list = ['Landed Cost Voucher', 'Stock Entry', 'Subcontracting Order']; +let document_list = ['Landed Cost Voucher', 'Stock Entry', 'Subcontracting Order', 'Subcontracting Receipt']; document_list.forEach((doctype) => { frappe.ui.form.on(doctype, { diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js index 35fec8bc33c..aff76eb50fa 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js @@ -3,6 +3,8 @@ frappe.provide('erpnext.buying'); +{% include 'erpnext/stock/landed_taxes_and_charges_common.js' %}; + frappe.ui.form.on('Subcontracting Receipt', { setup: (frm) => { frm.get_field('supplied_items').grid.cannot_add_rows = true; @@ -128,6 +130,16 @@ frappe.ui.form.on('Subcontracting Receipt', { }, }); +frappe.ui.form.on('Landed Cost Taxes and Charges', { + amount: function (frm, cdt, cdn) { + frm.events.set_base_amount(frm, cdt, cdn); + }, + + expense_account: function (frm, cdt, cdn) { + frm.events.set_account_currency(frm, cdt, cdn); + } +}); + frappe.ui.form.on('Subcontracting Receipt Item', { item_code(frm) { set_missing_values(frm); diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json index cb5b8c06ddd..ee96c50ba14 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json @@ -47,6 +47,10 @@ "raw_material_details", "get_current_stock", "supplied_items", + "additional_costs_section", + "distribute_additional_costs_based_on", + "additional_costs", + "total_additional_costs", "section_break_46", "in_words", "bill_no", @@ -580,11 +584,43 @@ "fieldtype": "Link", "label": "Project", "options": "Project" + }, + { + "collapsible": 1, + "collapsible_depends_on": "total_additional_costs", + "depends_on": "eval:(doc.docstatus == 0 || doc.total_additional_costs)", + "fieldname": "additional_costs_section", + "fieldtype": "Section Break", + "label": "Additional Costs" + }, + { + "default": "Qty", + "fieldname": "distribute_additional_costs_based_on", + "fieldtype": "Select", + "label": "Distribute Additional Costs Based On ", + "options": "Qty\nAmount" + }, + { + "fieldname": "additional_costs", + "fieldtype": "Table", + "label": "Additional Costs", + "options": "Landed Cost Taxes and Charges" + }, + { + "fieldname": "total_additional_costs", + "fieldtype": "Currency", + "label": "Total Additional Costs", + "print_hide_if_no_value": 1, + "read_only": 1 } ], "is_submittable": 1, "links": [], +<<<<<<< HEAD "modified": "2022-08-16 09:56:41.199435", +======= + "modified": "2022-08-18 15:48:57.419191", +>>>>>>> 256b4245d5 (chore: add additional-cost table in SCR) "modified_by": "Administrator", "module": "Subcontracting", "name": "Subcontracting Receipt", diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py index 51007c56358..f8b71ea0283 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py @@ -103,6 +103,7 @@ class SubcontractingReceipt(SubcontractingController): @frappe.whitelist() def set_missing_values(self): + self.set_missing_values_in_additional_costs() self.set_missing_values_in_supplied_items() self.set_missing_values_in_items() From e099e10c8eef3c497be2298ff087c315fee393a2 Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Fri, 19 Aug 2022 11:46:27 +0530 Subject: [PATCH 14/27] fix: test "test_pending_and_received_qty" (cherry picked from commit addd7347d888701f5ff9031a37aeaa25c97dda14) --- .../test_subcontracted_item_to_be_received.py | 25 ++++++++++++------- .../controllers/subcontracting_controller.py | 4 +-- .../subcontracting_order.py | 6 ++--- .../subcontracting_receipt.py | 6 ++--- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/erpnext/buying/report/subcontracted_item_to_be_received/test_subcontracted_item_to_be_received.py b/erpnext/buying/report/subcontracted_item_to_be_received/test_subcontracted_item_to_be_received.py index c772c1a1b17..d13d9701f31 100644 --- a/erpnext/buying/report/subcontracted_item_to_be_received/test_subcontracted_item_to_be_received.py +++ b/erpnext/buying/report/subcontracted_item_to_be_received/test_subcontracted_item_to_be_received.py @@ -4,6 +4,8 @@ # Decompiled by https://python-decompiler.com +import copy + import frappe from frappe.tests.utils import FrappeTestCase @@ -11,10 +13,12 @@ from erpnext.buying.report.subcontracted_item_to_be_received.subcontracted_item_ execute, ) from erpnext.controllers.tests.test_subcontracting_controller import ( + get_rm_items, get_subcontracting_order, make_service_item, + make_stock_in_entry, + make_stock_transfer_entry, ) -from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry from erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order import ( make_subcontracting_receipt, ) @@ -36,15 +40,18 @@ class TestSubcontractedItemToBeReceived(FrappeTestCase): sco = get_subcontracting_order( service_items=service_items, supplier_warehouse="_Test Warehouse 1 - _TC" ) - make_stock_entry( - item_code="_Test Item", target="_Test Warehouse 1 - _TC", qty=100, basic_rate=100 - ) - make_stock_entry( - item_code="_Test Item Home Desktop 100", - target="_Test Warehouse 1 - _TC", - qty=100, - basic_rate=100, + rm_items = get_rm_items(sco.supplied_items) + itemwise_details = make_stock_in_entry(rm_items=rm_items) + + for item in rm_items: + item["sco_rm_detail"] = sco.items[0].name + + make_stock_transfer_entry( + sco_no=sco.name, + rm_items=rm_items, + itemwise_details=copy.deepcopy(itemwise_details), ) + make_subcontracting_receipt_against_sco(sco.name) sco.reload() col, data = execute( diff --git a/erpnext/controllers/subcontracting_controller.py b/erpnext/controllers/subcontracting_controller.py index a944cb8fcf7..1372c89d470 100644 --- a/erpnext/controllers/subcontracting_controller.py +++ b/erpnext/controllers/subcontracting_controller.py @@ -490,7 +490,7 @@ class SubcontractingController(StockController): row.item_code, row.get(self.subcontract_data.order_field), ) and transfer_item.qty > 0: - qty = self.__get_qty_based_on_material_transfer(row, transfer_item) or 0 + qty = flt(self.__get_qty_based_on_material_transfer(row, transfer_item)) transfer_item.qty -= qty self.__add_supplied_item(row, transfer_item.get("item_details"), qty) @@ -749,7 +749,7 @@ class SubcontractingController(StockController): {"item_code": item.rm_item_code, "warehouse": self.supplier_warehouse}, "actual_qty", ) - item.current_stock = flt(actual_qty) or 0 + item.current_stock = flt(actual_qty) @property def sub_contracted_items(self): diff --git a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py index 0495fb41749..156f027617f 100644 --- a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py +++ b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py @@ -95,9 +95,7 @@ class SubcontractingOrder(SubcontractingController): def set_missing_values_in_items(self): total_qty = total = 0 for item in self.items: - item.rate = ( - item.rm_cost_per_qty + item.service_cost_per_qty + (item.additional_cost_per_qty or 0) - ) + item.rate = item.rm_cost_per_qty + item.service_cost_per_qty + flt(item.additional_cost_per_qty) item.amount = item.qty * item.rate total_qty += flt(item.qty) total += flt(item.amount) @@ -168,7 +166,7 @@ class SubcontractingOrder(SubcontractingController): total_required_qty = total_supplied_qty = 0 for item in self.supplied_items: total_required_qty += item.required_qty - total_supplied_qty += item.supplied_qty or 0 + total_supplied_qty += flt(item.supplied_qty) if total_supplied_qty: status = "Partial Material Transferred" if total_supplied_qty >= total_required_qty: diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py index f8b71ea0283..021d9aa8547 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py @@ -3,7 +3,7 @@ import frappe from frappe import _ -from frappe.utils import cint, getdate, nowdate +from frappe.utils import cint, flt, getdate, nowdate from erpnext.controllers.subcontracting_controller import SubcontractingController @@ -128,10 +128,10 @@ class SubcontractingReceipt(SubcontractingController): if item.recalculate_rate: item.rate = ( - item.rm_cost_per_qty + (item.service_cost_per_qty or 0) + item.additional_cost_per_qty + flt(item.rm_cost_per_qty) + flt(item.service_cost_per_qty) + flt(item.additional_cost_per_qty) ) - item.received_qty = item.qty + (item.rejected_qty or 0) + item.received_qty = item.qty + flt(item.rejected_qty) item.amount = item.qty * item.rate total_qty += item.qty total_amount += item.amount From 9a29e3c9f2f97b9e422538a3c9ae44b88e98e31e Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Fri, 19 Aug 2022 11:10:00 +0530 Subject: [PATCH 15/27] chore: add test for additional-cost (cherry picked from commit c247cf728c6aaaa55a47c8148df807944a515a6e) --- .../tests/test_subcontracting_controller.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/erpnext/controllers/tests/test_subcontracting_controller.py b/erpnext/controllers/tests/test_subcontracting_controller.py index 4fab8058b86..bc503f5440a 100644 --- a/erpnext/controllers/tests/test_subcontracting_controller.py +++ b/erpnext/controllers/tests/test_subcontracting_controller.py @@ -36,6 +36,36 @@ class TestSubcontractingController(FrappeTestCase): sco.remove_empty_rows() self.assertEqual((len_before - 1), len(sco.service_items)) + def test_set_missing_values_in_additional_costs(self): + sco = get_subcontracting_order(do_not_submit=1) + + rate_without_additional_cost = sco.items[0].rate + amount_without_additional_cost = sco.items[0].amount + + additional_amount = 120 + sco.append( + "additional_costs", + { + "expense_account": "Cost of Goods Sold - _TC", + "description": "Test", + "amount": additional_amount, + }, + ) + sco.save() + + additional_cost_per_qty = additional_amount / sco.items[0].qty + + self.assertEqual(sco.items[0].additional_cost_per_qty, additional_cost_per_qty) + self.assertEqual(rate_without_additional_cost + additional_cost_per_qty, sco.items[0].rate) + self.assertEqual(amount_without_additional_cost + additional_amount, sco.items[0].amount) + + sco.additional_costs = [] + sco.save() + + self.assertEqual(sco.items[0].additional_cost_per_qty, 0) + self.assertEqual(rate_without_additional_cost, sco.items[0].rate) + self.assertEqual(amount_without_additional_cost, sco.items[0].amount) + def test_create_raw_materials_supplied(self): sco = get_subcontracting_order() sco.supplied_items = None From 376293326b49d7c9daeb7007f72b13dfaf265797 Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Fri, 19 Aug 2022 15:30:50 +0530 Subject: [PATCH 16/27] chore: conflicts --- .../subcontracting_receipt/subcontracting_receipt.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json index ee96c50ba14..3aa8e61ae09 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json @@ -616,11 +616,7 @@ ], "is_submittable": 1, "links": [], -<<<<<<< HEAD - "modified": "2022-08-16 09:56:41.199435", -======= "modified": "2022-08-18 15:48:57.419191", ->>>>>>> 256b4245d5 (chore: add additional-cost table in SCR) "modified_by": "Administrator", "module": "Subcontracting", "name": "Subcontracting Receipt", From 200a971743066450d95509a8deb3af1d601a557e Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 19 Aug 2022 17:11:13 +0530 Subject: [PATCH 17/27] fix(pos): edge case while closing pos (#31892) --- .../doctype/pos_closing_entry/pos_closing_entry.js | 9 +++++++++ .../pos_closing_entry/pos_closing_entry.json | 13 +++++++++++-- .../doctype/pos_closing_entry/pos_closing_entry.py | 3 +++ .../pos_invoice_merge_log.json | 11 ++++++++++- .../pos_invoice_merge_log/pos_invoice_merge_log.py | 7 ++++++- 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js index 98f3420d87e..1d596c1bfbb 100644 --- a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js +++ b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js @@ -36,6 +36,15 @@ frappe.ui.form.on('POS Closing Entry', { }); set_html_data(frm); + + if (frm.doc.docstatus == 1) { + if (!frm.doc.posting_date) { + frm.set_value("posting_date", frappe.datetime.nowdate()); + } + if (!frm.doc.posting_time) { + frm.set_value("posting_time", frappe.datetime.now_time()); + } + } }, refresh: function(frm) { diff --git a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.json b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.json index d6e35c6a50d..9d15e6cf357 100644 --- a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.json +++ b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.json @@ -11,6 +11,7 @@ "period_end_date", "column_break_3", "posting_date", + "posting_time", "pos_opening_entry", "status", "section_break_5", @@ -51,7 +52,6 @@ "fieldtype": "Datetime", "in_list_view": 1, "label": "Period End Date", - "read_only": 1, "reqd": 1 }, { @@ -219,6 +219,13 @@ "fieldtype": "Small Text", "label": "Error", "read_only": 1 + }, + { + "fieldname": "posting_time", + "fieldtype": "Time", + "label": "Posting Time", + "no_copy": 1, + "reqd": 1 } ], "is_submittable": 1, @@ -228,10 +235,11 @@ "link_fieldname": "pos_closing_entry" } ], - "modified": "2021-10-20 16:19:25.340565", + "modified": "2022-08-01 11:37:14.991228", "modified_by": "Administrator", "module": "Accounts", "name": "POS Closing Entry", + "naming_rule": "Expression (old style)", "owner": "Administrator", "permissions": [ { @@ -278,5 +286,6 @@ ], "sort_field": "modified", "sort_order": "DESC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py index 49aab0d0bbf..655c4ec0035 100644 --- a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py +++ b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py @@ -15,6 +15,9 @@ from erpnext.controllers.status_updater import StatusUpdater class POSClosingEntry(StatusUpdater): def validate(self): + self.posting_date = self.posting_date or frappe.utils.nowdate() + self.posting_time = self.posting_time or frappe.utils.nowtime() + if frappe.db.get_value("POS Opening Entry", self.pos_opening_entry, "status") != "Open": frappe.throw(_("Selected POS Opening Entry should be open."), title=_("Invalid Opening Entry")) diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json index d7620870780..a0594556474 100644 --- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json +++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json @@ -6,6 +6,7 @@ "engine": "InnoDB", "field_order": [ "posting_date", + "posting_time", "merge_invoices_based_on", "column_break_3", "pos_closing_entry", @@ -105,12 +106,19 @@ "label": "Customer Group", "mandatory_depends_on": "eval:doc.merge_invoices_based_on == 'Customer Group'", "options": "Customer Group" + }, + { + "fieldname": "posting_time", + "fieldtype": "Time", + "label": "Posting Time", + "no_copy": 1, + "reqd": 1 } ], "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-09-14 11:17:19.001142", + "modified": "2022-08-01 11:36:42.456429", "modified_by": "Administrator", "module": "Accounts", "name": "POS Invoice Merge Log", @@ -173,5 +181,6 @@ ], "sort_field": "modified", "sort_order": "DESC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py index 5003a1d6a81..81a234a20a7 100644 --- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py +++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py @@ -9,7 +9,7 @@ from frappe import _ from frappe.core.page.background_jobs.background_jobs import get_info from frappe.model.document import Document from frappe.model.mapper import map_child_doc, map_doc -from frappe.utils import cint, flt, getdate, nowdate +from frappe.utils import cint, flt, get_time, getdate, nowdate, nowtime from frappe.utils.background_jobs import enqueue from frappe.utils.scheduler import is_scheduler_inactive @@ -99,6 +99,7 @@ class POSInvoiceMergeLog(Document): sales_invoice.is_consolidated = 1 sales_invoice.set_posting_time = 1 sales_invoice.posting_date = getdate(self.posting_date) + sales_invoice.posting_time = get_time(self.posting_time) sales_invoice.save() sales_invoice.submit() @@ -115,6 +116,7 @@ class POSInvoiceMergeLog(Document): credit_note.is_consolidated = 1 credit_note.set_posting_time = 1 credit_note.posting_date = getdate(self.posting_date) + credit_note.posting_time = get_time(self.posting_time) # TODO: return could be against multiple sales invoice which could also have been consolidated? # credit_note.return_against = self.consolidated_invoice credit_note.save() @@ -402,6 +404,9 @@ def create_merge_logs(invoice_by_customer, closing_entry=None): merge_log.posting_date = ( getdate(closing_entry.get("posting_date")) if closing_entry else nowdate() ) + merge_log.posting_time = ( + get_time(closing_entry.get("posting_time")) if closing_entry else nowtime() + ) merge_log.customer = customer merge_log.pos_closing_entry = closing_entry.get("name") if closing_entry else None From 0db912998a8a971fdc010bc9f7017658e0d88db4 Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Fri, 19 Aug 2022 20:44:13 +0530 Subject: [PATCH 18/27] chore: allow subcontracting receipt backdated entry (cherry picked from commit f8c11847bbff996d20cc6385d61fe5df3fe75019) --- .../subcontracting_receipt.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json index 3aa8e61ae09..872d18e15ea 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json @@ -15,6 +15,7 @@ "company", "posting_date", "posting_time", + "set_posting_time", "is_return", "return_against", "accounting_dimensions_section", @@ -138,6 +139,7 @@ "label": "Date", "no_copy": 1, "print_width": "100px", + "read_only_depends_on": "eval: !doc.set_posting_time", "reqd": 1, "search_index": 1, "width": "100px" @@ -150,6 +152,7 @@ "no_copy": 1, "print_hide": 1, "print_width": "100px", + "read_only_depends_on": "eval: !doc.set_posting_time", "reqd": 1, "width": "100px" }, @@ -612,11 +615,19 @@ "label": "Total Additional Costs", "print_hide_if_no_value": 1, "read_only": 1 + }, + { + "default": "0", + "depends_on": "eval:doc.docstatus==0", + "fieldname": "set_posting_time", + "fieldtype": "Check", + "label": "Edit Posting Date and Time", + "print_hide": 1 } ], "is_submittable": 1, "links": [], - "modified": "2022-08-18 15:48:57.419191", + "modified": "2022-08-19 19:50:16.935124", "modified_by": "Administrator", "module": "Subcontracting", "name": "Subcontracting Receipt", From 19d29d186135bb0f9bd2111a6294a2d98547808c Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Fri, 19 Aug 2022 20:52:26 +0530 Subject: [PATCH 19/27] chore: add option for "Subcontracting Receipt" in "Voucher Type" (cherry picked from commit f92f3e0208cdfd6812c32a5820f7b08791f64e3c) --- .../doctype/repost_item_valuation/repost_item_valuation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js index 4cd40bf38ec..d6e00eada72 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js @@ -15,7 +15,7 @@ frappe.ui.form.on('Repost Item Valuation', { return { filters: { name: ['in', ['Purchase Receipt', 'Purchase Invoice', 'Delivery Note', - 'Sales Invoice', 'Stock Entry', 'Stock Reconciliation']] + 'Sales Invoice', 'Stock Entry', 'Stock Reconciliation', 'Subcontracting Receipt']] } }; }); From 6be77d5729906c6e43c7744b07289b490e05c891 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 20 Aug 2022 19:28:21 +0530 Subject: [PATCH 20/27] fix: make rate field read-only in subcontracting receipt item (backport #31905) (#31906) fix: make rate field read-only in subcontracting receipt item (#31905) (cherry picked from commit 588ca68171ed8c8f65d9a6c27323e29a2ac30e94) Co-authored-by: Sagar Sharma --- .../subcontracting_receipt_item.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json index dcde6359929..fd86895b9e3 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json +++ b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json @@ -194,6 +194,8 @@ "label": "Rate", "options": "currency", "print_width": "100px", + "read_only": 1, + "read_only_depends_on": "eval: doc.recalculate_rate", "width": "100px" }, { @@ -472,7 +474,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2022-08-18 19:42:24.313449", + "modified": "2022-08-20 17:16:48.269164", "modified_by": "Administrator", "module": "Subcontracting", "name": "Subcontracting Receipt Item", From 78b39d6ca4e4a54833c52c9614b7a8ee72207ffa Mon Sep 17 00:00:00 2001 From: Maharshi Patel Date: Fri, 19 Aug 2022 12:30:47 +0530 Subject: [PATCH 21/27] fix: TDS calculation for advance payment "against_voucher": ["is", "not set"] was used in query due to which if TDS was added on "advance" payment vouchers and then reconciled against purchase invoice. it will not find those vouchers and consider this as first-time threshold due to which it will calculate Tax for all transactions. (cherry picked from commit a4521437825a960e14556fa3963bd1bd1a55a2dc) --- .../doctype/tax_withholding_category/tax_withholding_category.py | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py index a519d8be736..6004e2b19b2 100644 --- a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py +++ b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py @@ -318,7 +318,6 @@ def get_advance_vouchers( "is_cancelled": 0, "party_type": party_type, "party": ["in", parties], - "against_voucher": ["is", "not set"], } if company: From a76732613e605ef0b3fd3618612b32e7fa2bbed5 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 16 Aug 2022 16:39:28 +0530 Subject: [PATCH 22/27] fix: incorrect tax amt due to different exchange rate in PR and PI (cherry picked from commit 5fd0770372c07dbec89669e1dcdb4d98f1fbca90) --- erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index de3927e45b1..e6ff1281d91 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -1791,4 +1791,6 @@ def make_purchase_receipt(source_name, target_doc=None): target_doc, ) + doc.set_onload("ignore_price_list", True) + return doc From 981add9b6f99b63c21c464e4a7e0c4ffd28cb5bb Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 16 Aug 2022 09:27:42 +0530 Subject: [PATCH 23/27] fix: incorrect buying amount in Gross Profit rpt (cherry picked from commit 967dd398e7ff7207aaa4c7f5808bcac6084d44cb) --- erpnext/accounts/report/gross_profit/gross_profit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index 526ea9d6e2e..54af2259154 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -616,7 +616,7 @@ class GrossProfitGenerator(object): previous_stock_value = len(my_sle) > i + 1 and flt(my_sle[i + 1].stock_value) or 0.0 if previous_stock_value: - return (previous_stock_value - flt(sle.stock_value)) * flt(row.qty) / abs(flt(sle.qty)) + return abs(previous_stock_value - flt(sle.stock_value)) * flt(row.qty) / abs(flt(sle.qty)) else: return flt(row.qty) * self.get_average_buying_rate(row, item_code) else: From 0bfb774bdf90864133c04898b6ae57a5a8317f59 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 22 Aug 2022 18:38:21 +0530 Subject: [PATCH 24/27] fix: don't allow to create SCR directly (backport #31924) (#31926) fix: don't allow to create SCR directly (#31924) (cherry picked from commit bf5c43322a2fdf299a031ee2b864f5da0d9e15a9) Co-authored-by: Sagar Sharma --- .../doctype/subcontracting_receipt/subcontracting_receipt.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json index 872d18e15ea..84e95548e17 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json @@ -625,9 +625,10 @@ "print_hide": 1 } ], + "in_create": 1, "is_submittable": 1, "links": [], - "modified": "2022-08-19 19:50:16.935124", + "modified": "2022-08-22 17:30:40.827517", "modified_by": "Administrator", "module": "Subcontracting", "name": "Subcontracting Receipt", From b6d2de2cc11b7abf955d7765db8d2874752a5a9a Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 21 Aug 2022 17:51:05 +0530 Subject: [PATCH 25/27] fix: Cash and non trade discount calculation (cherry picked from commit 3b15966cc9fb2cf91eca9105f767d8775845f7fa) --- erpnext/accounts/doctype/gl_entry/gl_entry.py | 2 +- .../doctype/sales_invoice/sales_invoice.js | 4 ++ .../doctype/sales_invoice/sales_invoice.py | 16 ------- erpnext/controllers/accounts_controller.py | 46 ++++++++++--------- erpnext/controllers/taxes_and_totals.py | 16 ++++--- .../public/js/controllers/taxes_and_totals.js | 10 ++++ 6 files changed, 49 insertions(+), 45 deletions(-) diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index 1987c8340d4..7227b95818f 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -366,7 +366,7 @@ def update_outstanding_amt( if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]: ref_doc = frappe.get_doc(against_voucher_type, against_voucher) - # Didn't use db_set for optimisation purpose + # Didn't use db_set for optimization purpose ref_doc.outstanding_amount = bal frappe.db.set_value(against_voucher_type, against_voucher, "outstanding_amount", bal) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index ba4cdd606e9..a06da72ccbf 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -479,9 +479,13 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e is_cash_or_non_trade_discount() { this.frm.set_df_property("additional_discount_account", "hidden", 1 - this.frm.doc.is_cash_or_non_trade_discount); + this.frm.set_df_property("additional_discount_account", "reqd", this.frm.doc.is_cash_or_non_trade_discount); + if (!this.frm.doc.is_cash_or_non_trade_discount) { this.frm.set_value("additional_discount_account", ""); } + + this.calculate_taxes_and_totals(); } }; diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 19a234d9df3..4008863e9ba 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -1033,22 +1033,6 @@ class SalesInvoice(SellingController): ) ) - if self.apply_discount_on == "Grand Total" and self.get("is_cash_or_discount_account"): - gl_entries.append( - self.get_gl_dict( - { - "account": self.additional_discount_account, - "against": self.debit_to, - "debit": self.base_discount_amount, - "debit_in_account_currency": self.discount_amount, - "cost_center": self.cost_center, - "project": self.project, - }, - self.currency, - item=self, - ) - ) - def make_tax_gl_entries(self, gl_entries): enable_discount_accounting = cint( frappe.db.get_single_value("Selling Settings", "enable_discount_accounting") diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 70d2bc68a11..28070d23774 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1109,17 +1109,17 @@ class AccountsController(TransactionBase): frappe.db.get_single_value("Selling Settings", "enable_discount_accounting") ) + if self.doctype == "Purchase Invoice": + dr_or_cr = "credit" + rev_dr_cr = "debit" + supplier_or_customer = self.supplier + + else: + dr_or_cr = "debit" + rev_dr_cr = "credit" + supplier_or_customer = self.customer + if enable_discount_accounting: - if self.doctype == "Purchase Invoice": - dr_or_cr = "credit" - rev_dr_cr = "debit" - supplier_or_customer = self.supplier - - else: - dr_or_cr = "debit" - rev_dr_cr = "credit" - supplier_or_customer = self.customer - for item in self.get("items"): if item.get("discount_amount") and item.get("discount_account"): discount_amount = item.discount_amount * item.qty @@ -1173,18 +1173,22 @@ class AccountsController(TransactionBase): ) ) - if self.get("discount_amount") and self.get("additional_discount_account"): - gl_entries.append( - self.get_gl_dict( - { - "account": self.additional_discount_account, - "against": supplier_or_customer, - dr_or_cr: self.discount_amount, - "cost_center": self.cost_center, - }, - item=self, - ) + if ( + (enable_discount_accounting or self.is_cash_or_non_trade_discount) + and self.get("additional_discount_account") + and self.get("discount_amount") + ): + gl_entries.append( + self.get_gl_dict( + { + "account": self.additional_discount_account, + "against": supplier_or_customer, + dr_or_cr: self.discount_amount, + "cost_center": self.cost_center, + }, + item=self, ) + ) def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield): from erpnext.controllers.status_updater import get_allowance_for diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py index 0d8cffe03f8..bc38d08b809 100644 --- a/erpnext/controllers/taxes_and_totals.py +++ b/erpnext/controllers/taxes_and_totals.py @@ -37,6 +37,11 @@ class calculate_taxes_and_totals(object): self.set_discount_amount() self.apply_discount_amount() + # Update grand total as per cash and non trade discount + if self.doc.apply_discount_on == "Grand Total" and self.doc.get("is_cash_or_non_trade_discount"): + self.doc.grand_total -= self.doc.discount_amount + self.doc.base_grand_total -= self.doc.base_discount_amount + self.calculate_shipping_charges() if self.doc.doctype in ["Sales Invoice", "Purchase Invoice"]: @@ -500,9 +505,6 @@ class calculate_taxes_and_totals(object): else: self.doc.grand_total = flt(self.doc.net_total) - if self.doc.apply_discount_on == "Grand Total" and self.doc.get("is_cash_or_non_trade_discount"): - self.doc.grand_total -= self.doc.discount_amount - if self.doc.get("taxes"): self.doc.total_taxes_and_charges = flt( self.doc.grand_total - self.doc.net_total - flt(self.doc.rounding_adjustment), @@ -597,16 +599,16 @@ class calculate_taxes_and_totals(object): if not self.doc.apply_discount_on: frappe.throw(_("Please select Apply Discount On")) + self.doc.base_discount_amount = flt( + self.doc.discount_amount * self.doc.conversion_rate, self.doc.precision("base_discount_amount") + ) + if self.doc.apply_discount_on == "Grand Total" and self.doc.get( "is_cash_or_non_trade_discount" ): self.discount_amount_applied = True return - self.doc.base_discount_amount = flt( - self.doc.discount_amount * self.doc.conversion_rate, self.doc.precision("base_discount_amount") - ) - total_for_discount_amount = self.get_total_for_discount_amount() taxes = self.doc.get("taxes") net_total = 0 diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js index 16b0b4a866f..3b9e23a3f51 100644 --- a/erpnext/public/js/controllers/taxes_and_totals.js +++ b/erpnext/public/js/controllers/taxes_and_totals.js @@ -39,6 +39,12 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments { this._calculate_taxes_and_totals(); this.calculate_discount_amount(); + // # Update grand total as per cash and non trade discount + if (this.frm.doc.apply_discount_on == "Grand Total" && this.frm.doc.is_cash_or_non_trade_discount) { + this.frm.doc.grand_total -= this.frm.doc.discount_amount; + this.frm.doc.base_grand_total -= this.frm.doc.base_discount_amount; + } + await this.calculate_shipping_charges(); // Advance calculation applicable to Sales /Purchase Invoice @@ -633,6 +639,10 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments { this.frm.doc.base_discount_amount = flt(this.frm.doc.discount_amount * this.frm.doc.conversion_rate, precision("base_discount_amount")); + if (this.frm.doc.apply_discount_on == "Grand Total" && this.frm.doc.is_cash_or_non_trade_discount) { + return + } + var total_for_discount_amount = this.get_total_for_discount_amount(); var net_total = 0; // calculate item amount after Discount Amount From 3afb625ff86f30269ce75f22f5b7c0d7f890ef34 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 22 Aug 2022 08:57:58 +0530 Subject: [PATCH 26/27] fix: Test cases (cherry picked from commit ae3dce0cbdca40294739b547d85bfca9b1e28c0f) --- erpnext/controllers/accounts_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 28070d23774..e689d567a17 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1174,7 +1174,7 @@ class AccountsController(TransactionBase): ) if ( - (enable_discount_accounting or self.is_cash_or_non_trade_discount) + (enable_discount_accounting or self.get("is_cash_or_non_trade_discount")) and self.get("additional_discount_account") and self.get("discount_amount") ): From 856a64b77c4d1e7bb966b0c605c2c050cc8d4630 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 23 Aug 2022 09:12:20 +0530 Subject: [PATCH 27/27] chore: Linting issues (cherry picked from commit 1cb7ae16ab156da2fd43ec915316947b0b8db964) --- erpnext/public/js/controllers/taxes_and_totals.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js index 3b9e23a3f51..4c3e9dcf0a7 100644 --- a/erpnext/public/js/controllers/taxes_and_totals.js +++ b/erpnext/public/js/controllers/taxes_and_totals.js @@ -640,7 +640,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments { precision("base_discount_amount")); if (this.frm.doc.apply_discount_on == "Grand Total" && this.frm.doc.is_cash_or_non_trade_discount) { - return + return; } var total_for_discount_amount = this.get_total_for_discount_amount();