mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-26 16:34:46 +00:00
fix: fetch payment terms from quotation
(cherry picked from commit 99ed1c34f3)
# Conflicts:
# erpnext/accounts/doctype/accounts_settings/accounts_settings.json
# erpnext/controllers/accounts_controller.py
# erpnext/selling/doctype/sales_order/sales_order.json
# erpnext/selling/doctype/selling_settings/selling_settings.json
This commit is contained in:
committed by
Mergify
parent
ceba14cb0d
commit
6d99039bc1
@@ -216,7 +216,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 ",
|
||||||
@@ -671,7 +671,11 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
|
<<<<<<< HEAD
|
||||||
"modified": "2025-12-26 19:46:55.093717",
|
"modified": "2025-12-26 19:46:55.093717",
|
||||||
|
=======
|
||||||
|
"modified": "2026-02-27 01:04:09.415288",
|
||||||
|
>>>>>>> 99ed1c34f3 (fix: fetch payment terms from quotation)
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounts Settings",
|
"name": "Accounts Settings",
|
||||||
|
|||||||
@@ -2502,13 +2502,14 @@ class AccountsController(TransactionBase):
|
|||||||
grand_total = self.get("rounded_total") or self.grand_total
|
grand_total = 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.db.get_single_value("Accounts Settings", "automatically_fetch_payment_terms")
|
frappe.db.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:
|
||||||
@@ -2524,7 +2525,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)
|
||||||
):
|
):
|
||||||
@@ -2580,6 +2581,7 @@ class AccountsController(TransactionBase):
|
|||||||
|
|
||||||
def get_order_details(self):
|
def get_order_details(self):
|
||||||
if self.doctype == "Sales Invoice":
|
if self.doctype == "Sales Invoice":
|
||||||
|
<<<<<<< HEAD
|
||||||
po_or_so = self.get("items") and self.get("items")[0].get("sales_order")
|
po_or_so = self.get("items") and self.get("items")[0].get("sales_order")
|
||||||
po_or_so_doctype = "Sales Order"
|
po_or_so_doctype = "Sales Order"
|
||||||
po_or_so_doctype_name = "sales_order"
|
po_or_so_doctype_name = "sales_order"
|
||||||
@@ -2590,6 +2592,20 @@ class AccountsController(TransactionBase):
|
|||||||
po_or_so_doctype_name = "purchase_order"
|
po_or_so_doctype_name = "purchase_order"
|
||||||
|
|
||||||
return po_or_so, po_or_so_doctype, po_or_so_doctype_name
|
return po_or_so, po_or_so_doctype, po_or_so_doctype_name
|
||||||
|
=======
|
||||||
|
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:
|
||||||
|
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
|
||||||
|
>>>>>>> 99ed1c34f3 (fix: fetch payment terms from quotation)
|
||||||
|
|
||||||
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):
|
||||||
|
|||||||
@@ -1052,6 +1052,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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -443,35 +443,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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -120,6 +120,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",
|
||||||
@@ -1665,13 +1666,97 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"is_virtual": 1,
|
"is_virtual": 1,
|
||||||
"label": "Last Scanned Warehouse"
|
"label": "Last Scanned Warehouse"
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "is_subcontracted",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Is Subcontracted",
|
||||||
|
"print_hide": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "item_wise_tax_details",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"hidden": 1,
|
||||||
|
"label": "Item Wise Tax Details",
|
||||||
|
"no_copy": 1,
|
||||||
|
"options": "Item Wise Tax Detail",
|
||||||
|
"print_hide": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "totals_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hide_days": 1,
|
||||||
|
"hide_seconds": 1,
|
||||||
|
"label": "Totals",
|
||||||
|
"oldfieldtype": "Section Break",
|
||||||
|
"options": "fa fa-money",
|
||||||
|
"print_hide": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "base_totals_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Totals (Company Currency)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_nuxg",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_bgfw",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break_efew",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsible": 1,
|
||||||
|
"fieldname": "additional_discount_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hide_days": 1,
|
||||||
|
"hide_seconds": 1,
|
||||||
|
"label": "Additional Discount"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_ijxt",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsible": 1,
|
||||||
|
"fieldname": "utm_analytics_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "UTM Analytics"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "Now",
|
||||||
|
"depends_on": "is_internal_customer",
|
||||||
|
"fieldname": "transaction_time",
|
||||||
|
"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
|
||||||
|
>>>>>>> 99ed1c34f3 (fix: fetch payment terms from quotation)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 105,
|
"idx": 105,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
|
<<<<<<< HEAD
|
||||||
"modified": "2026-02-06 11:06:16.092658",
|
"modified": "2026-02-06 11:06:16.092658",
|
||||||
|
=======
|
||||||
|
"modified": "2026-03-04 18:04:05.873483",
|
||||||
|
>>>>>>> 99ed1c34f3 (fix: fetch payment terms from quotation)
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Sales Order",
|
"name": "Sales Order",
|
||||||
|
|||||||
@@ -111,6 +111,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
|
||||||
|
|||||||
@@ -40,7 +40,6 @@
|
|||||||
"set_zero_rate_for_expired_batch"
|
"set_zero_rate_for_expired_batch"
|
||||||
=======
|
=======
|
||||||
"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",
|
||||||
@@ -268,6 +267,7 @@
|
|||||||
"fieldname": "enable_utm",
|
"fieldname": "enable_utm",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Enable UTM"
|
"label": "Enable UTM"
|
||||||
|
<<<<<<< HEAD
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
@@ -275,6 +275,8 @@
|
|||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Automatically Fetch Payment Terms from Quotation"
|
"label": "Automatically Fetch Payment Terms from Quotation"
|
||||||
>>>>>>> 70b401e610 (feat(selling-settings): add checkbox to recalculate payment date)
|
>>>>>>> 70b401e610 (feat(selling-settings): add checkbox to recalculate payment date)
|
||||||
|
=======
|
||||||
|
>>>>>>> 99ed1c34f3 (fix: fetch payment terms from quotation)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"grid_page_length": 50,
|
"grid_page_length": 50,
|
||||||
@@ -283,11 +285,15 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
"modified": "2026-01-24 00:04:33.105916",
|
"modified": "2026-01-24 00:04:33.105916",
|
||||||
=======
|
=======
|
||||||
"modified": "2026-02-18 21:25:56.307468",
|
"modified": "2026-02-18 21:25:56.307468",
|
||||||
>>>>>>> 8b9e02fd44 (fix: set default to 1)
|
>>>>>>> 8b9e02fd44 (fix: set default to 1)
|
||||||
|
=======
|
||||||
|
"modified": "2026-02-27 00:47:46.003305",
|
||||||
|
>>>>>>> 99ed1c34f3 (fix: fetch payment terms from quotation)
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Selling Settings",
|
"name": "Selling Settings",
|
||||||
|
|||||||
@@ -26,7 +26,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
|
||||||
|
|||||||
Reference in New Issue
Block a user