diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 185ef4c22f0..e12ebd9c18e 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -3515,6 +3515,37 @@ def check_if_child_table_updated( return False +def merge_taxes(source_taxes, target_doc): + from erpnext.accounts.doctype.pos_invoice_merge_log.pos_invoice_merge_log import ( + update_item_wise_tax_detail, + ) + + existing_taxes = target_doc.get("taxes") or [] + idx = 1 + for tax in source_taxes: + found = False + for t in existing_taxes: + if t.account_head == tax.account_head and t.cost_center == tax.cost_center: + t.tax_amount = flt(t.tax_amount) + flt(tax.tax_amount_after_discount_amount) + t.base_tax_amount = flt(t.base_tax_amount) + flt(tax.base_tax_amount_after_discount_amount) + update_item_wise_tax_detail(t, tax) + found = True + + if not found: + tax.charge_type = "Actual" + tax.idx = idx + idx += 1 + tax.included_in_print_rate = 0 + tax.dont_recompute_tax = 1 + tax.row_id = "" + tax.tax_amount = tax.tax_amount_after_discount_amount + tax.base_tax_amount = tax.base_tax_amount_after_discount_amount + tax.item_wise_tax_detail = tax.item_wise_tax_detail + existing_taxes.append(tax) + + target_doc.set("taxes", existing_taxes) + + @erpnext.allow_regional def validate_regional(doc): pass diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 7bf8b9bed6d..ed2092fdb51 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -933,7 +933,7 @@ erpnext.utils.map_current_doc = function (opts) { if (opts.source_doctype) { let data_fields = []; - if (opts.source_doctype == "Purchase Receipt") { + if (["Purchase Receipt", "Delivery Note"].includes(opts.source_doctype)) { data_fields.push({ fieldname: "merge_taxes", fieldtype: "Check", @@ -959,7 +959,10 @@ erpnext.utils.map_current_doc = function (opts) { return; } opts.source_name = values; - if (opts.allow_child_item_selection || opts.source_doctype == "Purchase Receipt") { + if ( + opts.allow_child_item_selection || + ["Purchase Receipt", "Delivery Note"].includes(opts.source_doctype) + ) { // args contains filtered child docnames opts.args = args; } diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index 4b8c1e9d2c6..b41732e6fa8 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -10,7 +10,7 @@ from frappe.model.mapper import get_mapped_doc from frappe.model.utils import get_fetch_values from frappe.utils import cint, flt -from erpnext.controllers.accounts_controller import get_taxes_and_charges +from erpnext.controllers.accounts_controller import get_taxes_and_charges, merge_taxes from erpnext.controllers.selling_controller import SellingController from erpnext.stock.doctype.serial_no.serial_no import get_delivery_note_serial_no @@ -945,7 +945,7 @@ def get_returned_qty_map(delivery_note): @frappe.whitelist() -def make_sales_invoice(source_name, target_doc=None): +def make_sales_invoice(source_name, target_doc=None, args=None): doc = frappe.get_doc("Delivery Note", source_name) to_make_invoice_qty_map = {} @@ -959,6 +959,9 @@ def make_sales_invoice(source_name, target_doc=None): if len(target.get("items")) == 0: frappe.throw(_("All these items have already been Invoiced/Returned")) + if args and args.get("merge_taxes"): + merge_taxes(source.get("taxes") or [], target) + target.run_method("calculate_taxes_and_totals") # set company address @@ -1023,7 +1026,11 @@ def make_sales_invoice(source_name, target_doc=None): if not doc.get("is_return") else get_pending_qty(d) > 0, }, - "Sales Taxes and Charges": {"doctype": "Sales Taxes and Charges", "add_if_empty": True}, + "Sales Taxes and Charges": { + "doctype": "Sales Taxes and Charges", + "add_if_empty": True, + "ignore": args.get("merge_taxes") if args else 0, + }, "Sales Team": { "doctype": "Sales Team", "field_map": {"incentives": "incentives"}, diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index ed43d553713..c56c4788a5d 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -14,6 +14,7 @@ import erpnext from erpnext.accounts.utils import get_account_currency from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_enabled from erpnext.buying.utils import check_on_hold_or_closed_status +from erpnext.controllers.accounts_controller import merge_taxes from erpnext.controllers.buying_controller import BuyingController from erpnext.stock.doctype.delivery_note.delivery_note import make_inter_company_transaction @@ -1126,37 +1127,6 @@ def get_item_wise_returned_qty(pr_doc): ) -def merge_taxes(source_taxes, target_doc): - from erpnext.accounts.doctype.pos_invoice_merge_log.pos_invoice_merge_log import ( - update_item_wise_tax_detail, - ) - - existing_taxes = target_doc.get("taxes") or [] - idx = 1 - for tax in source_taxes: - found = False - for t in existing_taxes: - if t.account_head == tax.account_head and t.cost_center == tax.cost_center: - t.tax_amount = flt(t.tax_amount) + flt(tax.tax_amount_after_discount_amount) - t.base_tax_amount = flt(t.base_tax_amount) + flt(tax.base_tax_amount_after_discount_amount) - update_item_wise_tax_detail(t, tax) - found = True - - if not found: - tax.charge_type = "Actual" - tax.idx = idx - idx += 1 - tax.included_in_print_rate = 0 - tax.dont_recompute_tax = 1 - tax.row_id = "" - tax.tax_amount = tax.tax_amount_after_discount_amount - tax.base_tax_amount = tax.base_tax_amount_after_discount_amount - tax.item_wise_tax_detail = tax.item_wise_tax_detail - existing_taxes.append(tax) - - target_doc.set("taxes", existing_taxes) - - @frappe.whitelist() def make_purchase_invoice(source_name, target_doc=None, args=None): from erpnext.accounts.party import get_payment_terms_template