From 18fdd17e94f92a06154d4ad07f8bb1cd1c2ff08d Mon Sep 17 00:00:00 2001 From: Sugesh G <73237300+Sugesh393@users.noreply.github.com> Date: Tue, 11 Mar 2025 14:28:23 +0530 Subject: [PATCH] Merge pull request #45958 from aerele/validate-party-address fix: validate address and contact related to party --- erpnext/controllers/accounts_controller.py | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 9956d36617b..a7e7e14608e 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -274,6 +274,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: @@ -445,6 +446,42 @@ 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") + 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 {party}").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"