From 92047e896c4294b5e7b30a2691e1f29c8e9ce3ed Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 22 Jun 2026 17:01:40 +0530 Subject: [PATCH] fix(selling): carry commission_rate through Make Delivery Note / Sales Invoice commission_rate is no_copy so it is not carried on Duplicate/amend, but the mapper also skips no_copy fields, leaving the mapped Delivery Note / Sales Invoice showing 0 commission until saved (it only re-fetched from the sales partner on save). Map commission_rate explicitly in the SO->DN, SO->SI and DN->SI mappers so it carries over immediately; Duplicate still does not copy it. --- erpnext/selling/doctype/sales_order/mapper.py | 9 ++++++++- .../doctype/sales_order/test_sales_order.py | 18 ++++++++++++++++++ erpnext/stock/doctype/delivery_note/mapper.py | 3 ++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/mapper.py b/erpnext/selling/doctype/sales_order/mapper.py index 086e6c5b6fd..d2972fdc302 100644 --- a/erpnext/selling/doctype/sales_order/mapper.py +++ b/erpnext/selling/doctype/sales_order/mapper.py @@ -245,7 +245,12 @@ def make_delivery_note( sre_details = get_sre_reserved_qty_details_for_voucher("Sales Order", source_name) mapper = { - "Sales Order": {"doctype": "Delivery Note", "validation": {"docstatus": ["=", 1]}}, + "Sales Order": { + "doctype": "Delivery Note", + "validation": {"docstatus": ["=", 1]}, + # commission_rate is no_copy (so it isn't carried on Duplicate), map it explicitly here + "field_map": {"commission_rate": "commission_rate"}, + }, "Sales Taxes and Charges": {"doctype": "Sales Taxes and Charges", "reset_value": True}, "Sales Team": {"doctype": "Sales Team", "add_if_empty": True}, } @@ -558,6 +563,8 @@ def make_sales_invoice( "doctype": "Sales Invoice", "field_map": { "party_account_currency": "party_account_currency", + # commission_rate is no_copy (so it isn't carried on Duplicate), map it explicitly here + "commission_rate": "commission_rate", }, "field_no_map": ["payment_terms_template"], "validation": {"docstatus": ["=", 1]}, diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py index c841bcdd02b..934141a2090 100644 --- a/erpnext/selling/doctype/sales_order/test_sales_order.py +++ b/erpnext/selling/doctype/sales_order/test_sales_order.py @@ -3063,6 +3063,24 @@ class TestSalesOrder(ERPNextTestSuite): finally: frappe.db.set_value("Item", "_Test Item", "grant_commission", 0) + def test_commission_rate_carried_through_mapper(self): + """commission_rate is no_copy, but Make Delivery Note / Sales Invoice still carries it.""" + from erpnext.selling.doctype.sales_order.mapper import make_delivery_note, make_sales_invoice + + original = frappe.db.get_value("Item", "_Test Item", "grant_commission") + frappe.db.set_value("Item", "_Test Item", "grant_commission", 1) + try: + so = make_sales_order(qty=10, rate=100, do_not_save=True) + so.sales_partner = "_Test Sales Partner India - 1" + so.commission_rate = 7 + so.submit() + + # carried to the mapped (unsaved) documents even though the field is no_copy + self.assertEqual(make_delivery_note(so.name).commission_rate, 7) + self.assertEqual(make_sales_invoice(so.name).commission_rate, 7) + finally: + frappe.db.set_value("Item", "_Test Item", "grant_commission", original) + def compare_payment_schedules(doc, doc1, doc2): for index, schedule in enumerate(doc1.get("payment_schedule")): diff --git a/erpnext/stock/doctype/delivery_note/mapper.py b/erpnext/stock/doctype/delivery_note/mapper.py index a77a94dcf88..605a2d22df6 100644 --- a/erpnext/stock/doctype/delivery_note/mapper.py +++ b/erpnext/stock/doctype/delivery_note/mapper.py @@ -132,7 +132,8 @@ def make_sales_invoice( { "Delivery Note": { "doctype": "Sales Invoice", - "field_map": {"is_return": "is_return"}, + # commission_rate is no_copy (so it isn't carried on Duplicate), map it explicitly here + "field_map": {"is_return": "is_return", "commission_rate": "commission_rate"}, "validation": {"docstatus": ["=", 1]}, }, "Delivery Note Item": {