diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index e53299ac2b7..ec2b5caf9d2 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -2590,10 +2590,12 @@ class AccountsController(TransactionBase): prev_doc = self.get("items")[0].get("purchase_order") prev_doctype = "Purchase Order" prev_doctype_name = "purchase_order" - else: + elif self.doctype == "Sales Order": prev_doc = self.get("items")[0].get("prevdoc_docname") prev_doctype = "Quotation" prev_doctype_name = "prevdoc_docname" + else: + return None, None, None return prev_doc, prev_doctype, prev_doctype_name def linked_order_has_payment_terms(self, po_or_so, fieldname, doctype): @@ -2690,7 +2692,9 @@ class AccountsController(TransactionBase): for d in self.get("payment_schedule"): d.validate_from_to_dates("discount_date", "due_date") - if self.doctype == "Sales Order" and getdate(d.due_date) < getdate(self.transaction_date): + if self.doctype in ["Sales Order", "Quotation"] and getdate(d.due_date) < getdate( + self.transaction_date + ): frappe.throw( _("Row {0}: Due Date in the Payment Terms table cannot be before Posting Date").format( d.idx diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 593a80d92bc..b4e433ac805 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -441,12 +441,11 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False, ar filtered_items = args.get("filtered_children", []) child_filter = d.name in filtered_items if filtered_items else True return child_filter - + automatically_fetch_payment_terms = cint( frappe.get_single_value("Accounts Settings", "automatically_fetch_payment_terms") ) - doclist = get_mapped_doc( "Quotation", source_name, @@ -464,7 +463,6 @@ 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, diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py index 6f33a753c4e..4d4d485c71a 100644 --- a/erpnext/selling/doctype/quotation/test_quotation.py +++ b/erpnext/selling/doctype/quotation/test_quotation.py @@ -174,12 +174,11 @@ class TestQuotation(FrappeTestCase): quotation.insert() self.assertTrue(quotation.payment_schedule) - + @change_settings( "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 @@ -322,7 +321,11 @@ class TestQuotation(FrappeTestCase): @change_settings( "Accounts Settings", - {"add_taxes_from_item_tax_template": 0, "add_taxes_from_taxes_and_charges_template": 0,"automatically_fetch_payment_terms": 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 @@ -1065,7 +1068,7 @@ class TestQuotation(FrappeTestCase): quotation.reload() self.assertEqual(quotation.status, "Open") - + @change_settings( "Accounts Settings", {"automatically_fetch_payment_terms": 1}, @@ -1117,7 +1120,6 @@ class TestQuotation(FrappeTestCase): self.assertEqual(sales_order.payment_schedule[1].payment_amount, 5000) - test_records = frappe.get_test_records("Quotation") diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index 27e2f72bc4f..e649b8e9383 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -1669,7 +1669,6 @@ }, { "default": "0", - "fetch_from": "customer.is_internal_customer", "fieldname": "ignore_default_payment_terms_template", "fieldtype": "Check", "hidden": 1, @@ -1681,7 +1680,7 @@ "idx": 105, "is_submittable": 1, "links": [], - "modified": "2026-03-06 15:03:35.717402", + "modified": "2026-03-06 15:33:49.059029", "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 268219e3c2e..dbd7f406432 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -52,13 +52,16 @@ class SalesOrder(SellingController): from typing import TYPE_CHECKING if TYPE_CHECKING: + from frappe.types import DF + from erpnext.accounts.doctype.payment_schedule.payment_schedule import PaymentSchedule from erpnext.accounts.doctype.pricing_rule_detail.pricing_rule_detail import PricingRuleDetail - from erpnext.accounts.doctype.sales_taxes_and_charges.sales_taxes_and_charges import SalesTaxesandCharges + from erpnext.accounts.doctype.sales_taxes_and_charges.sales_taxes_and_charges import ( + SalesTaxesandCharges, + ) from erpnext.selling.doctype.sales_order_item.sales_order_item import SalesOrderItem from erpnext.selling.doctype.sales_team.sales_team import SalesTeam from erpnext.stock.doctype.packed_item.packed_item import PackedItem - from frappe.types import DF additional_discount_percentage: DF.Float address_display: DF.SmallText | None @@ -96,7 +99,9 @@ class SalesOrder(SellingController): customer_group: DF.Link | None customer_name: DF.Data | None delivery_date: DF.Date | None - delivery_status: DF.Literal["Not Delivered", "Fully Delivered", "Partly Delivered", "Closed", "Not Applicable"] + delivery_status: DF.Literal[ + "Not Delivered", "Fully Delivered", "Partly Delivered", "Closed", "Not Applicable" + ] disable_rounded_total: DF.Check discount_amount: DF.Currency dispatch_address: DF.SmallText | None @@ -149,7 +154,17 @@ class SalesOrder(SellingController): shipping_rule: DF.Link | None skip_delivery_note: DF.Check source: DF.Link | None - status: DF.Literal["", "Draft", "On Hold", "To Deliver and Bill", "To Bill", "To Deliver", "Completed", "Cancelled", "Closed"] + status: DF.Literal[ + "", + "Draft", + "On Hold", + "To Deliver and Bill", + "To Bill", + "To Deliver", + "Completed", + "Cancelled", + "Closed", + ] tax_category: DF.Link | None tax_id: DF.Data | None taxes: DF.Table[SalesTaxesandCharges]