Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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})"
Expand Down
21 changes: 21 additions & 0 deletions helpdesk/helpdesk/doctype/hd_ticket/test_hd_ticket.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down