feat(Contacts): Multiple Emails in a Contact (#18675)

* feat: render multiple addresses

* feat: move to newer contacts structure

* fix: iterate over valid variable

* fix: use primary label instead of bold letters

* fix: call popup get contact name from number

* fix: make contact structure  call popup compatible

* fix: query

* fix: add city, state and country

* fix: display address

* fix: get address in single line

* fix: review fixes

* fix: translation strings

* fix: fix query for contacts

* fix: remove references of mobile_no
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index e290b23..7e23793 100755
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -227,8 +227,8 @@
 		customers = [frappe._dict({'name': customers})]
 
 	for data in customers:
-		contact = frappe.db.sql(""" select email_id, phone, mobile_no from `tabContact`
-			where is_primary_contact =1 and name in
+		contact = frappe.db.sql(""" select email_id, phone from `tabContact`
+			where is_primary_contact=1 and name in
 			(select parent from `tabDynamic Link` where link_doctype = 'Customer' and link_name = %s
 			and parenttype = 'Contact')""", data.name, as_dict=1)
 		if contact:
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index b5a02d0..0e73012 100755
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -816,7 +816,6 @@
 				contact = me.contacts[data.name];
 				if(reg.test(data.name.toLowerCase())
 					|| reg.test(data.customer_name.toLowerCase())
-					|| (contact && reg.test(contact["mobile_no"]))
 					|| (contact && reg.test(contact["phone"]))
 					|| (data.customer_group && reg.test(data.customer_group.toLowerCase()))){
 						return data;
@@ -834,7 +833,6 @@
 				if(contact && !c['phone']) {
 					c["phone"] = contact["phone"];
 					c["email_id"] = contact["email_id"];
-					c["mobile_no"] = contact["mobile_no"];
 				}
 
 				me.customers_mapper.push({
@@ -844,10 +842,9 @@
 					customer_group: c.customer_group,
 					territory: c.territory,
 					phone: contact ? contact["phone"] : '',
-					mobile_no: contact ? contact["mobile_no"] : '',
 					email_id: contact ? contact["email_id"] : '',
 					searchtext: ['customer_name', 'customer_group', 'name', 'value',
-						'label', 'email_id', 'phone', 'mobile_no']
+						'label', 'email_id', 'phone']
 						.map(key => c[key]).join(' ')
 						.toLowerCase()
 				});
diff --git a/erpnext/communication/doctype/call_log/call_log.py b/erpnext/communication/doctype/call_log/call_log.py
index 2343632..35c31a0 100644
--- a/erpnext/communication/doctype/call_log/call_log.py
+++ b/erpnext/communication/doctype/call_log/call_log.py
@@ -73,6 +73,10 @@
 	# contact_name or lead_name
 	display_name_field = '{}_name'.format(fieldname)
 
+	# Contact now has all the nos saved in child table
+	if doc.doctype == 'Contact':
+		numbers = [d.phone for d in doc.phone_nos]
+
 	for number in numbers:
 		number = strip_number(number)
 		if not number: continue
diff --git a/erpnext/crm/doctype/opportunity/test_opportunity.py b/erpnext/crm/doctype/opportunity/test_opportunity.py
index 1a9f66a..8f61edf 100644
--- a/erpnext/crm/doctype/opportunity/test_opportunity.py
+++ b/erpnext/crm/doctype/opportunity/test_opportunity.py
@@ -45,15 +45,16 @@
 
 		# create new customer and create new contact against 'new.opportunity@example.com'
 		customer = make_customer(opp_doc.party_name).insert(ignore_permissions=True)
-		frappe.get_doc({
+		contact = frappe.get_doc({
 			"doctype": "Contact",
-			"email_id": new_lead_email_id,
 			"first_name": "_Test Opportunity Customer",
 			"links": [{
 				"link_doctype": "Customer",
 				"link_name": customer.name
 			}]
-		}).insert(ignore_permissions=True)
+		})
+		contact.add_email(new_lead_email_id)
+		contact.insert(ignore_permissions=True)
 
 		opp_doc = frappe.get_doc(args).insert(ignore_permissions=True)
 		self.assertTrue(opp_doc.party_name)
diff --git a/erpnext/erpnext_integrations/doctype/exotel_settings/exotel_settings.py b/erpnext/erpnext_integrations/doctype/exotel_settings/exotel_settings.py
index 77de84c..6a846ef 100644
--- a/erpnext/erpnext_integrations/doctype/exotel_settings/exotel_settings.py
+++ b/erpnext/erpnext_integrations/doctype/exotel_settings/exotel_settings.py
@@ -3,7 +3,6 @@
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
-# import frappe
 from frappe.model.document import Document
 import requests
 import frappe
diff --git a/erpnext/hub_node/legacy.py b/erpnext/hub_node/legacy.py
index 95ada76..85eb1b2 100644
--- a/erpnext/hub_node/legacy.py
+++ b/erpnext/hub_node/legacy.py
@@ -68,12 +68,13 @@
 		contact = frappe.get_doc({
 			'doctype': 'Contact',
 			'first_name': supplier.supplier_name,
-			'email_id': supplier.supplier_email,
 			'is_primary_contact': 1,
 			'links': [
 				{'link_doctype': 'Supplier', 'link_name': supplier.supplier_name}
 			]
-		}).insert()
+		})
+		contact.add_email(supplier.supplier_email)
+		contact.insert()
 	else:
 		contact = frappe.get_doc('Contact', contact_name)
 
diff --git a/erpnext/public/js/templates/contact_list.html b/erpnext/public/js/templates/contact_list.html
index 893b4e0..50fbfd9 100644
--- a/erpnext/public/js/templates/contact_list.html
+++ b/erpnext/public/js/templates/contact_list.html
@@ -14,20 +14,33 @@
 				style="margin-top:-3px; margin-right: -5px;">
 				{%= __("Edit") %}</a>
 		</p>
-		{% if (contact_list[i].phone || contact_list[i].mobile_no ||
-			contact_list[i].email_id) { %}
+		{% if (contact_list[i].phones || contact_list[i].email_ids) { %}
 		<p>
-		{% if(contact_list[i].phone) { %}
-			{%= __("Phone") %}: {%= contact_list[i].phone %}<br>
-		{% } %}
-		{% if(contact_list[i].mobile_no) { %}
-			{%= __("Mobile No.") %}: {%= contact_list[i].mobile_no %}<br>
-		{% } %}
-		{% if(contact_list[i].email_id) { %}
-			{%= __("Email Address") %}: {%= contact_list[i].email_id %}
-		{% } %}
+			{% if(contact_list[i].phone) { %}
+				{%= __("Phone") %}: {%= contact_list[i].phone %}<span class="text-muted"> ({%= __("Primary") %})</span><br>
+			{% endif %}
+			{% if(contact_list[i].phone_nos) { %}
+				{% for(var j=0, k=contact_list[i].phone_nos.length; j<k; j++) { %}
+					{%= __("Phone") %}: {%= contact_list[i].phone_nos[j].phone %}<br>
+				{% } %}
+			{% endif %}
+		</p>
+		<p>
+			{% if(contact_list[i].email_id) { %}
+				{%= __("Email") %}: {%= contact_list[i].email_id %}<span class="text-muted"> ({%= __("Primary") %})</span><br>
+			{% endif %}
+			{% if(contact_list[i].email_ids) { %}
+				{% for(var j=0, k=contact_list[i].email_ids.length; j<k; j++) { %}
+					{%= __("Email") %}: {%= contact_list[i].email_ids[j].email_id %}<br>
+				{% } %}
+			{% endif %}
 		</p>
 		{% endif %}
+		<p>
+		{% if (contact_list[i].address) { %}
+			{%= __("Address") %}: {%= contact_list[i].address %}<br>
+		{% endif %}
+		</p>
 	</div>
 {% } %}
 {% if(!contact_list.length) { %}
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index c946c47..d0b4ba0 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -337,14 +337,15 @@
 	contact = frappe.get_doc({
 		'doctype': 'Contact',
 		'first_name': args.get('name'),
-		'mobile_no': args.get('mobile_no'),
-		'email_id': args.get('email_id'),
 		'is_primary_contact': is_primary_contact,
 		'links': [{
 			'link_doctype': args.get('doctype'),
 			'link_name': args.get('name')
 		}]
-	}).insert()
+	})
+	contact.add_email(args.get('email_id'))
+	contact.add_phone(args.get('mobile_no'))
+	contact.insert()
 
 	return contact
 
diff --git a/erpnext/selling/doctype/sms_center/sms_center.py b/erpnext/selling/doctype/sms_center/sms_center.py
index bb6ba1f..289b045 100644
--- a/erpnext/selling/doctype/sms_center/sms_center.py
+++ b/erpnext/selling/doctype/sms_center/sms_center.py
@@ -31,7 +31,7 @@
 					self.sales_partner.replace("'", "\'") or " and ifnull(dl.link_name, '') != ''"
 		if self.send_to in ['All Contact', 'All Customer Contact', 'All Supplier Contact', 'All Sales Partner Contact']:
 			rec = frappe.db.sql("""select CONCAT(ifnull(c.first_name,''), ' ', ifnull(c.last_name,'')),
-				c.mobile_no from `tabContact` c, `tabDynamic Link` dl  where ifnull(c.mobile_no,'')!='' and
+				c.phone from `tabContact` c, `tabDynamic Link` dl  where ifnull(c.phone,'')!='' and
 				c.docstatus != 2 and dl.parent = c.name%s""" % where_clause)
 
 		elif self.send_to == 'All Lead (Open)':