V8: How to fetch primary contact & address?

Struggling to fetch primary contact link & billing address link for customer/supplier after v8 upgrade. As the structure has been changed and dynamic link table has been introduced.

Earlier used below code to fetch it:

frappe.ui.form.on('Payment Entry', 'onload', function(frm){
    if(frm.doc.__islocal){
		if(frm.doc.party_type == "Customer") {	
			frappe.call({
				'method': 'frappe.client.get_value',
				'args': {
					'doctype': 'Contact',
					'fieldname': 'name',
					  'filters': {
						'customer': frm.doc.party,
						'is_primary_contact': 1
					  }
					},
				   callback: function(r){
						frm.set_value('contact_person', r.message.name);
				   }
			});
		}
	}
});

get_default_contact & get_default_address functions are not white listed in frappe, so unable to use them directly. Tried using them in custom app code:

@frappe.whitelist()
def set_contact_details(out, party, party_type):
	out.contact_person = get_default_contact(party_type, party)

	if not out.contact_person:
		out.update({
			"contact_person": None,
			"contact_display": None,
			"contact_email": None,
			"contact_mobile": None,
			"contact_phone": None,
			"contact_designation": None,
			"contact_department": None
		})
	else:
		out.update(get_contact_details(out.contact_person))

& calling it though custom script in Payment entry, but getting error: 404 (NOT FOUND) @ frappe.call({

frappe.ui.form.on("Payment Entry", "party", function(frm){
frappe.call({
	'method': 'customapp.customapp.api.set_contact_details',
	'args': {
		'out' : frm.doc,
		'party': frm.doc.party,
		'party_type': frm.doc.party_type,
		},
	callback: function(r){
		if(r.message) {
				frm.set_value(r.message);
				frm.refresh(); 
			} 
		}
	});
});

What is the use case?

I am using payment entry to send automated mails with payment receipt/Payment advise. For that I need to get customer/supplier contact details (At least email id).

Address was fetched to take print out with address to post cheque in chase of payment.

Earlier didn’t had to select contact/address, it will be updated as soon as party was selected. It has become manual selection now.

I am able to filter list of contact & address using address_query & contact_query, but not sure how to set first value of filtered list as default.

You can refer post for mail alert defined.

You can directly fetch it in the Jinja template no?

Fetching it has been a challenge after dynamic row has been introduce. Logic used in below function to fetch contact from name of customer, finding it difficult to replicate even in custom script.

def get_default_contact(doctype, name):
	'''Returns default contact for the given doctype, name'''
	out = frappe.db.sql('''select parent,
			(select is_primary_contact from tabContact c where c.name = dl.parent)
				as is_primary_contact
		from
			`tabDynamic Link` dl
		where
			dl.link_doctype=%s and
			dl.link_name=%s and
			dl.parenttype = "Contact"''', (doctype, name))
	if out:
		return sorted(out, lambda x,y: cmp(y[1], x[1]))[0][0]
	else:
		return None

Unless you contribute your feature, we have idea what the downstream problems are! If you are a building something that is helpful to a lot of users, contribute it, so it can be managed during upgrades

2 Likes

I would love to contribute, but unfortunately still a novice coder.

If we can whitelist get_default_contact & get_default_address in frappe, they can be useful to many to fetch default address & contact from customer/supplier at any custom field.

Unless you contribute your feature, we have idea what the downstream problems are! If you are a building something that is helpful to a lot of users, contribute it, so it can be managed during upgrades

1 Like

Have you tried
erpnext.accounts.party.get_party_details?

Where do you put this? I’m in same situation as I want to fetch the party bill-to address into the payment entry screen in order to have it on print format for check printing.

You need to write custom script to fetch contact, get_party_details is function in ERPNEXT app which can be used.

Checkout Frappe Ajax Call

{% set links = frappe.get_all(‘Dynamic Link’, filters={‘link_doctype’: ‘Company’, ‘link_name’: doc.company, ‘parenttype’: ‘Address’}, fields=[‘parent’]) %}
{% if links %}
{{frappe.db.get_value(“Address”, links[0].parent, “address_line1”)}}
{% endif %}`

its working

1 Like

I found this thread…I know it’s an older thread, but your solutions seems to work…right? I need this solution to put addresses on printed checks, but I am not sure how/where to insert this code. Any tips for someone new to ERPnext/frappe?

you can add this above code in your Print Format