From 70b401e610c51adbb221bbe83b89cca664c3c755 Mon Sep 17 00:00:00 2001 From: SowmyaArunachalam Date: Wed, 28 Jan 2026 15:38:17 +0530 Subject: [PATCH 1/7] feat(selling-settings): add checkbox to recalculate payment date --- erpnext/selling/doctype/quotation/quotation.py | 10 ++++++++-- .../doctype/selling_settings/selling_settings.json | 7 +++++++ .../doctype/selling_settings/selling_settings.py | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 603aeb9c7ec..a7ab743acd8 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -8,7 +8,7 @@ import frappe from frappe import _ from frappe.model.document import Document from frappe.model.mapper import get_mapped_doc -from frappe.utils import flt, getdate, nowdate +from frappe.utils import cint, flt, getdate, nowdate from erpnext.controllers.selling_controller import SellingController @@ -467,13 +467,19 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False, ar }, "Sales Taxes and Charges": {"doctype": "Sales Taxes and Charges", "reset_value": True}, "Sales Team": {"doctype": "Sales Team", "add_if_empty": True}, - "Payment Schedule": {"doctype": "Payment Schedule", "add_if_empty": True}, }, target_doc, set_missing_values, ignore_permissions=ignore_permissions, ) + automatically_fetch_payment_terms = cint( + frappe.get_single_value("Selling Settings", "automatically_fetch_payment_terms_from_quotation") + ) + + if automatically_fetch_payment_terms: + doclist.set_payment_schedule() + return doclist diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.json b/erpnext/selling/doctype/selling_settings/selling_settings.json index 53e9d42a7ab..375d2e2d465 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.json +++ b/erpnext/selling/doctype/selling_settings/selling_settings.json @@ -41,6 +41,7 @@ "allow_zero_qty_in_quotation", "allow_zero_qty_in_sales_order", "set_zero_rate_for_expired_batch", + "automatically_fetch_payment_terms_from_quotation", "section_break_avhb", "enable_utm", "experimental_section", @@ -320,6 +321,12 @@ "fieldname": "enable_utm", "fieldtype": "Check", "label": "Enable UTM" + }, + { + "default": "0", + "fieldname": "automatically_fetch_payment_terms_from_quotation", + "fieldtype": "Check", + "label": "Automatically Fetch Payment Terms from Quotation" } ], "grid_page_length": 50, diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.py b/erpnext/selling/doctype/selling_settings/selling_settings.py index 8621f5f066d..837b6357825 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.py +++ b/erpnext/selling/doctype/selling_settings/selling_settings.py @@ -38,6 +38,7 @@ class SellingSettings(Document): allow_sales_order_creation_for_expired_quotation: DF.Check allow_zero_qty_in_quotation: DF.Check allow_zero_qty_in_sales_order: DF.Check + automatically_fetch_payment_terms_from_quotation: DF.Check blanket_order_allowance: DF.Float cust_master_name: DF.Literal["Customer Name", "Naming Series", "Auto Name"] customer_group: DF.Link | None From b1149fe950bcdbba2b2e55e5314617b0e611e0f5 Mon Sep 17 00:00:00 2001 From: SowmyaArunachalam Date: Wed, 28 Jan 2026 22:23:10 +0530 Subject: [PATCH 2/7] fix: consider payment term only when enabled --- .../selling/doctype/quotation/quotation.py | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index a7ab743acd8..8f39e857ea1 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -451,34 +451,33 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False, ar child_filter = d.name in filtered_items if filtered_items else True return child_filter - doclist = get_mapped_doc( - "Quotation", - source_name, - { - "Quotation": { - "doctype": "Sales Order", - "validation": {"docstatus": ["=", 1]}, - }, - "Quotation Item": { - "doctype": "Sales Order Item", - "field_map": {"parent": "prevdoc_docname", "name": "quotation_item"}, - "postprocess": update_item, - "condition": lambda d: can_map_row(d) and select_item(d), - }, - "Sales Taxes and Charges": {"doctype": "Sales Taxes and Charges", "reset_value": True}, - "Sales Team": {"doctype": "Sales Team", "add_if_empty": True}, - }, - target_doc, - set_missing_values, - ignore_permissions=ignore_permissions, - ) - automatically_fetch_payment_terms = cint( frappe.get_single_value("Selling Settings", "automatically_fetch_payment_terms_from_quotation") ) + mapping = { + "Quotation": {"doctype": "Sales Order", "validation": {"docstatus": ["=", 1]}}, + "Quotation Item": { + "doctype": "Sales Order Item", + "field_map": {"parent": "prevdoc_docname", "name": "quotation_item"}, + "postprocess": update_item, + "condition": lambda d: can_map_row(d) and select_item(d), + }, + "Sales Taxes and Charges": {"doctype": "Sales Taxes and Charges", "reset_value": True}, + "Sales Team": {"doctype": "Sales Team", "add_if_empty": True}, + } + if automatically_fetch_payment_terms: - doclist.set_payment_schedule() + mapping["Payment Schedule"] = {"doctype": "Payment Schedule", "add_if_empty": True} + + doclist = get_mapped_doc( + "Quotation", + source_name, + mapping, + target_doc, + set_missing_values, + ignore_permissions=ignore_permissions, + ) return doclist From 5611e9168ec742c1e1300c9cd48fd7190d6c07d8 Mon Sep 17 00:00:00 2001 From: SowmyaArunachalam Date: Wed, 28 Jan 2026 22:24:59 +0530 Subject: [PATCH 3/7] test: enable automatically_fetch_payment_terms_from_quotation --- erpnext/selling/doctype/quotation/test_quotation.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py index fb03984f3e8..ec994233400 100644 --- a/erpnext/selling/doctype/quotation/test_quotation.py +++ b/erpnext/selling/doctype/quotation/test_quotation.py @@ -181,6 +181,10 @@ class TestQuotation(IntegrationTestCase): self.assertTrue(quotation.payment_schedule) + @IntegrationTestCase.change_settings( + "Selling Settings", + {"automatically_fetch_payment_terms_from_quotation": 1}, + ) def test_make_sales_order_terms_copied(self): from erpnext.selling.doctype.quotation.quotation import make_sales_order @@ -325,6 +329,10 @@ class TestQuotation(IntegrationTestCase): "Accounts Settings", {"add_taxes_from_item_tax_template": 0, "add_taxes_from_taxes_and_charges_template": 0}, ) + @IntegrationTestCase.change_settings( + "Selling Settings", + {"automatically_fetch_payment_terms_from_quotation": 1}, + ) def test_make_sales_order_with_terms(self): from erpnext.selling.doctype.quotation.quotation import make_sales_order From f23dc079147b2a09e01a08ae94146bb5c48077d3 Mon Sep 17 00:00:00 2001 From: SowmyaArunachalam Date: Thu, 5 Feb 2026 11:08:38 +0530 Subject: [PATCH 4/7] fix: handle payment terms template when disabled --- erpnext/selling/doctype/quotation/quotation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 8f39e857ea1..2c794aa6f68 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -469,6 +469,8 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False, ar if automatically_fetch_payment_terms: mapping["Payment Schedule"] = {"doctype": "Payment Schedule", "add_if_empty": True} + else: + mapping["Quotation"]["field_no_map"] = ["payment_terms_template"] doclist = get_mapped_doc( "Quotation", From 8b9e02fd44a3b3fbb76386ffecba5638dfeddb03 Mon Sep 17 00:00:00 2001 From: SowmyaArunachalam Date: Wed, 18 Feb 2026 21:28:26 +0530 Subject: [PATCH 5/7] fix: set default to 1 --- .../selling/doctype/selling_settings/selling_settings.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.json b/erpnext/selling/doctype/selling_settings/selling_settings.json index 375d2e2d465..48fffc77f9b 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.json +++ b/erpnext/selling/doctype/selling_settings/selling_settings.json @@ -321,9 +321,9 @@ "fieldname": "enable_utm", "fieldtype": "Check", "label": "Enable UTM" - }, + }, { - "default": "0", + "default": "1", "fieldname": "automatically_fetch_payment_terms_from_quotation", "fieldtype": "Check", "label": "Automatically Fetch Payment Terms from Quotation" @@ -336,7 +336,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2026-02-12 10:38:34.605126", + "modified": "2026-02-18 21:25:56.307468", "modified_by": "Administrator", "module": "Selling", "name": "Selling Settings", From 99ed1c34f35344613aca48c82a2fa18b4a204c45 Mon Sep 17 00:00:00 2001 From: SowmyaArunachalam Date: Fri, 27 Feb 2026 01:09:09 +0530 Subject: [PATCH 6/7] fix: fetch payment terms from quotation --- .../accounts_settings/accounts_settings.json | 4 +- erpnext/controllers/accounts_controller.py | 29 +++++++------- erpnext/public/js/controllers/transaction.js | 1 + .../selling/doctype/quotation/quotation.py | 38 +++++++++---------- .../doctype/sales_order/sales_order.json | 11 +++++- .../doctype/sales_order/sales_order.py | 1 + .../selling_settings/selling_settings.json | 9 +---- .../selling_settings/selling_settings.py | 1 - 8 files changed, 50 insertions(+), 44 deletions(-) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index 874da99bdbf..ee734184452 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -205,7 +205,7 @@ "description": "Payment Terms from orders will be fetched into the invoices as is", "fieldname": "automatically_fetch_payment_terms", "fieldtype": "Check", - "label": "Automatically Fetch Payment Terms from Order" + "label": "Automatically Fetch Payment Terms from Order/Quotation" }, { "description": "The percentage you are allowed to bill more against the amount ordered. For example, if the order value is $100 for an item and tolerance is set as 10%, then you are allowed to bill up to $110 ", @@ -697,7 +697,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2026-02-04 17:15:38.609327", + "modified": "2026-02-27 01:04:09.415288", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 184a60d685a..09a31eea4be 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -2526,13 +2526,14 @@ class AccountsController(TransactionBase): grand_total = flt(self.get("rounded_total") or self.grand_total) automatically_fetch_payment_terms = 0 - if self.doctype in ("Sales Invoice", "Purchase Invoice"): - base_grand_total = base_grand_total - flt(self.base_write_off_amount) - grand_total = grand_total - flt(self.write_off_amount) + if self.doctype in ("Sales Invoice", "Purchase Invoice", "Sales Order"): po_or_so, doctype, fieldname = self.get_order_details() automatically_fetch_payment_terms = cint( frappe.get_single_value("Accounts Settings", "automatically_fetch_payment_terms") ) + if self.doctype != "Sales Order": + base_grand_total = base_grand_total - flt(self.base_write_off_amount) + grand_total = grand_total - flt(self.write_off_amount) if self.get("total_advance"): if party_account_currency == self.company_currency: @@ -2548,7 +2549,7 @@ class AccountsController(TransactionBase): if not self.get("payment_schedule"): if ( - self.doctype in ["Sales Invoice", "Purchase Invoice"] + self.doctype in ["Sales Invoice", "Purchase Invoice", "Sales Order"] and automatically_fetch_payment_terms and self.linked_order_has_payment_terms(po_or_so, fieldname, doctype) ): @@ -2606,16 +2607,18 @@ class AccountsController(TransactionBase): if not self.get("items"): return None, None, None if self.doctype == "Sales Invoice": - po_or_so = self.get("items")[0].get("sales_order") - po_or_so_doctype = "Sales Order" - po_or_so_doctype_name = "sales_order" - + prev_doc = self.get("items")[0].get("sales_order") + prev_doctype = "Sales Order" + prev_doctype_name = "sales_order" + elif self.doctype == "Purchase Invoice": + prev_doc = self.get("items")[0].get("purchase_order") + prev_doctype = "Purchase Order" + prev_doctype_name = "purchase_order" else: - po_or_so = self.get("items")[0].get("purchase_order") - po_or_so_doctype = "Purchase Order" - po_or_so_doctype_name = "purchase_order" - - return po_or_so, po_or_so_doctype, po_or_so_doctype_name + prev_doc = self.get("items")[0].get("prevdoc_docname") + prev_doctype = "Quotation" + prev_doctype_name = "prevdoc_docname" + return prev_doc, prev_doctype, prev_doctype_name def linked_order_has_payment_terms(self, po_or_so, fieldname, doctype): if po_or_so and self.all_items_have_same_po_or_so(po_or_so, fieldname): diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index b3fa69c77e7..6c4260641ea 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -1307,6 +1307,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe if (this.frm.doc.transaction_date) { this.frm.transaction_date = this.frm.doc.transaction_date; frappe.ui.form.trigger(this.frm.doc.doctype, "currency"); + this.recalculate_terms(); } } diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 2c794aa6f68..5250f209d26 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -452,35 +452,35 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False, ar return child_filter automatically_fetch_payment_terms = cint( - frappe.get_single_value("Selling Settings", "automatically_fetch_payment_terms_from_quotation") + frappe.get_single_value("Accounts Settings", "automatically_fetch_payment_terms") ) - mapping = { - "Quotation": {"doctype": "Sales Order", "validation": {"docstatus": ["=", 1]}}, - "Quotation Item": { - "doctype": "Sales Order Item", - "field_map": {"parent": "prevdoc_docname", "name": "quotation_item"}, - "postprocess": update_item, - "condition": lambda d: can_map_row(d) and select_item(d), - }, - "Sales Taxes and Charges": {"doctype": "Sales Taxes and Charges", "reset_value": True}, - "Sales Team": {"doctype": "Sales Team", "add_if_empty": True}, - } - - if automatically_fetch_payment_terms: - mapping["Payment Schedule"] = {"doctype": "Payment Schedule", "add_if_empty": True} - else: - mapping["Quotation"]["field_no_map"] = ["payment_terms_template"] - doclist = get_mapped_doc( "Quotation", source_name, - mapping, + { + "Quotation": { + "doctype": "Sales Order", + "validation": {"docstatus": ["=", 1]}, + "field_no_map": ["payment_terms_template"], + }, + "Quotation Item": { + "doctype": "Sales Order Item", + "field_map": {"parent": "prevdoc_docname", "name": "quotation_item"}, + "postprocess": update_item, + "condition": lambda d: can_map_row(d) and select_item(d), + }, + "Sales Taxes and Charges": {"doctype": "Sales Taxes and Charges", "reset_value": True}, + "Sales Team": {"doctype": "Sales Team", "add_if_empty": True}, + }, target_doc, set_missing_values, ignore_permissions=ignore_permissions, ) + if automatically_fetch_payment_terms: + doclist.set_payment_schedule() + return doclist diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index 1b186352bfa..87816741728 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -123,6 +123,7 @@ "company_contact_person", "payment_schedule_section", "payment_terms_section", + "ignore_default_payment_terms_template", "payment_terms_template", "payment_schedule", "terms_section_break", @@ -1733,6 +1734,14 @@ "fieldtype": "Time", "label": "Time", "mandatory_depends_on": "is_internal_customer" + }, + { + "default": "0", + "fieldname": "ignore_default_payment_terms_template", + "fieldtype": "Check", + "hidden": 1, + "label": "Ignore Default Payment Terms Template", + "read_only": 1 } ], "grid_page_length": 50, @@ -1740,7 +1749,7 @@ "idx": 105, "is_submittable": 1, "links": [], - "modified": "2026-03-02 00:42:18.834823", + "modified": "2026-03-04 18:04:05.873483", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order", diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index a46d646e8f4..37d7ef1f162 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -117,6 +117,7 @@ class SalesOrder(SellingController): grand_total: DF.Currency group_same_items: DF.Check has_unit_price_items: DF.Check + ignore_default_payment_terms_template: DF.Check ignore_pricing_rule: DF.Check in_words: DF.Data | None incoterm: DF.Link | None diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.json b/erpnext/selling/doctype/selling_settings/selling_settings.json index 48fffc77f9b..6304a55c7d8 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.json +++ b/erpnext/selling/doctype/selling_settings/selling_settings.json @@ -41,7 +41,6 @@ "allow_zero_qty_in_quotation", "allow_zero_qty_in_sales_order", "set_zero_rate_for_expired_batch", - "automatically_fetch_payment_terms_from_quotation", "section_break_avhb", "enable_utm", "experimental_section", @@ -321,12 +320,6 @@ "fieldname": "enable_utm", "fieldtype": "Check", "label": "Enable UTM" - }, - { - "default": "1", - "fieldname": "automatically_fetch_payment_terms_from_quotation", - "fieldtype": "Check", - "label": "Automatically Fetch Payment Terms from Quotation" } ], "grid_page_length": 50, @@ -336,7 +329,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2026-02-18 21:25:56.307468", + "modified": "2026-02-27 00:47:46.003305", "modified_by": "Administrator", "module": "Selling", "name": "Selling Settings", diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.py b/erpnext/selling/doctype/selling_settings/selling_settings.py index 837b6357825..8621f5f066d 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.py +++ b/erpnext/selling/doctype/selling_settings/selling_settings.py @@ -38,7 +38,6 @@ class SellingSettings(Document): allow_sales_order_creation_for_expired_quotation: DF.Check allow_zero_qty_in_quotation: DF.Check allow_zero_qty_in_sales_order: DF.Check - automatically_fetch_payment_terms_from_quotation: DF.Check blanket_order_allowance: DF.Float cust_master_name: DF.Literal["Customer Name", "Naming Series", "Auto Name"] customer_group: DF.Link | None From 8aae46a25ed7ff0ca6329df787802c6c594e1937 Mon Sep 17 00:00:00 2001 From: SowmyaArunachalam Date: Fri, 27 Feb 2026 01:10:51 +0530 Subject: [PATCH 7/7] test: test payment terms with backdated entries --- .../doctype/quotation/test_quotation.py | 71 ++++++++++++++++--- 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py index ec994233400..bd1610276bb 100644 --- a/erpnext/selling/doctype/quotation/test_quotation.py +++ b/erpnext/selling/doctype/quotation/test_quotation.py @@ -182,8 +182,8 @@ class TestQuotation(IntegrationTestCase): self.assertTrue(quotation.payment_schedule) @IntegrationTestCase.change_settings( - "Selling Settings", - {"automatically_fetch_payment_terms_from_quotation": 1}, + "Accounts Settings", + {"automatically_fetch_payment_terms": 1}, ) def test_make_sales_order_terms_copied(self): from erpnext.selling.doctype.quotation.quotation import make_sales_order @@ -327,11 +327,11 @@ class TestQuotation(IntegrationTestCase): @IntegrationTestCase.change_settings( "Accounts Settings", - {"add_taxes_from_item_tax_template": 0, "add_taxes_from_taxes_and_charges_template": 0}, - ) - @IntegrationTestCase.change_settings( - "Selling Settings", - {"automatically_fetch_payment_terms_from_quotation": 1}, + { + "add_taxes_from_item_tax_template": 0, + "add_taxes_from_taxes_and_charges_template": 0, + "automatically_fetch_payment_terms": 1, + }, ) def test_make_sales_order_with_terms(self): from erpnext.selling.doctype.quotation.quotation import make_sales_order @@ -369,10 +369,13 @@ class TestQuotation(IntegrationTestCase): sales_order.save() self.assertEqual(sales_order.payment_schedule[0].payment_amount, 8906.00) - self.assertEqual(sales_order.payment_schedule[0].due_date, getdate(quotation.transaction_date)) + self.assertEqual( + getdate(sales_order.payment_schedule[0].due_date), getdate(quotation.transaction_date) + ) self.assertEqual(sales_order.payment_schedule[1].payment_amount, 8906.00) self.assertEqual( - sales_order.payment_schedule[1].due_date, getdate(add_days(quotation.transaction_date, 30)) + getdate(sales_order.payment_schedule[1].due_date), + getdate(add_days(quotation.transaction_date, 30)), ) def test_valid_till_before_transaction_date(self): @@ -1072,6 +1075,56 @@ class TestQuotation(IntegrationTestCase): quotation.reload() self.assertEqual(quotation.status, "Open") + @IntegrationTestCase.change_settings( + "Accounts Settings", + {"automatically_fetch_payment_terms": 1}, + ) + def test_make_sales_order_with_payment_terms(self): + from erpnext.selling.doctype.quotation.quotation import make_sales_order + + template = frappe.get_doc( + { + "doctype": "Payment Terms Template", + "template_name": "_Test Payment Terms Template for Quotation", + "terms": [ + { + "doctype": "Payment Terms Template Detail", + "invoice_portion": 50.00, + "credit_days_based_on": "Day(s) after invoice date", + "credit_days": 0, + }, + { + "doctype": "Payment Terms Template Detail", + "invoice_portion": 50.00, + "credit_days_based_on": "Day(s) after invoice date", + "credit_days": 10, + }, + ], + } + ).save() + + quotation = make_quotation(qty=10, rate=1000, do_not_submit=1) + quotation.transaction_date = add_days(nowdate(), -2) + quotation.valid_till = add_days(nowdate(), 10) + quotation.update({"payment_terms_template": template.name, "payment_schedule": []}) + quotation.save() + quotation.submit() + + self.assertEqual(quotation.payment_schedule[0].payment_amount, 5000) + self.assertEqual(quotation.payment_schedule[1].payment_amount, 5000) + self.assertEqual(quotation.payment_schedule[0].due_date, quotation.transaction_date) + self.assertEqual(quotation.payment_schedule[1].due_date, add_days(quotation.transaction_date, 10)) + + sales_order = make_sales_order(quotation.name) + sales_order.transaction_date = nowdate() + sales_order.delivery_date = nowdate() + sales_order.save() + + self.assertEqual(sales_order.payment_schedule[0].due_date, sales_order.transaction_date) + self.assertEqual(sales_order.payment_schedule[1].due_date, add_days(sales_order.transaction_date, 10)) + self.assertEqual(sales_order.payment_schedule[0].payment_amount, 5000) + self.assertEqual(sales_order.payment_schedule[1].payment_amount, 5000) + def enable_calculate_bundle_price(enable=1): selling_settings = frappe.get_doc("Selling Settings")