feat: add option to filter email recipients

This commit is contained in:
barredterra 2024-03-20 00:44:22 +01:00
parent cc2c39d583
commit 3730dfa44e
2 changed files with 21 additions and 40 deletions

View file

@ -9,20 +9,22 @@ def sendmail_to_system_managers(subject, content):
@frappe.whitelist()
def get_contact_list(txt, page_length=20) -> list[dict]:
def get_contact_list(txt, page_length=20, extra_filters: str | None = None) -> list[dict]:
"""Return email ids for a multiselect field."""
from frappe.contacts.doctype.contact.contact import get_full_name
if extra_filters:
extra_filters = frappe.parse_json(extra_filters)
if cached_contacts := get_cached_contacts(txt):
return cached_contacts[:page_length]
filters = [
["Contact Email", "email_id", "is", "set"],
]
if extra_filters:
filters.extend(extra_filters)
fields = ["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"],
],
fields=["full_name", "`tabContact Email`.email_id"],
filters=filters,
or_filters=[[field, "like", f"%{txt}%"] for field in fields]
+ [["Contact Email", "email_id", "like", f"%{txt}%"]],
limit_page_length=page_length,
@ -31,19 +33,15 @@ def get_contact_list(txt, page_length=20) -> list[dict]:
# 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
result = [
return [
frappe._dict(
value=d.email_id,
label=d.email_id,
description=get_full_name(d.first_name, d.middle_name, d.last_name, d.company_name),
description=d.full_name,
)
for d in contacts
]
update_contact_cache(result)
return result
def get_system_managers():
return frappe.db.sql_list(
@ -94,28 +92,3 @@ def get_communication_doctype(doctype, txt, searchfield, start, page_len, filter
]
return [[dt] for dt in com_doctypes if txt.lower().replace("%", "") in dt.lower() and dt in can_read]
def get_cached_contacts(txt):
contacts = frappe.cache.hget("contacts", frappe.session.user) or []
if not contacts:
return
if not txt:
return contacts
return [
d
for d in contacts
if (d.value and ((d.value and txt in d.value) or (d.description and txt in d.description)))
]
def update_contact_cache(contacts):
cached_contacts = frappe.cache.hget("contacts", frappe.session.user) or []
uncached_contacts = [d for d in contacts if d not in cached_contacts]
cached_contacts.extend(uncached_contacts)
frappe.cache.hset("contacts", frappe.session.user, cached_contacts)

View file

@ -255,10 +255,18 @@ frappe.views.CommunicationComposer = class {
this.dialog.fields_dict[field].get_data = () => {
const data = this.dialog.fields_dict[field].get_value();
const txt = data.match(/[^,\s*]*$/)[0] || "";
const args = { txt };
if (this.frm.events.get_email_recipient_filters) {
args.extra_filters = this.frm.events.get_email_recipient_filters(
this.frm,
field
);
}
frappe.call({
method: "frappe.email.get_contact_list",
args: { txt },
args: args,
callback: (r) => {
this.dialog.fields_dict[field].set_data(r.message);
},