Merge pull request #39412 from frappe/mergify/bp/version-15-hotfix/pr-39402
fix: project query controller logic (backport #39402)
This commit is contained in:
		
						commit
						93a861fac5
					
				| @ -6,10 +6,12 @@ import json | ||||
| from collections import OrderedDict, defaultdict | ||||
| 
 | ||||
| import frappe | ||||
| from frappe import scrub | ||||
| from frappe import qb, scrub | ||||
| 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 pypika import Order | ||||
| 
 | ||||
| import erpnext | ||||
| from erpnext.stock.get_item_details import _get_item_tax_template | ||||
| @ -339,37 +341,46 @@ def bom(doctype, txt, searchfield, start, page_len, filters): | ||||
| @frappe.whitelist() | ||||
| @frappe.validate_and_sanitize_search_inputs | ||||
| def get_project_name(doctype, txt, searchfield, start, page_len, filters): | ||||
| 	doctype = "Project" | ||||
| 	cond = "" | ||||
| 	proj = qb.DocType("Project") | ||||
| 	qb_filter_and_conditions = [] | ||||
| 	qb_filter_or_conditions = [] | ||||
| 	ifelse = CustomFunction("IF", ["condition", "then", "else"]) | ||||
| 
 | ||||
| 	if filters and filters.get("customer"): | ||||
| 		cond = """(`tabProject`.customer = %s or | ||||
| 			ifnull(`tabProject`.customer,"")="") and""" % ( | ||||
| 			frappe.db.escape(filters.get("customer")) | ||||
| 		) | ||||
| 		qb_filter_and_conditions.append(proj.customer == filters.get("customer")) | ||||
| 
 | ||||
| 	qb_filter_and_conditions.append(proj.status.notin(["Completed", "Cancelled"])) | ||||
| 
 | ||||
| 	q = qb.from_(proj) | ||||
| 
 | ||||
| 	fields = get_fields(doctype, ["name", "project_name"]) | ||||
| 	searchfields = frappe.get_meta(doctype).get_search_fields() | ||||
| 	searchfields = " or ".join(["`tabProject`." + field + " like %(txt)s" for field in searchfields]) | ||||
| 	for x in fields: | ||||
| 		q = q.select(proj[x]) | ||||
| 
 | ||||
| 	return frappe.db.sql( | ||||
| 		"""select {fields} from `tabProject` | ||||
| 		where | ||||
| 			`tabProject`.status not in ('Completed', 'Cancelled') | ||||
| 			and {cond} {scond} {match_cond} | ||||
| 		order by | ||||
| 			(case when locate(%(_txt)s, `tabProject`.name) > 0 then locate(%(_txt)s, `tabProject`.name) else 99999 end), | ||||
| 			`tabProject`.idx desc, | ||||
| 			`tabProject`.name asc | ||||
| 		limit {page_len} offset {start}""".format( | ||||
| 			fields=", ".join(["`tabProject`.{0}".format(f) for f in fields]), | ||||
| 			cond=cond, | ||||
| 			scond=searchfields, | ||||
| 			match_cond=get_match_cond(doctype), | ||||
| 			start=start, | ||||
| 			page_len=page_len, | ||||
| 		), | ||||
| 		{"txt": "%{0}%".format(txt), "_txt": txt.replace("%", "")}, | ||||
| 	) | ||||
| 	# don't consider 'customer' and 'status' fields for pattern search, as they must be exactly matched | ||||
| 	searchfields = [ | ||||
| 		x for x in frappe.get_meta(doctype).get_search_fields() if x not in ["customer", "status"] | ||||
| 	] | ||||
| 
 | ||||
| 	# pattern search | ||||
| 	if txt: | ||||
| 		for x in searchfields: | ||||
| 			qb_filter_or_conditions.append(proj[x].like(f"%{txt}%")) | ||||
| 
 | ||||
| 	q = q.where(Criterion.all(qb_filter_and_conditions)).where(Criterion.any(qb_filter_or_conditions)) | ||||
| 
 | ||||
| 	# ordering | ||||
| 	if txt: | ||||
| 		# project_name containing search string 'txt' will be given higher precedence | ||||
| 		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) | ||||
| 
 | ||||
| 	if page_len: | ||||
| 		q = q.limit(page_len) | ||||
| 
 | ||||
| 	if start: | ||||
| 		q = q.offset(start) | ||||
| 	return q.run() | ||||
| 
 | ||||
| 
 | ||||
| @frappe.whitelist() | ||||
|  | ||||
| @ -68,7 +68,7 @@ class TestQueries(unittest.TestCase): | ||||
| 		self.assertGreaterEqual(len(query(txt="_Test Item Home Desktop Manufactured")), 1) | ||||
| 
 | ||||
| 	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) | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user