diff --git a/frappe/contacts/doctype/contact/test_contact.py b/frappe/contacts/doctype/contact/test_contact.py index e91e132258..18f0d78732 100644 --- a/frappe/contacts/doctype/contact/test_contact.py +++ b/frappe/contacts/doctype/contact/test_contact.py @@ -2,6 +2,7 @@ # License: MIT. See LICENSE import frappe from frappe.contacts.doctype.contact.contact import get_full_name +from frappe.email import get_contact_list from frappe.tests.utils import FrappeTestCase test_dependencies = ["Contact", "Salutation"] @@ -44,6 +45,17 @@ class TestContact(FrappeTestCase): "John Jane Doe", ) + def test_get_contact_list(self): + # First time from database + results = get_contact_list("_Test Supplier") + self.assertEqual(results[0].label, "test_contact@example.com") + self.assertEqual(results[0].description, "_Test Contact For _Test Supplier") + + # Second time from cache + results = get_contact_list("_Test Supplier") + self.assertEqual(results[0].label, "test_contact@example.com") + self.assertEqual(results[0].description, "_Test Contact For _Test Supplier") + def create_contact(name, salutation, emails=None, phones=None, save=True): doc = frappe.get_doc( diff --git a/frappe/email/__init__.py b/frappe/email/__init__.py index 5c4d6f4c72..463f54d7e0 100644 --- a/frappe/email/__init__.py +++ b/frappe/email/__init__.py @@ -2,7 +2,6 @@ # License: MIT. See LICENSE import frappe -from frappe.desk.reportview import build_match_conditions def sendmail_to_system_managers(subject, content): @@ -12,31 +11,38 @@ def sendmail_to_system_managers(subject, content): @frappe.whitelist() def get_contact_list(txt, page_length=20) -> list[dict]: """Return email ids for a multiselect field.""" + from frappe.contacts.doctype.contact.contact import get_full_name if cached_contacts := get_cached_contacts(txt): return cached_contacts[:page_length] - reportview_conditions = build_match_conditions("Contact") - match_conditions = f"and {reportview_conditions}" if reportview_conditions else "" + fields = ["name", "first_name", "middle_name", "last_name", "company_name"] + contacts = frappe.get_list( + "Contact", + fields=fields + ["`tabContact Email`.email_id"], + filters=[ + ["Contact Email", "email_id", "is", "set"], + ], + or_filters=[[field, "like", f"%{txt}%"] for field in fields] + + [["Contact Email", "email_id", "like", f"%{txt}%"]], + limit_page_length=page_length, + ) # The multiselect field will store the `label` as the selected value. # The `value` is just used as a unique key to distinguish between the options. # https://github.com/frappe/frappe/blob/6c6a89bcdd9454060a1333e23b855d0505c9ebc2/frappe/public/js/frappe/form/controls/autocomplete.js#L29-L35 - out = frappe.db.sql( - f"""select name as value, email_id as label, - concat(first_name, ifnull(concat(' ',last_name), '' )) as description - from tabContact - where (name like %(txt)s or email_id like %(txt)s) and email_id != '' - {match_conditions} - limit %(page_length)s""", - {"txt": f"%{txt}%", "page_length": page_length}, - as_dict=True, - ) - out = list(filter(None, out)) + result = [ + frappe._dict( + value=d.name, + label=d.email_id, + description=get_full_name(d.first_name, d.middle_name, d.last_name, d.company_name), + ) + for d in contacts + ] - update_contact_cache(out) + update_contact_cache(result) - return out + return result def get_system_managers():