mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-02 11:49:10 +00:00
Merge pull request #47208 from frappe/mergify/bp/version-15-hotfix/pr-46717
fix: respect field "ignore_user_permissions" property in employee query (backport #46717)
This commit is contained in:
@@ -8,9 +8,10 @@ from collections import OrderedDict, defaultdict
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import qb, 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.permissions import has_permission
|
||||||
from frappe.query_builder import Criterion, CustomFunction
|
from frappe.query_builder import Criterion, CustomFunction
|
||||||
from frappe.query_builder.functions import Concat, Locate, Sum
|
from frappe.query_builder.functions import Concat, Locate, Sum
|
||||||
from frappe.utils import nowdate, today, unique
|
from frappe.utils import cint, nowdate, today, unique
|
||||||
from pypika import Order
|
from pypika import Order
|
||||||
|
|
||||||
import erpnext
|
import erpnext
|
||||||
@@ -20,10 +21,28 @@ from erpnext.stock.get_item_details import _get_item_tax_template
|
|||||||
# searches for active employees
|
# searches for active employees
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@frappe.validate_and_sanitize_search_inputs
|
@frappe.validate_and_sanitize_search_inputs
|
||||||
def employee_query(doctype, txt, searchfield, start, page_len, filters):
|
def employee_query(
|
||||||
|
doctype,
|
||||||
|
txt,
|
||||||
|
searchfield,
|
||||||
|
start,
|
||||||
|
page_len,
|
||||||
|
filters,
|
||||||
|
reference_doctype: str | None = None,
|
||||||
|
ignore_user_permissions: bool = False,
|
||||||
|
):
|
||||||
doctype = "Employee"
|
doctype = "Employee"
|
||||||
conditions = []
|
conditions = []
|
||||||
fields = get_fields(doctype, ["name", "employee_name"])
|
fields = get_fields(doctype, ["name", "employee_name"])
|
||||||
|
ignore_permissions = False
|
||||||
|
|
||||||
|
if reference_doctype and ignore_user_permissions:
|
||||||
|
ignore_permissions = has_ignored_field(reference_doctype, doctype) and has_permission(
|
||||||
|
doctype,
|
||||||
|
ptype="select" if frappe.only_has_select_perm(doctype) else "read",
|
||||||
|
)
|
||||||
|
|
||||||
|
mcond = "" if ignore_permissions else get_match_cond(doctype)
|
||||||
|
|
||||||
return frappe.db.sql(
|
return frappe.db.sql(
|
||||||
"""select {fields} from `tabEmployee`
|
"""select {fields} from `tabEmployee`
|
||||||
@@ -42,13 +61,32 @@ def employee_query(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
"fields": ", ".join(fields),
|
"fields": ", ".join(fields),
|
||||||
"key": searchfield,
|
"key": searchfield,
|
||||||
"fcond": get_filters_cond(doctype, filters, conditions),
|
"fcond": get_filters_cond(doctype, filters, conditions),
|
||||||
"mcond": get_match_cond(doctype),
|
"mcond": mcond,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
{"txt": "%%%s%%" % txt, "_txt": txt.replace("%", ""), "start": start, "page_len": page_len},
|
{"txt": "%%%s%%" % txt, "_txt": txt.replace("%", ""), "start": start, "page_len": page_len},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def has_ignored_field(reference_doctype, doctype):
|
||||||
|
meta = frappe.get_meta(reference_doctype)
|
||||||
|
for field in meta.fields:
|
||||||
|
if not field.ignore_user_permissions:
|
||||||
|
continue
|
||||||
|
if field.fieldtype == "Link" and field.options == doctype:
|
||||||
|
return True
|
||||||
|
elif field.fieldtype == "Dynamic Link":
|
||||||
|
options = meta.get_link_doctype(field.fieldname)
|
||||||
|
if not options:
|
||||||
|
continue
|
||||||
|
if isinstance(options, str):
|
||||||
|
options = options.split("\n")
|
||||||
|
if doctype in options or "DocType" in options:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
# searches for leads which are not converted
|
# searches for leads which are not converted
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@frappe.validate_and_sanitize_search_inputs
|
@frappe.validate_and_sanitize_search_inputs
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import unittest
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe.core.doctype.user_permission.test_user_permission import create_user
|
||||||
|
from frappe.core.doctype.user_permission.user_permission import add_user_permissions
|
||||||
|
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
|
||||||
|
|
||||||
from erpnext.controllers import queries
|
from erpnext.controllers import queries
|
||||||
|
|
||||||
@@ -81,3 +84,54 @@ class TestQueries(unittest.TestCase):
|
|||||||
|
|
||||||
def test_default_uoms(self):
|
def test_default_uoms(self):
|
||||||
self.assertGreaterEqual(frappe.db.count("UOM", {"enabled": 1}), 10)
|
self.assertGreaterEqual(frappe.db.count("UOM", {"enabled": 1}), 10)
|
||||||
|
|
||||||
|
def test_employee_query_with_user_permissions(self):
|
||||||
|
# party field is a dynamic link field in Payment Entry doctype with ignore_user_permissions=0
|
||||||
|
ps = make_property_setter(
|
||||||
|
doctype="Payment Entry",
|
||||||
|
fieldname="party",
|
||||||
|
property="ignore_user_permissions",
|
||||||
|
value=1,
|
||||||
|
property_type="Check",
|
||||||
|
)
|
||||||
|
ps.save()
|
||||||
|
|
||||||
|
user = create_user("test_employee_query@example.com", ("Accounts User", "HR User"))
|
||||||
|
add_user_permissions(
|
||||||
|
{
|
||||||
|
"user": user.name,
|
||||||
|
"doctype": "Employee",
|
||||||
|
"docname": "_T-Employee-00001",
|
||||||
|
"is_default": 1,
|
||||||
|
"apply_to_all_doctypes": 1,
|
||||||
|
"applicable_doctypes": [],
|
||||||
|
"hide_descendants": 0,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
frappe.reload_doc("accounts", "doctype", "payment entry")
|
||||||
|
|
||||||
|
frappe.set_user(user.name)
|
||||||
|
params = {
|
||||||
|
"doctype": "Employee",
|
||||||
|
"txt": "",
|
||||||
|
"searchfield": "name",
|
||||||
|
"start": 0,
|
||||||
|
"page_len": 20,
|
||||||
|
"filters": None,
|
||||||
|
"reference_doctype": "Payment Entry",
|
||||||
|
"ignore_user_permissions": 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
result = queries.employee_query(**params)
|
||||||
|
self.assertGreater(len(result), 1)
|
||||||
|
|
||||||
|
ps.delete(ignore_permissions=1, force=1, delete_permanently=1)
|
||||||
|
frappe.reload_doc("accounts", "doctype", "payment entry")
|
||||||
|
frappe.clear_cache()
|
||||||
|
|
||||||
|
# only one employee should be returned even though ignore_user_permissions is passed as 1
|
||||||
|
result = queries.employee_query(**params)
|
||||||
|
self.assertEqual(len(result), 1)
|
||||||
|
|
||||||
|
frappe.set_user("Administrator")
|
||||||
|
|||||||
Reference in New Issue
Block a user