Restrict indexed department filters to scoped entities

This commit is contained in:
Jeppe B
2026-06-02 01:34:21 +02:00
parent 5850bfbce7
commit 0bf19c9d33
2 changed files with 25 additions and 1 deletions
@@ -455,6 +455,20 @@ class system_search_service
return empty(array_intersect($normalizedDirty, system_search_registry::sourceTablesForEntityType($entityType)));
}
private function indexedEntitySupportsDepartmentFilter(string $entityType): bool
{
$entityType = trim(mb_strtolower($entityType));
if (in_array($entityType, ['orders', 'objects'], true)) {
return true;
}
$config = system_search_registry::genericEntityConfigs()[$entityType] ?? null;
return is_array($config)
&& isset($config['department_field'])
&& is_string($config['department_field'])
&& trim($config['department_field']) !== '';
}
/**
* @param array<int, string> $terms
* @param array<string, bool> $moduleConfigVisibility
@@ -491,7 +505,7 @@ class system_search_service
if (!empty($customerNumbers)) {
$wheres[] = "`customer_number` IN (" . implode(',', array_map('intval', $customerNumbers)) . ")";
}
if (!empty($allowedDepartmentIds)) {
if (!empty($allowedDepartmentIds) && $this->indexedEntitySupportsDepartmentFilter($entityType)) {
$wheres[] = "`department_id` IN (" . implode(',', array_map('intval', $allowedDepartmentIds)) . ")";
}
@@ -406,6 +406,16 @@ it('passes allowed department ids into lexical execution context', function ():
expect($service->lexicalCalls[0]['allowedDepartmentIds'])->toBe([3, 7]);
});
it('only applies indexed department filters to department-scoped indexed entities', function (): void {
$service = new TestableSystemSearchService(new FakeSystemSearchIntentParser(), []);
expect(system_search_service_invoke_private($service, 'indexedEntitySupportsDepartmentFilter', ['orders']))->toBeTrue();
expect(system_search_service_invoke_private($service, 'indexedEntitySupportsDepartmentFilter', ['objects']))->toBeTrue();
expect(system_search_service_invoke_private($service, 'indexedEntitySupportsDepartmentFilter', ['bookings']))->toBeTrue();
expect(system_search_service_invoke_private($service, 'indexedEntitySupportsDepartmentFilter', ['customers']))->toBeFalse();
expect(system_search_service_invoke_private($service, 'indexedEntitySupportsDepartmentFilter', ['invoices']))->toBeFalse();
});
it('does not expand associations for own-only entity types', function (): void {
$parser = new FakeSystemSearchIntentParser();
$service = new TestableSystemSearchService($parser, [