mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-15 15:45:01 +00:00
fix: use shipping_address_name for address validation in sales invoice (#46473)
* fix: validate address and contact related to party
* fix: solve unboundlocal error
* refactor: improve variable scope
* refactor: translatable strings
* fix: use shipping_address_name for address validation in sales invoice
* test: add new unit test for address and contact validation
* chore: to avoid keyerror
---------
Co-authored-by: ruthra kumar <ruthra@erpnext.com>
(cherry picked from commit 0bdb81db53)
This commit is contained in:
@@ -271,6 +271,7 @@ class AccountsController(TransactionBase):
|
||||
self.set_total_in_words()
|
||||
self.set_default_letter_head()
|
||||
self.validate_company_in_accounting_dimension()
|
||||
self.validate_party_address_and_contact()
|
||||
|
||||
def set_default_letter_head(self):
|
||||
if hasattr(self, "letter_head") and not self.letter_head:
|
||||
@@ -441,6 +442,45 @@ class AccountsController(TransactionBase):
|
||||
)
|
||||
)
|
||||
|
||||
def validate_party_address_and_contact(self):
|
||||
party, party_type = None, None
|
||||
if self.get("customer"):
|
||||
party, party_type = self.customer, "Customer"
|
||||
billing_address, shipping_address = (
|
||||
self.get("customer_address"),
|
||||
self.get("shipping_address_name"),
|
||||
)
|
||||
self.validate_party_address(party, party_type, billing_address, shipping_address)
|
||||
elif self.get("supplier"):
|
||||
party, party_type = self.supplier, "Supplier"
|
||||
billing_address = self.get("supplier_address")
|
||||
self.validate_party_address(party, party_type, billing_address)
|
||||
|
||||
if party and party_type:
|
||||
self.validate_party_contact(party, party_type)
|
||||
|
||||
def validate_party_address(self, party, party_type, billing_address, shipping_address=None):
|
||||
if billing_address or shipping_address:
|
||||
party_address = frappe.get_list(
|
||||
"Dynamic Link",
|
||||
{"link_doctype": party_type, "link_name": party, "parenttype": "Address"},
|
||||
pluck="parent",
|
||||
)
|
||||
if billing_address and billing_address not in party_address:
|
||||
frappe.throw(_("Billing Address does not belong to the {0}").format(party))
|
||||
elif shipping_address and shipping_address not in party_address:
|
||||
frappe.throw(_("Shipping Address does not belong to the {0}").format(party))
|
||||
|
||||
def validate_party_contact(self, party, party_type):
|
||||
if self.get("contact_person"):
|
||||
contact = frappe.get_list(
|
||||
"Dynamic Link",
|
||||
{"link_doctype": party_type, "link_name": party, "parenttype": "Contact"},
|
||||
pluck="parent",
|
||||
)
|
||||
if self.contact_person and self.contact_person not in contact:
|
||||
frappe.throw(_("Contact Person does not belong to the {0}").format(party))
|
||||
|
||||
def validate_return_against_account(self):
|
||||
if self.doctype in ["Sales Invoice", "Purchase Invoice"] and self.is_return and self.return_against:
|
||||
cr_dr_account_field = "debit_to" if self.doctype == "Sales Invoice" else "credit_to"
|
||||
|
||||
@@ -2175,3 +2175,59 @@ class TestAccountsController(FrappeTestCase):
|
||||
si_1 = create_sales_invoice(do_not_submit=True)
|
||||
si_1.items[0].project = project.name
|
||||
self.assertRaises(frappe.ValidationError, si_1.save)
|
||||
|
||||
def test_party_billing_and_shipping_address(self):
|
||||
from erpnext.crm.doctype.prospect.test_prospect import make_address
|
||||
|
||||
customer_billing = make_address(address_title="Customer")
|
||||
customer_billing.append("links", {"link_doctype": "Customer", "link_name": "_Test Customer"})
|
||||
customer_billing.save()
|
||||
supplier_billing = make_address(address_title="Supplier", address_line1="2", city="Ahmedabad")
|
||||
supplier_billing.append("links", {"link_doctype": "Supplier", "link_name": "_Test Supplier"})
|
||||
supplier_billing.save()
|
||||
|
||||
customer_shipping = make_address(
|
||||
address_title="Customer", address_type="Shipping", address_line1="10"
|
||||
)
|
||||
customer_shipping.append("links", {"link_doctype": "Customer", "link_name": "_Test Customer"})
|
||||
customer_shipping.save()
|
||||
supplier_shipping = make_address(
|
||||
address_title="Supplier", address_type="Shipping", address_line1="20", city="Ahmedabad"
|
||||
)
|
||||
supplier_shipping.append("links", {"link_doctype": "Supplier", "link_name": "_Test Supplier"})
|
||||
supplier_shipping.save()
|
||||
|
||||
si = create_sales_invoice(do_not_save=True)
|
||||
si.customer_address = supplier_billing.name
|
||||
self.assertRaises(frappe.ValidationError, si.save)
|
||||
si.customer_address = customer_billing.name
|
||||
si.save()
|
||||
|
||||
si.shipping_address_name = supplier_shipping.name
|
||||
self.assertRaises(frappe.ValidationError, si.save)
|
||||
si.shipping_address_name = customer_shipping.name
|
||||
si.reload()
|
||||
si.save()
|
||||
|
||||
pi = make_purchase_invoice(do_not_save=True)
|
||||
pi.supplier_address = customer_shipping.name
|
||||
self.assertRaises(frappe.ValidationError, pi.save)
|
||||
pi.supplier_address = supplier_shipping.name
|
||||
pi.save()
|
||||
|
||||
def test_party_contact(self):
|
||||
from frappe.contacts.doctype.contact.test_contact import create_contact
|
||||
|
||||
customer_contact = create_contact(name="Customer", salutation="Mr", save=False)
|
||||
customer_contact.append("links", {"link_doctype": "Customer", "link_name": "_Test Customer"})
|
||||
customer_contact.save()
|
||||
|
||||
supplier_contact = create_contact(name="Supplier", salutation="Mr", save=False)
|
||||
supplier_contact.append("links", {"link_doctype": "Supplier", "link_name": "_Test Supplier"})
|
||||
supplier_contact.save()
|
||||
|
||||
si = create_sales_invoice(do_not_save=True)
|
||||
si.contact_person = supplier_contact.name
|
||||
self.assertRaises(frappe.ValidationError, si.save)
|
||||
si.contact_person = customer_contact.name
|
||||
si.save()
|
||||
|
||||
Reference in New Issue
Block a user