@@ -271,6 +271,7 @@ def validate(self):
271271 self .set_total_in_words ()
272272 self .set_default_letter_head ()
273273 self .validate_company_in_accounting_dimension ()
274+ self .validate_party_address_and_contact ()
274275
275276 def set_default_letter_head (self ):
276277 if hasattr (self , "letter_head" ) and not self .letter_head :
@@ -441,6 +442,45 @@ def validate_company(self, dimension_list, child=None):
441442 )
442443 )
443444
445+ def validate_party_address_and_contact (self ):
446+ party , party_type = None , None
447+ if self .get ("customer" ):
448+ party , party_type = self .customer , "Customer"
449+ billing_address , shipping_address = (
450+ self .get ("customer_address" ),
451+ self .get ("shipping_address_name" ),
452+ )
453+ self .validate_party_address (party , party_type , billing_address , shipping_address )
454+ elif self .get ("supplier" ):
455+ party , party_type = self .supplier , "Supplier"
456+ billing_address = self .get ("supplier_address" )
457+ self .validate_party_address (party , party_type , billing_address )
458+
459+ if party and party_type :
460+ self .validate_party_contact (party , party_type )
461+
462+ def validate_party_address (self , party , party_type , billing_address , shipping_address = None ):
463+ if billing_address or shipping_address :
464+ party_address = frappe .get_all (
465+ "Dynamic Link" ,
466+ {"link_doctype" : party_type , "link_name" : party , "parenttype" : "Address" },
467+ pluck = "parent" ,
468+ )
469+ if billing_address and billing_address not in party_address :
470+ frappe .throw (_ ("Billing Address does not belong to the {0}" ).format (party ))
471+ elif shipping_address and shipping_address not in party_address :
472+ frappe .throw (_ ("Shipping Address does not belong to the {0}" ).format (party ))
473+
474+ def validate_party_contact (self , party , party_type ):
475+ if self .get ("contact_person" ):
476+ contact = frappe .get_all (
477+ "Dynamic Link" ,
478+ {"link_doctype" : party_type , "link_name" : party , "parenttype" : "Contact" },
479+ pluck = "parent" ,
480+ )
481+ if self .contact_person and self .contact_person not in contact :
482+ frappe .throw (_ ("Contact Person does not belong to the {0}" ).format (party ))
483+
444484 def validate_return_against_account (self ):
445485 if self .doctype in ["Sales Invoice" , "Purchase Invoice" ] and self .is_return and self .return_against :
446486 cr_dr_account_field = "debit_to" if self .doctype == "Sales Invoice" else "credit_to"
@@ -3666,6 +3706,9 @@ def validate_fg_item_for_subcontracting(new_data, is_new):
36663706 if d .get ("schedule_date" ) and parent_doctype == "Purchase Order" :
36673707 child_item .schedule_date = d .get ("schedule_date" )
36683708
3709+ if d .get ("bom_no" ) and parent_doctype == "Sales Order" :
3710+ child_item .bom_no = d .get ("bom_no" )
3711+
36693712 if flt (child_item .price_list_rate ):
36703713 if flt (child_item .rate ) > flt (child_item .price_list_rate ):
36713714 # if rate is greater than price_list_rate, set margin
0 commit comments