refactor: filter_dynamic_link_doctypes API

* Added typing, better variable naming
* Remove unnecessary re-iterations
* Optimize queries and membership processing
This commit is contained in:
Gavin D'souza 2022-06-03 15:41:55 +05:30 committed by gavin
parent 6dfbf7b19e
commit 963648667d

View file

@ -3,6 +3,7 @@
import functools
import re
from typing import Dict, List
import frappe
from frappe import _
@ -169,29 +170,34 @@ def delete_contact_and_address(doctype, docname):
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def filter_dynamic_link_doctypes(doctype, txt, searchfield, start, page_len, filters):
if not txt:
txt = ""
def filter_dynamic_link_doctypes(txt: str, filters: Dict) -> List[List[str]]:
from frappe.permissions import get_doctypes_with_read
doctypes = frappe.db.get_all(
"DocField", filters=filters, fields=["parent"], distinct=True, as_list=True
txt = txt or ""
filters = filters or {}
TXT_PATTERN = re.compile(f"{txt}.*")
_doctypes_from_df = frappe.get_all(
"DocField",
filters=filters,
pluck="parent",
distinct=True,
order_by=None,
)
doctypes_from_df = {d for d in _doctypes_from_df if TXT_PATTERN.search(_(d), re.IGNORECASE)}
doctypes = tuple(d for d in doctypes if re.search(txt + ".*", _(d[0]), re.IGNORECASE))
filters.update({"dt": ("not in", doctypes_from_df)})
_doctypes_from_cdf = frappe.get_all(
"Custom Field", filters=filters, pluck="dt", distinct=True, order_by=None
)
doctypes_from_cdf = {d for d in _doctypes_from_cdf if TXT_PATTERN.search(_(d), re.IGNORECASE)}
filters.update({"dt": ("not in", [d[0] for d in doctypes])})
all_doctypes = doctypes_from_df.union(doctypes_from_cdf)
allowed_doctypes = set(get_doctypes_with_read())
_doctypes = frappe.db.get_all("Custom Field", filters=filters, fields=["dt"], as_list=True)
valid_doctypes = sorted(all_doctypes.intersection(allowed_doctypes))
_doctypes = tuple([d for d in _doctypes if re.search(txt + ".*", _(d[0]), re.IGNORECASE)])
all_doctypes = [d[0] for d in doctypes + _doctypes]
allowed_doctypes = frappe.permissions.get_doctypes_with_read()
valid_doctypes = sorted(set(all_doctypes).intersection(set(allowed_doctypes)))
valid_doctypes = [[doctype] for doctype in valid_doctypes]
return valid_doctypes
return [[doctype] for doctype in valid_doctypes]
def set_link_title(doc):