diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.py b/erpnext/accounts/doctype/pos_profile/pos_profile.py index e67c79c6194..1a28f5fd187 100644 --- a/erpnext/accounts/doctype/pos_profile/pos_profile.py +++ b/erpnext/accounts/doctype/pos_profile/pos_profile.py @@ -4,6 +4,7 @@ import frappe from frappe import _, msgprint, scrub, unscrub +from frappe.core.doctype.user_permission.user_permission import get_permitted_documents from frappe.model.document import Document from frappe.utils import get_link_to_form, now @@ -206,17 +207,41 @@ class POSProfile(Document): def get_item_groups(pos_profile): item_groups = [] pos_profile = frappe.get_cached_doc("POS Profile", pos_profile) + permitted_item_groups = get_permitted_nodes("Item Group") if pos_profile.get("item_groups"): # Get items based on the item groups defined in the POS profile for data in pos_profile.get("item_groups"): item_groups.extend( - ["%s" % frappe.db.escape(d.name) for d in get_child_nodes("Item Group", data.item_group)] + [ + "%s" % frappe.db.escape(d.name) + for d in get_child_nodes("Item Group", data.item_group) + if not permitted_item_groups or d.name in permitted_item_groups + ] ) + if not item_groups and permitted_item_groups: + item_groups = ["%s" % frappe.db.escape(d) for d in permitted_item_groups] + return list(set(item_groups)) +def get_permitted_nodes(group_type): + nodes = [] + permitted_nodes = get_permitted_documents(group_type) + + if not permitted_nodes: + return nodes + + for node in permitted_nodes: + if frappe.db.get_value(group_type, node, "is_group"): + nodes.extend([d.name for d in get_child_nodes(group_type, node)]) + else: + nodes.append(node) + + return nodes + + def get_child_nodes(group_type, root): lft, rgt = frappe.db.get_value(group_type, root, ["lft", "rgt"]) return frappe.db.sql( diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py index 7f758f4c8db..9be5a656a8e 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.py +++ b/erpnext/selling/page/point_of_sale/point_of_sale.py @@ -115,6 +115,14 @@ def filter_result_items(result, pos_profile): result["items"] = [item for item in result.get("items") if item.get("item_group") in pos_item_groups] +@frappe.whitelist() +def get_parent_item_group(): + # Using get_all to ignore user permission + item_group = frappe.get_all("Item Group", {"lft": 1, "is_group": 1}, pluck="name") + if item_group: + return item_group[0] + + @frappe.whitelist() def get_items(start, page_length, price_list, item_group, pos_profile, search_term=""): warehouse, hide_unavailable_items = frappe.db.get_value( diff --git a/erpnext/selling/page/point_of_sale/pos_item_selector.js b/erpnext/selling/page/point_of_sale/pos_item_selector.js index 909d1bb9c2d..6ae0d675140 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_selector.js +++ b/erpnext/selling/page/point_of_sale/pos_item_selector.js @@ -38,8 +38,13 @@ erpnext.PointOfSale.ItemSelector = class { async load_items_data() { if (!this.item_group) { - const res = await frappe.db.get_value("Item Group", { lft: 1, is_group: 1 }, "name"); - this.parent_item_group = res.message.name; + frappe.call({ + method: "erpnext.selling.page.point_of_sale.point_of_sale.get_parent_item_group", + async: false, + callback: (r) => { + if (r.message) this.parent_item_group = r.message; + }, + }); } if (!this.price_list) { const res = await frappe.db.get_value("POS Profile", this.pos_profile, "selling_price_list");