diff --git a/helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.py b/helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.py index 51010362da..60cf17ce56 100644 --- a/helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.py +++ b/helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.py @@ -1396,14 +1396,13 @@ def permission_query(user: str | None = None): def _customer_query(user: str) -> str: """Non-agents see their own tickets, plus all tickets of customers they manage.""" query = _get_base_visibility(user) - managed_customers = _get_managed_customers(user) - if managed_customers: - query += " OR " + _build_in_clause("customer", managed_customers) + query = _add_managed_customer_visibility(query, user) return query def _agent_query(user: str) -> str | None: query = _get_base_visibility(user) + query = _add_managed_customer_visibility(query, user) if not frappe.db.get_single_value("HD Settings", "restrict_tickets_by_agent_group"): return # Restrictions disabled, return all tickets @@ -1450,6 +1449,13 @@ def _get_managed_customers(user: str) -> list[str]: ] +def _add_managed_customer_visibility(query: str, user: str) -> str: + managed_customers = _get_managed_customers(user) + if managed_customers: + query += " OR " + _build_in_clause("customer", managed_customers) + return query + + def _build_in_clause(field: str, values: list[str]) -> str: _values = ", ".join(frappe.db.escape(v) for v in values) return f"`tabHD Ticket`.{field} in ({_values})" diff --git a/helpdesk/helpdesk/doctype/hd_ticket/test_hd_ticket.py b/helpdesk/helpdesk/doctype/hd_ticket/test_hd_ticket.py index 67a366f979..f98ad79630 100644 --- a/helpdesk/helpdesk/doctype/hd_ticket/test_hd_ticket.py +++ b/helpdesk/helpdesk/doctype/hd_ticket/test_hd_ticket.py @@ -2328,6 +2328,27 @@ def test_permission_check_answers_for_passed_user_not_session(self): self.assertFalse(has_permission(ticket, user=agent)) self.assertNotIn("Team B", permission_query(agent)) + def test_customer_managers_see_their_tickets_in_lists(self): + """Customer-link access must survive both doc checks and list queries.""" + contact = create_contact("Account Manager", agent, user=True, role="Agent") + customer = create_customer("Manager Visibility Customer") + add_contact_in_customer(customer, contact["contact"], is_manager=True) + make_team("Team B", members=[agent2]) + frappe.db.set_single_value("HD Settings", "restrict_tickets_by_agent_group", 1) + self.addCleanup( + frappe.db.set_single_value, + "HD Settings", + "restrict_tickets_by_agent_group", + 0, + ) + + ticket = make_ticket(customer=customer.name, agent_group="Team B") + + frappe.set_user(agent) + self.assertTrue(has_permission(ticket, user=agent)) + self.assertIn(ticket.name, frappe.get_list("HD Ticket", pluck="name")) + self.assertIn(customer.name, permission_query(agent)) + def tearDown(self): frappe.set_user("Administrator") remove_holidays()