mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-14 15:11:52 +00:00
fix: set conversion_rate on quotation created from customer
This commit is contained in:
@@ -11,6 +11,7 @@ from frappe.contacts.address_and_contact import (
|
|||||||
delete_contact_and_address,
|
delete_contact_and_address,
|
||||||
load_address_and_contact,
|
load_address_and_contact,
|
||||||
)
|
)
|
||||||
|
from frappe.model.document import Document
|
||||||
from frappe.model.mapper import get_mapped_doc
|
from frappe.model.mapper import get_mapped_doc
|
||||||
from frappe.model.naming import set_name_by_naming_series, set_name_from_naming_options
|
from frappe.model.naming import set_name_by_naming_series, set_name_from_naming_options
|
||||||
from frappe.model.utils.rename_doc import update_linked_doctypes
|
from frappe.model.utils.rename_doc import update_linked_doctypes
|
||||||
@@ -444,7 +445,7 @@ class Customer(TransactionBase):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_quotation(source_name, target_doc=None):
|
def make_quotation(source_name: str, target_doc: str | Document | None = None) -> Document:
|
||||||
def set_missing_values(source, target):
|
def set_missing_values(source, target):
|
||||||
_set_missing_values(source, target)
|
_set_missing_values(source, target)
|
||||||
|
|
||||||
@@ -457,9 +458,6 @@ def make_quotation(source_name, target_doc=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_doc.quotation_to = "Customer"
|
target_doc.quotation_to = "Customer"
|
||||||
target_doc.run_method("set_missing_values")
|
|
||||||
target_doc.run_method("set_other_charges")
|
|
||||||
target_doc.run_method("calculate_taxes_and_totals")
|
|
||||||
|
|
||||||
price_list, currency = frappe.db.get_value(
|
price_list, currency = frappe.db.get_value(
|
||||||
"Customer", {"name": source_name}, ["default_price_list", "default_currency"]
|
"Customer", {"name": source_name}, ["default_price_list", "default_currency"]
|
||||||
@@ -469,6 +467,10 @@ def make_quotation(source_name, target_doc=None):
|
|||||||
if currency:
|
if currency:
|
||||||
target_doc.currency = currency
|
target_doc.currency = currency
|
||||||
|
|
||||||
|
target_doc.run_method("set_missing_values")
|
||||||
|
target_doc.run_method("set_other_charges")
|
||||||
|
target_doc.run_method("calculate_taxes_and_totals")
|
||||||
|
|
||||||
return target_doc
|
return target_doc
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,67 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt, nowdate
|
||||||
|
|
||||||
from erpnext.accounts.party import get_due_date
|
from erpnext.accounts.party import get_due_date
|
||||||
from erpnext.exceptions import PartyDisabled, PartyFrozen
|
from erpnext.exceptions import PartyDisabled, PartyFrozen
|
||||||
from erpnext.selling.doctype.customer.customer import (
|
from erpnext.selling.doctype.customer.customer import (
|
||||||
get_credit_limit,
|
get_credit_limit,
|
||||||
get_customer_outstanding,
|
get_customer_outstanding,
|
||||||
|
make_quotation,
|
||||||
parse_full_name,
|
parse_full_name,
|
||||||
)
|
)
|
||||||
from erpnext.tests.utils import ERPNextTestSuite
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestCustomer(ERPNextTestSuite):
|
class TestCustomer(ERPNextTestSuite):
|
||||||
|
def test_quotation_from_customer_uses_actual_exchange_rate(self):
|
||||||
|
company = "_Test Company"
|
||||||
|
company_currency = frappe.get_cached_value("Company", company, "default_currency")
|
||||||
|
foreign_currency = "USD" if company_currency != "USD" else "EUR"
|
||||||
|
|
||||||
|
frappe.defaults.set_user_default("company", company)
|
||||||
|
self.addCleanup(frappe.defaults.clear_user_default, "company")
|
||||||
|
|
||||||
|
# Seed a deterministic rate so the test does not depend on the live exchange-rate API.
|
||||||
|
rate = 83.0
|
||||||
|
exchange_filters = {
|
||||||
|
"date": nowdate(),
|
||||||
|
"from_currency": foreign_currency,
|
||||||
|
"to_currency": company_currency,
|
||||||
|
}
|
||||||
|
existing = frappe.db.exists("Currency Exchange", exchange_filters)
|
||||||
|
if existing:
|
||||||
|
frappe.db.set_value("Currency Exchange", existing, "exchange_rate", rate)
|
||||||
|
else:
|
||||||
|
exchange = frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Currency Exchange",
|
||||||
|
**exchange_filters,
|
||||||
|
"exchange_rate": rate,
|
||||||
|
"for_selling": 1,
|
||||||
|
"for_buying": 1,
|
||||||
|
}
|
||||||
|
).insert()
|
||||||
|
self.addCleanup(frappe.delete_doc, "Currency Exchange", exchange.name, force=1)
|
||||||
|
|
||||||
|
customer = frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Customer",
|
||||||
|
"customer_name": "_Test Customer FX Quotation",
|
||||||
|
"customer_type": "Company",
|
||||||
|
"default_currency": foreign_currency,
|
||||||
|
}
|
||||||
|
).insert()
|
||||||
|
self.addCleanup(frappe.delete_doc, "Customer", customer.name, force=1)
|
||||||
|
|
||||||
|
quotation = make_quotation(customer.name)
|
||||||
|
|
||||||
|
self.assertEqual(quotation.currency, foreign_currency)
|
||||||
|
self.assertNotEqual(flt(quotation.conversion_rate), 1.0)
|
||||||
|
self.assertNotEqual(flt(quotation.conversion_rate), 0.0)
|
||||||
|
self.assertEqual(flt(quotation.conversion_rate), rate)
|
||||||
|
|
||||||
def test_get_customer_group_details(self):
|
def test_get_customer_group_details(self):
|
||||||
doc = frappe.new_doc("Customer Group")
|
doc = frappe.new_doc("Customer Group")
|
||||||
doc.customer_group_name = "_Testing Customer Group"
|
doc.customer_group_name = "_Testing Customer Group"
|
||||||
|
|||||||
Reference in New Issue
Block a user