Add customer pricing permissions and update related tests

This commit is contained in:
Jeppe Bundgaard
2026-07-07 17:58:39 +02:00
parent 172a21c517
commit 084435e9b8
7 changed files with 115 additions and 11 deletions
@@ -11,6 +11,8 @@ class limited_backoffice_service
{
public const PERMISSION_ACCESS = 'limited_backoffice_access';
public const PERMISSION_MANAGE_PRICES = 'limited_backoffice_prices_manage';
public const PERMISSION_VIEW_CUSTOMER_PRICING = 'limited_backoffice_customer_pricing_view';
public const PERMISSION_MANAGE_CUSTOMER_PRICING = 'limited_backoffice_customer_pricing_manage';
public const PERMISSION_MANAGE_EMPLOYEES = 'limited_backoffice_employees_manage';
private const PERMISSION_PUBLIC_EMPLOYEE_DATA = 'employee_public_data';
@@ -251,6 +253,8 @@ class limited_backoffice_service
'statistics_bookings_new',
self::PERMISSION_ACCESS,
self::PERMISSION_MANAGE_PRICES,
self::PERMISSION_VIEW_CUSTOMER_PRICING,
self::PERMISSION_MANAGE_CUSTOMER_PRICING,
self::PERMISSION_MANAGE_EMPLOYEES,
],
],
@@ -484,6 +488,14 @@ class limited_backoffice_service
'group' => 'limited_backoffice',
'capability' => 'manage_department_prices',
],
self::PERMISSION_VIEW_CUSTOMER_PRICING => [
'group' => 'limited_backoffice',
'capability' => 'view_customer_pricing',
],
self::PERMISSION_MANAGE_CUSTOMER_PRICING => [
'group' => 'limited_backoffice',
'capability' => 'manage_customer_pricing',
],
self::PERMISSION_MANAGE_EMPLOYEES => [
'group' => 'limited_backoffice',
'capability' => 'manage_employee_access',
+24 -4
View File
@@ -12683,7 +12683,15 @@ paths:
minimum: 1
- name: user_id
in: query
required: true
required: false
description: Internal user id. Provide either user_id or customer_number.
schema:
type: integer
minimum: 1
- name: customer_number
in: query
required: false
description: Customer number. Provide either user_id or customer_number.
schema:
type: integer
minimum: 1
@@ -12746,7 +12754,15 @@ paths:
minimum: 1
- name: user_id
in: query
required: true
required: false
description: Internal user id. Provide either user_id or customer_number.
schema:
type: integer
minimum: 1
- name: customer_number
in: query
required: false
description: Customer number. Provide either user_id or customer_number.
schema:
type: integer
minimum: 1
@@ -13619,7 +13635,6 @@ components:
type: object
required:
- department_id
- user_id
- overrides
properties:
department_id:
@@ -13628,6 +13643,9 @@ components:
user_id:
type: integer
minimum: 1
customer_number:
type: integer
minimum: 1
overrides:
type: array
items:
@@ -13636,12 +13654,14 @@ components:
DepartmentCustomerPricingLimitedUpdateRequest:
type: object
required:
- user_id
- overrides
properties:
user_id:
type: integer
minimum: 1
customer_number:
type: integer
minimum: 1
overrides:
type: array
items:
@@ -47,18 +47,20 @@ class limitedBackofficeRoute
$this->get('/limited-backoffice/departments/{departmentId}/customer-pricing', function () {
$this->withLimitedBackoffice(function (limited_backoffice_service $service, $user): array {
$this->requirePermission(limited_backoffice_service::PERMISSION_ACCESS);
$this->requirePermission(limited_backoffice_service::PERMISSION_VIEW_CUSTOMER_PRICING);
$departmentId = $this->routePositiveInt('departmentId');
$customerUserId = $this->queryCustomerUserId();
return $service->getDepartmentCustomerPricing($user, $departmentId, $customerUserId);
});
}, [
limited_backoffice_service::PERMISSION_ACCESS => 'Access the limited backoffice',
limited_backoffice_service::PERMISSION_VIEW_CUSTOMER_PRICING => 'View limited backoffice department customer pricing',
]);
$this->put('/limited-backoffice/departments/{departmentId}/customer-pricing', function () {
$this->withLimitedBackoffice(function (limited_backoffice_service $service, $user): array {
$this->requirePermission(limited_backoffice_service::PERMISSION_ACCESS);
$this->requirePermission(limited_backoffice_service::PERMISSION_MANAGE_PRICES);
$this->requirePermission(limited_backoffice_service::PERMISSION_MANAGE_CUSTOMER_PRICING);
$departmentId = $this->routePositiveInt('departmentId');
$payload = $this->requestPayload();
$customerUserId = $this->payloadCustomerUserId($payload);
@@ -66,7 +68,7 @@ class limitedBackofficeRoute
});
}, [
limited_backoffice_service::PERMISSION_ACCESS => 'Access the limited backoffice',
limited_backoffice_service::PERMISSION_MANAGE_PRICES => 'Manage limited backoffice department prices',
limited_backoffice_service::PERMISSION_MANAGE_CUSTOMER_PRICING => 'Manage limited backoffice department customer pricing',
]);
$this->get('/limited-backoffice/roles', function () {
@@ -144,10 +144,25 @@ it('limits department customer pricing to assigned limited-backoffice department
$otherFixture = department_customer_pricing_setup(['name' => 'Denied Scoped Customer Pricing Department']);
$session = api_fixtures()->createUserSession([
limited_backoffice_service::PERMISSION_ACCESS,
limited_backoffice_service::PERMISSION_MANAGE_PRICES,
limited_backoffice_service::PERMISSION_VIEW_CUSTOMER_PRICING,
limited_backoffice_service::PERMISSION_MANAGE_CUSTOMER_PRICING,
'department_access_' . (int)$fixture['department']['id'],
]);
api_client()
->get(
'/limited-backoffice/departments/' . (int)$fixture['department']['id'] .
'/customer-pricing?user_id=' . (int)$fixture['customer']['id'],
api_fixtures()->createUserSession([
limited_backoffice_service::PERMISSION_ACCESS,
'department_access_' . (int)$fixture['department']['id'],
])['headers']
)
->assertStatus(403)
->assertEnvelope()
->assertSuccess(false)
->assertMissingPermissions([limited_backoffice_service::PERMISSION_VIEW_CUSTOMER_PRICING]);
api_client()
->get(
'/limited-backoffice/departments/' . (int)$otherFixture['department']['id'] .
@@ -159,6 +174,24 @@ it('limits department customer pricing to assigned limited-backoffice department
->assertSuccess(false)
->assertMissingPermissions(['department_access_' . (int)$otherFixture['department']['id']]);
api_client()
->put(
'/limited-backoffice/departments/' . (int)$fixture['department']['id'] . '/customer-pricing',
[
'user_id' => $fixture['customer']['id'],
'overrides' => [],
],
api_fixtures()->createUserSession([
limited_backoffice_service::PERMISSION_ACCESS,
limited_backoffice_service::PERMISSION_VIEW_CUSTOMER_PRICING,
'department_access_' . (int)$fixture['department']['id'],
])['headers']
)
->assertStatus(403)
->assertEnvelope()
->assertSuccess(false)
->assertMissingPermissions([limited_backoffice_service::PERMISSION_MANAGE_CUSTOMER_PRICING]);
$updated = api_client()->put(
'/limited-backoffice/departments/' . (int)$fixture['department']['id'] . '/customer-pricing',
[
@@ -11,6 +11,8 @@ function limited_backoffice_manager_session(array $departmentIds, array $extraPe
$permissions = [
limited_backoffice_service::PERMISSION_ACCESS,
limited_backoffice_service::PERMISSION_MANAGE_PRICES,
limited_backoffice_service::PERMISSION_VIEW_CUSTOMER_PRICING,
limited_backoffice_service::PERMISSION_MANAGE_CUSTOMER_PRICING,
limited_backoffice_service::PERMISSION_MANAGE_EMPLOYEES,
];
foreach ($departmentIds as $departmentId) {
@@ -77,6 +79,8 @@ function limited_backoffice_all_role_permissions(): array
'list_own_notifications',
'statistics_orders_new',
'statistics_bookings_new',
'limited_backoffice_customer_pricing_view',
'limited_backoffice_customer_pricing_manage',
];
}
@@ -879,6 +883,8 @@ it('creates updates lists and deactivates scoped employees without exposing raw
expect($departmentAdminGroups['limited_backoffice'] ?? null)->toBe([
'open_limited_backoffice',
'manage_department_prices',
'view_customer_pricing',
'manage_customer_pricing',
'manage_employee_access',
]);
expect($roles->body)->not->toContain('department_access_');
@@ -940,6 +946,8 @@ it('creates updates lists and deactivates scoped employees without exposing raw
'statistics_bookings_new',
'limited_backoffice_access',
'limited_backoffice_prices_manage',
'limited_backoffice_customer_pricing_view',
'limited_backoffice_customer_pricing_manage',
'limited_backoffice_employees_manage',
] as $rawPermission) {
expect($rolePayloadStrings)->not->toContain($rawPermission);
@@ -1654,6 +1662,13 @@ it('includes statistics_orders_new and statistics_bookings_new (Overblik) in all
}
});
it('includes customer pricing permissions in the department admin limited backoffice role preset', function (): void {
$permissions = limited_backoffice_role_preset_permissions('department_admin');
expect($permissions)
->toContain(limited_backoffice_service::PERMISSION_VIEW_CUSTOMER_PRICING)
->toContain(limited_backoffice_service::PERMISSION_MANAGE_CUSTOMER_PRICING);
});
it('assigns list_departments to managed employees and enforces list_departments permission on GET /departments', function (): void {
api_test_covers('GET /departments', 'limited backoffice employee');
@@ -34,6 +34,8 @@ it('lists limited backoffice permission templates for superuser role maintenance
expect($templatesByKey['cashier']['permissions'] ?? [])->toContain('statistics_orders_new');
expect($templatesByKey['department_admin']['permissions'] ?? [])->toContain('limited_backoffice_access');
expect($templatesByKey['department_admin']['permissions'] ?? [])->toContain('limited_backoffice_prices_manage');
expect($templatesByKey['department_admin']['permissions'] ?? [])->toContain('limited_backoffice_customer_pricing_view');
expect($templatesByKey['department_admin']['permissions'] ?? [])->toContain('limited_backoffice_customer_pricing_manage');
expect($templatesByKey['department_admin']['permissions'] ?? [])->toContain('limited_backoffice_employees_manage');
});