fix: fetch payment terms from quotation

(cherry picked from commit 99ed1c34f3)
This commit is contained in:
SowmyaArunachalam
2026-02-27 01:09:09 +05:30
committed by Mergify
parent 3b7410f2d3
commit b2f695310c
8 changed files with 50 additions and 44 deletions

View File

@@ -205,7 +205,7 @@
"description": "Payment Terms from orders will be fetched into the invoices as is", "description": "Payment Terms from orders will be fetched into the invoices as is",
"fieldname": "automatically_fetch_payment_terms", "fieldname": "automatically_fetch_payment_terms",
"fieldtype": "Check", "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 ", "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, "index_web_pages_for_search": 1,
"issingle": 1, "issingle": 1,
"links": [], "links": [],
"modified": "2026-02-04 17:15:38.609327", "modified": "2026-02-27 01:04:09.415288",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Accounts Settings", "name": "Accounts Settings",

View File

@@ -2525,13 +2525,14 @@ class AccountsController(TransactionBase):
grand_total = flt(self.get("rounded_total") or self.grand_total) grand_total = flt(self.get("rounded_total") or self.grand_total)
automatically_fetch_payment_terms = 0 automatically_fetch_payment_terms = 0
if self.doctype in ("Sales Invoice", "Purchase Invoice"): if self.doctype in ("Sales Invoice", "Purchase Invoice", "Sales Order"):
base_grand_total = base_grand_total - flt(self.base_write_off_amount)
grand_total = grand_total - flt(self.write_off_amount)
po_or_so, doctype, fieldname = self.get_order_details() po_or_so, doctype, fieldname = self.get_order_details()
automatically_fetch_payment_terms = cint( automatically_fetch_payment_terms = cint(
frappe.get_single_value("Accounts Settings", "automatically_fetch_payment_terms") 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 self.get("total_advance"):
if party_account_currency == self.company_currency: if party_account_currency == self.company_currency:
@@ -2547,7 +2548,7 @@ class AccountsController(TransactionBase):
if not self.get("payment_schedule"): if not self.get("payment_schedule"):
if ( if (
self.doctype in ["Sales Invoice", "Purchase Invoice"] self.doctype in ["Sales Invoice", "Purchase Invoice", "Sales Order"]
and automatically_fetch_payment_terms and automatically_fetch_payment_terms
and self.linked_order_has_payment_terms(po_or_so, fieldname, doctype) and self.linked_order_has_payment_terms(po_or_so, fieldname, doctype)
): ):
@@ -2605,16 +2606,18 @@ class AccountsController(TransactionBase):
if not self.get("items"): if not self.get("items"):
return None, None, None return None, None, None
if self.doctype == "Sales Invoice": if self.doctype == "Sales Invoice":
po_or_so = self.get("items")[0].get("sales_order") prev_doc = self.get("items")[0].get("sales_order")
po_or_so_doctype = "Sales Order" prev_doctype = "Sales Order"
po_or_so_doctype_name = "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: else:
po_or_so = self.get("items")[0].get("purchase_order") prev_doc = self.get("items")[0].get("prevdoc_docname")
po_or_so_doctype = "Purchase Order" prev_doctype = "Quotation"
po_or_so_doctype_name = "purchase_order" prev_doctype_name = "prevdoc_docname"
return prev_doc, prev_doctype, prev_doctype_name
return po_or_so, po_or_so_doctype, po_or_so_doctype_name
def linked_order_has_payment_terms(self, po_or_so, fieldname, doctype): 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): if po_or_so and self.all_items_have_same_po_or_so(po_or_so, fieldname):

View File

@@ -1307,6 +1307,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
if (this.frm.doc.transaction_date) { if (this.frm.doc.transaction_date) {
this.frm.transaction_date = this.frm.doc.transaction_date; this.frm.transaction_date = this.frm.doc.transaction_date;
frappe.ui.form.trigger(this.frm.doc.doctype, "currency"); frappe.ui.form.trigger(this.frm.doc.doctype, "currency");
this.recalculate_terms();
} }
} }

View File

@@ -447,35 +447,35 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False, ar
return child_filter return child_filter
automatically_fetch_payment_terms = cint( 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( doclist = get_mapped_doc(
"Quotation", "Quotation",
source_name, 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, target_doc,
set_missing_values, set_missing_values,
ignore_permissions=ignore_permissions, ignore_permissions=ignore_permissions,
) )
if automatically_fetch_payment_terms:
doclist.set_payment_schedule()
return doclist return doclist

View File

@@ -123,6 +123,7 @@
"company_contact_person", "company_contact_person",
"payment_schedule_section", "payment_schedule_section",
"payment_terms_section", "payment_terms_section",
"ignore_default_payment_terms_template",
"payment_terms_template", "payment_terms_template",
"payment_schedule", "payment_schedule",
"terms_section_break", "terms_section_break",
@@ -1733,6 +1734,14 @@
"fieldtype": "Time", "fieldtype": "Time",
"label": "Time", "label": "Time",
"mandatory_depends_on": "is_internal_customer" "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, "grid_page_length": 50,
@@ -1740,7 +1749,7 @@
"idx": 105, "idx": 105,
"is_submittable": 1, "is_submittable": 1,
"links": [], "links": [],
"modified": "2026-03-02 00:42:18.834823", "modified": "2026-03-04 18:04:05.873483",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Selling", "module": "Selling",
"name": "Sales Order", "name": "Sales Order",

View File

@@ -116,6 +116,7 @@ class SalesOrder(SellingController):
grand_total: DF.Currency grand_total: DF.Currency
group_same_items: DF.Check group_same_items: DF.Check
has_unit_price_items: DF.Check has_unit_price_items: DF.Check
ignore_default_payment_terms_template: DF.Check
ignore_pricing_rule: DF.Check ignore_pricing_rule: DF.Check
in_words: DF.Data | None in_words: DF.Data | None
incoterm: DF.Link | None incoterm: DF.Link | None

View File

@@ -41,7 +41,6 @@
"allow_zero_qty_in_quotation", "allow_zero_qty_in_quotation",
"allow_zero_qty_in_sales_order", "allow_zero_qty_in_sales_order",
"set_zero_rate_for_expired_batch", "set_zero_rate_for_expired_batch",
"automatically_fetch_payment_terms_from_quotation",
"section_break_avhb", "section_break_avhb",
"enable_utm", "enable_utm",
"experimental_section", "experimental_section",
@@ -321,12 +320,6 @@
"fieldname": "enable_utm", "fieldname": "enable_utm",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Enable UTM" "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, "grid_page_length": 50,
@@ -336,7 +329,7 @@
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"issingle": 1, "issingle": 1,
"links": [], "links": [],
"modified": "2026-02-18 21:25:56.307468", "modified": "2026-02-27 00:47:46.003305",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Selling", "module": "Selling",
"name": "Selling Settings", "name": "Selling Settings",

View File

@@ -38,7 +38,6 @@ class SellingSettings(Document):
allow_sales_order_creation_for_expired_quotation: DF.Check allow_sales_order_creation_for_expired_quotation: DF.Check
allow_zero_qty_in_quotation: DF.Check allow_zero_qty_in_quotation: DF.Check
allow_zero_qty_in_sales_order: DF.Check allow_zero_qty_in_sales_order: DF.Check
automatically_fetch_payment_terms_from_quotation: DF.Check
blanket_order_allowance: DF.Float blanket_order_allowance: DF.Float
cust_master_name: DF.Literal["Customer Name", "Naming Series", "Auto Name"] cust_master_name: DF.Literal["Customer Name", "Naming Series", "Auto Name"]
customer_group: DF.Link | None customer_group: DF.Link | None