Merge pull request #39402 from ruthra-kumar/fix_project_query

fix: project query controller logic
This commit is contained in:
ruthra kumar 2024-01-16 16:24:02 +05:30 committed by GitHub
commit ca9413bc64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 30 deletions

View File

@ -6,10 +6,12 @@ import json
from collections import OrderedDict, defaultdict from collections import OrderedDict, defaultdict
import frappe import frappe
from frappe import scrub from frappe import qb, scrub
from frappe.desk.reportview import get_filters_cond, get_match_cond from frappe.desk.reportview import get_filters_cond, get_match_cond
from frappe.query_builder.functions import Concat, Sum from frappe.query_builder import Criterion, CustomFunction
from frappe.query_builder.functions import Concat, Locate, Sum
from frappe.utils import nowdate, today, unique from frappe.utils import nowdate, today, unique
from pypika import Order
import erpnext import erpnext
from erpnext.stock.get_item_details import _get_item_tax_template from erpnext.stock.get_item_details import _get_item_tax_template
@ -344,37 +346,46 @@ def bom(doctype, txt, searchfield, start, page_len, filters):
@frappe.whitelist() @frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs @frappe.validate_and_sanitize_search_inputs
def get_project_name(doctype, txt, searchfield, start, page_len, filters): def get_project_name(doctype, txt, searchfield, start, page_len, filters):
doctype = "Project" proj = qb.DocType("Project")
cond = "" qb_filter_and_conditions = []
qb_filter_or_conditions = []
ifelse = CustomFunction("IF", ["condition", "then", "else"])
if filters and filters.get("customer"): if filters and filters.get("customer"):
cond = """(`tabProject`.customer = %s or qb_filter_and_conditions.append(proj.customer == filters.get("customer"))
ifnull(`tabProject`.customer,"")="") and""" % (
frappe.db.escape(filters.get("customer")) qb_filter_and_conditions.append(proj.status.notin(["Completed", "Cancelled"]))
)
q = qb.from_(proj)
fields = get_fields(doctype, ["name", "project_name"]) fields = get_fields(doctype, ["name", "project_name"])
searchfields = frappe.get_meta(doctype).get_search_fields() for x in fields:
searchfields = " or ".join(["`tabProject`." + field + " like %(txt)s" for field in searchfields]) q = q.select(proj[x])
return frappe.db.sql( # don't consider 'customer' and 'status' fields for pattern search, as they must be exactly matched
"""select {fields} from `tabProject` searchfields = [
where x for x in frappe.get_meta(doctype).get_search_fields() if x not in ["customer", "status"]
`tabProject`.status not in ('Completed', 'Cancelled') ]
and {cond} {scond} {match_cond}
order by # pattern search
(case when locate(%(_txt)s, `tabProject`.name) > 0 then locate(%(_txt)s, `tabProject`.name) else 99999 end), if txt:
`tabProject`.idx desc, for x in searchfields:
`tabProject`.name asc qb_filter_or_conditions.append(proj[x].like(f"%{txt}%"))
limit {page_len} offset {start}""".format(
fields=", ".join(["`tabProject`.{0}".format(f) for f in fields]), q = q.where(Criterion.all(qb_filter_and_conditions)).where(Criterion.any(qb_filter_or_conditions))
cond=cond,
scond=searchfields, # ordering
match_cond=get_match_cond(doctype), if txt:
start=start, # project_name containing search string 'txt' will be given higher precedence
page_len=page_len, q = q.orderby(ifelse(Locate(txt, proj.project_name) > 0, Locate(txt, proj.project_name), 99999))
), q = q.orderby(proj.idx, order=Order.desc).orderby(proj.name)
{"txt": "%{0}%".format(txt), "_txt": txt.replace("%", "")},
) if page_len:
q = q.limit(page_len)
if start:
q = q.offset(start)
return q.run()
@frappe.whitelist() @frappe.whitelist()

View File

@ -68,7 +68,7 @@ class TestQueries(unittest.TestCase):
self.assertGreaterEqual(len(query(txt="_Test Item Home Desktop Manufactured")), 1) self.assertGreaterEqual(len(query(txt="_Test Item Home Desktop Manufactured")), 1)
def test_project_query(self): def test_project_query(self):
query = add_default_params(queries.get_project_name, "BOM") query = add_default_params(queries.get_project_name, "Project")
self.assertGreaterEqual(len(query(txt="_Test Project")), 1) self.assertGreaterEqual(len(query(txt="_Test Project")), 1)