692 lines
32 KiB
PHP
692 lines
32 KiB
PHP
<?php
|
|
|
|
namespace routes;
|
|
|
|
use classes\authentication;
|
|
use classes\selfserve;
|
|
use DateTimeImmutable;
|
|
use DateTimeZone;
|
|
use objects\categories_o;
|
|
use objects\department_categories_o;
|
|
use objects\department_lanes_o;
|
|
use objects\department_time_bookings_opening_hours_o;
|
|
use objects\department_variables_o;
|
|
use objects\departments_o;
|
|
use objects\logs_o;
|
|
use objects\orders_o;
|
|
use traits\route_t;
|
|
|
|
class departmentsRoute
|
|
{
|
|
use route_t;
|
|
|
|
private function buildDepartmentListFilters(departments_o $departments, bool $canListArchived): array
|
|
{
|
|
global $response;
|
|
|
|
$filters = $response->getRequestParameter('filters') ?? [];
|
|
if (is_string($filters) || is_array($filters)) {
|
|
$filters = $departments->filter_string_to_array($filters);
|
|
} else {
|
|
$filters = [];
|
|
}
|
|
|
|
$archived = 0;
|
|
if (
|
|
$canListArchived
|
|
&& array_key_exists('archived', $filters)
|
|
&& self::isTruthyBooleanValue($filters['archived'])
|
|
) {
|
|
$archived = 1;
|
|
}
|
|
|
|
unset($filters['visible'], $filters['archived']);
|
|
$filters['visible'] = 1;
|
|
$filters['archived'] = $archived;
|
|
|
|
return $filters;
|
|
}
|
|
|
|
private static function isTruthyBooleanValue(mixed $value): bool
|
|
{
|
|
if (is_array($value)) {
|
|
foreach ($value as $singleValue) {
|
|
if (self::isTruthyBooleanValue($singleValue)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
if (is_bool($value)) {
|
|
return $value;
|
|
}
|
|
|
|
if (is_numeric($value)) {
|
|
return (int)$value === 1;
|
|
}
|
|
|
|
if (is_string($value)) {
|
|
return in_array(strtolower(trim($value)), ['1', 'true', 'yes', 'on'], true);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function run(): void
|
|
{
|
|
$this->get('/departments', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
$this->requirePermission('list_departments');
|
|
// Get the user object
|
|
$user = (new authentication())->get_user();
|
|
// Check if the request was successful
|
|
if ($user) {
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, $user->id, 'LIST_DEPARTMENTS', 'Successfully listed departments');
|
|
// Check if the id is set in the request
|
|
if (self::isParametersSet(['id'])) {
|
|
// Return the department
|
|
$response->success(
|
|
(new departments_o())->select((int)self::getParameter('id'))->asArray([
|
|
'slack_webhook' => $user->hasPermission('view_slack_webhook')
|
|
])
|
|
);
|
|
}
|
|
$departments_o = new departments_o();
|
|
// Return the list of departments
|
|
$response->success(
|
|
$departments_o
|
|
->setSearchableFields([
|
|
// The fields that can be searched. This would otherwise make it possible to get secret information from the database, simply by searching for it and getting the result count back
|
|
'id',
|
|
'name',
|
|
'description',
|
|
'economic_department_id',
|
|
'visible',
|
|
'archived',
|
|
'custom_pricing_only',
|
|
'longitude',
|
|
'latitude',
|
|
])
|
|
->listObjectsWithPaginationIfSet(
|
|
function ($department) use ($user) {
|
|
$tmp_department = [
|
|
'id' => (int)$department['id'],
|
|
'name' => (string)$department['name'],
|
|
'description' => $department['description'],
|
|
'economic_department_id' => (int)$department['economic_department_id'],
|
|
'created_at' => (string)$department['created_at'],
|
|
'updated_at' => (string)$department['updated_at'],
|
|
'visible' => (int)$department['visible'],
|
|
'dimension' => (int)$department['dimension'],
|
|
'branding' => (int)$department['branding'],
|
|
'archived' => (bool)(int)($department['archived'] ?? 0),
|
|
'longitude' => (float)$department['longitude'],
|
|
'latitude' => (float)$department['latitude'],
|
|
'order_priority' => (int)$department['order_priority'],
|
|
];
|
|
if (
|
|
$user->hasPermission('superuser_fetch_department')
|
|
|| $user->hasPermission('edit_department')
|
|
) {
|
|
$tmp_department['custom_pricing_only'] = (bool)(int)($department['custom_pricing_only'] ?? 0);
|
|
}
|
|
// If the user has the permission to view the slack webhook, add it to the response
|
|
if ($user->hasPermission('view_slack_webhook')) {
|
|
$tmp_department['slack_webhook'] = $department['slack_webhook'];
|
|
}
|
|
return $tmp_department;
|
|
},
|
|
$this->buildDepartmentListFilters(
|
|
$departments_o,
|
|
$user->hasPermission('superuser_fetch_department')
|
|
)
|
|
)
|
|
);
|
|
} else {
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, 0, 'LIST_DEPARTMENTS', 'No user found, or invalid session');
|
|
// Return an error
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
},
|
|
[
|
|
'list_departments' => 'List all departments',
|
|
'view_slack_webhook' => 'View the slack webhook'
|
|
]
|
|
);
|
|
|
|
$this->post('/departments', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
$this->requirePermission('add_department');
|
|
// Get the user object
|
|
$user = (new authentication())->get_user();
|
|
// Check if the request was successful
|
|
if ($user) {
|
|
// Get the post data
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
// Check if the required fields are set
|
|
if (!isset($data['name'])) {
|
|
$response->error('Name is required', 400);
|
|
}
|
|
if (!isset($data['description'])) {
|
|
$response->error('Description is required', 400);
|
|
}
|
|
|
|
// Add the department
|
|
(new departments_o())->create($data['name'], $data['description']);
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, $user->id, 'ADD_DEPARTMENT', 'Successfully added a department ' . $data['name']);
|
|
// Return a success message
|
|
$response->success(['message' => 'Department added successfully']);
|
|
} else {
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, 0, 'ADD_DEPARTMENT', 'No user found, or invalid session');
|
|
// Return an error
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
},
|
|
[
|
|
'add_department' => 'Add a department'
|
|
]
|
|
);
|
|
|
|
$this->put('/departments', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
self::requirePermission('edit_department');
|
|
// Get the user object
|
|
$user = (new authentication())->get_user();
|
|
// Check if the request was successful
|
|
if ($user) {
|
|
// Require the required fields
|
|
self::requireParameters(['id']);
|
|
// Validate the required fields
|
|
self::requireType((int)self::getParameter('id'), self::TYPE_INT());
|
|
// Get the department object
|
|
$department = (new departments_o())->select(self::getParameter('id'));
|
|
// Update the fields provided
|
|
if (self::isParametersSet(['name'])) {
|
|
$department->name->set(self::getParameter('name'));
|
|
}
|
|
if (self::isParametersSet(['description'])) {
|
|
$department->description->set(self::getParameter('description'));
|
|
}
|
|
if (self::isParametersSet(['economic_department_id'])) {
|
|
$department->economic_department_id->set(self::getParameter('economic_department_id'));
|
|
}
|
|
if (self::isParametersSet(['latitude'])) {
|
|
$department->latitude->set(self::getParameter('latitude'));
|
|
}
|
|
if (self::isParametersSet(['longitude'])) {
|
|
$department->longitude->set(self::getParameter('longitude'));
|
|
}
|
|
if (self::isParametersSet(['order_priority'])) {
|
|
$department->order_priority->set((int)self::getParameter('order_priority'));
|
|
}
|
|
if (self::isParametersSet(['archived'])) {
|
|
$department->archived->set(self::isTruthyBooleanValue(self::getParameter('archived')));
|
|
}
|
|
if (self::isParametersSet(['custom_pricing_only'])) {
|
|
$department->custom_pricing_only->set(self::isTruthyBooleanValue(self::getParameter('custom_pricing_only')));
|
|
}
|
|
$department->objectChanged();
|
|
// Log the incident
|
|
(new logs_o())->add('departments', (int)self::getParameter('id'), 1, $user->id, 'EDIT_DEPARTMENT', 'Successfully edited a department');
|
|
// Return a success message
|
|
$response->success(['message' => 'Department updated successfully']);
|
|
} else {
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, 0, 'EDIT_DEPARTMENT', 'No user found, or invalid session');
|
|
// Return an error
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
},
|
|
[
|
|
'edit_department' => 'Edit a department'
|
|
]
|
|
);
|
|
|
|
$this->get('/departments/categories', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
$auth = new authentication();
|
|
$user = $auth->get_user();
|
|
$subuser = $auth->get_subuser();
|
|
// Check if the request was successful
|
|
if ($user || $subuser) {
|
|
$isCustomerBookingSession = ($user && self::hasPermission('user')) || $subuser;
|
|
if (!$isCustomerBookingSession && !self::hasPermission('list_department_categories')) {
|
|
$this->emitForbidden(['list_department_categories']);
|
|
}
|
|
|
|
$responsibleUserId = $user ? (int)$user->id : 0;
|
|
// Require the department id
|
|
self::requireParameters(['id']);
|
|
self::requireType((int)self::getParameter('id'), self::TYPE_INT());
|
|
// Get the department object
|
|
$department = (new departments_o())->select(self::getParameter('id'));
|
|
// Validate the department categories object
|
|
if (!$department->exists()) {
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, $responsibleUserId, 'LIST_DEPARTMENT_CATEGORIES', 'Department categories not found');
|
|
// Return an error
|
|
$response->error('Department categories not found', 400);
|
|
}
|
|
// Get the department categories
|
|
$department_categories = new department_categories_o();
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, $responsibleUserId, 'LIST_DEPARTMENT_CATEGORIES', 'Successfully listed department categories');
|
|
// Return the list of department categories
|
|
$response->success(
|
|
$department_categories
|
|
->getCategoriesForDepartment(self::getParameter('id'),
|
|
function ($department_category) {
|
|
return [
|
|
'id' => (int)$department_category['id'],
|
|
'department_id' => (int)$department_category['department_id'],
|
|
'category_id' => (int)$department_category['category_id'],
|
|
'created_at' => (string)$department_category['created_at'],
|
|
'updated_at' => $department_category['updated_at'],
|
|
'category' => $department_category['category']->asArray()
|
|
];
|
|
}
|
|
)
|
|
);
|
|
} else {
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, 0, 'LIST_DEPARTMENT_CATEGORIES', 'No user found, or invalid session');
|
|
// Return an error
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
},
|
|
[
|
|
'list_department_categories' => 'List all department categories. Authenticated customer booking sessions may read this endpoint without the permission.'
|
|
]
|
|
);
|
|
|
|
$this->get('/departments/self-serve/enabled', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
self::requirePermission('view_department_selfserve_enabled');
|
|
// Get the user object
|
|
$user = (new authentication())->get_user();
|
|
// Check if the request was successful
|
|
if ($user) {
|
|
// Require the department id
|
|
self::requireParameters(['id']);
|
|
self::requireType((int)self::getParameter('id'), self::type_int());
|
|
// Get the department object
|
|
$department = (new departments_o())->select(self::getParameter('id'));
|
|
// Validate the department object
|
|
if (!$department->exists()) {
|
|
// Return an error
|
|
$response->error('Department not found', 404);
|
|
}
|
|
// Check if the user has access to the department
|
|
self::requireDepartmentAccess((string)$department->id);
|
|
// Get the department variable
|
|
$department_variables = (new department_variables_o())->selectDepartment($department->id);
|
|
$enabled = $department_variables->getVariable('selfserve_enabled');
|
|
|
|
// Return the status
|
|
$response->success(
|
|
$this->buildDepartmentSelfServeEnabledPayload((int)$department->id, $enabled === true)
|
|
);
|
|
} else {
|
|
// Return an error
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
},
|
|
[
|
|
'view_department_selfserve_enabled' => 'View if department self-serve is enabled',
|
|
'department_access_:id' => 'Access the department'
|
|
]
|
|
);
|
|
|
|
$this->put('/departments/self-serve/enabled', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
self::requirePermission('edit_department_selfserve_enabled');
|
|
// Get the user object
|
|
$user = (new authentication())->get_user();
|
|
// Check if the request was successful
|
|
if ($user) {
|
|
// Require the department id and enabled status
|
|
self::requireParameters(['id', 'enabled']);
|
|
self::requireType((int)self::getParameter('id'), self::type_int());
|
|
self::requireType((bool)self::getParameter('enabled'), self::type_bool());
|
|
// Get the department object
|
|
$department = (new departments_o())->select(self::getParameter('id'));
|
|
// Validate the department object
|
|
if (!$department->exists()) {
|
|
// Return an error
|
|
$response->error('Department not found', 404);
|
|
}
|
|
// Check if the user has access to the department
|
|
self::requireDepartmentAccess((string)$department->id);
|
|
// Set the department variable
|
|
$department_variables = (new department_variables_o())->selectDepartment($department->id);
|
|
$enabled = self::getParameter('enabled') === 'true' || self::getParameter('enabled') === true || self::getParameter('enabled') === 1 || self::getParameter('enabled') === '1';
|
|
department_variables_o::withSelfServeTransitionLock(
|
|
(int)$department->id,
|
|
function () use ($department_variables, $department, $enabled): void {
|
|
$department_variables->set('selfserve_enabled', $enabled ? 'true' : 'false');
|
|
$this->syncDepartmentSelfServeRelayStates((int)$department->id, $enabled);
|
|
}
|
|
);
|
|
|
|
// Log the incident
|
|
(new logs_o())->add('departments', $department->id, 1, $user->id, 'EDIT_DEPARTMENT_SELFSERVE_ENABLED', 'Successfully edited department self-serve enabled status to ' . ($enabled ? 'true' : 'false'));
|
|
|
|
// Return a success message
|
|
$response->success([
|
|
'message' => 'Department self-serve enabled status updated successfully',
|
|
...$this->buildDepartmentSelfServeEnabledPayload((int)$department->id, $enabled)
|
|
]);
|
|
} else {
|
|
// Return an error
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
},
|
|
[
|
|
'edit_department_selfserve_enabled' => 'Edit if department self-serve is enabled (Requires department access)',
|
|
'department_access_:id' => 'Access the department'
|
|
]
|
|
);
|
|
|
|
$this->post('/departments/categories', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
self::requirePermission('add_department_category');
|
|
// Get the user object
|
|
$user = (new authentication())->get_user();
|
|
// Check if the request was successful
|
|
if ($user) {
|
|
// Require the parameters
|
|
self::requireParameters(['department_id', 'category_id']);
|
|
self::requireType((int)self::getParameter('department_id'), self::TYPE_INT());
|
|
self::requireType((int)self::getParameter('category_id'), self::TYPE_INT());
|
|
// Get the department object
|
|
$department = (new departments_o())->select(self::getParameter('department_id'));
|
|
// Validate the department object
|
|
if (!$department->exists()) {
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, $user->id, 'ADD_DEPARTMENT_CATEGORY', 'Department not found');
|
|
// Return an error
|
|
$response->error('Department not found', 400);
|
|
}
|
|
// Get the category object
|
|
$category = (new categories_o())->select(self::getParameter('category_id'));
|
|
// Validate the category object
|
|
if (!$category->exists()) {
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, $user->id, 'ADD_DEPARTMENT_CATEGORY', 'Category not found');
|
|
// Return an error
|
|
$response->error('Category not found', 400);
|
|
}
|
|
// Add the department category
|
|
$department_categories = new department_categories_o();
|
|
$department_categories->add(
|
|
self::getParameter('department_id'),
|
|
self::getParameter('category_id')
|
|
);
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, $user->id, 'ADD_DEPARTMENT_CATEGORY', 'Successfully added a department category');
|
|
// Return a success message
|
|
$response->success(['message' => 'Department category added successfully']);
|
|
} else {
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, 0, 'ADD_DEPARTMENT_CATEGORY', 'No user found, or invalid session');
|
|
// Return an error
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
},
|
|
[
|
|
'add_department_category' => 'Add a department category'
|
|
]
|
|
);
|
|
|
|
$this->delete('/departments/categories', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
self::requirePermission('delete_department_category');
|
|
// Get the user object
|
|
$user = (new authentication())->get_user();
|
|
// Check if the request was successful
|
|
if ($user) {
|
|
// Require the parameters
|
|
self::requireParameters(['id']);
|
|
self::requireType((int)self::getParameter('id'), self::TYPE_INT());
|
|
// Get the department category object
|
|
$department_category = (new department_categories_o())->select(self::getParameter('id'));
|
|
// Validate the department category object
|
|
if (!$department_category->exists()) {
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, $user->id, 'DELETE_DEPARTMENT_CATEGORY', 'Department category not found');
|
|
// Return an error
|
|
$response->error('Department category not found', 400);
|
|
}
|
|
// Delete the department category
|
|
$department_category->delete();
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, $user->id, 'DELETE_DEPARTMENT_CATEGORY', 'Successfully deleted a department category');
|
|
// Return a success message
|
|
$response->success(['message' => 'Department category deleted successfully']);
|
|
} else {
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, 0, 'DELETE_DEPARTMENT_CATEGORY', 'No user found, or invalid session');
|
|
// Return an error
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
},
|
|
[
|
|
'delete_department_category' => 'Delete a department category'
|
|
]
|
|
);
|
|
|
|
self::get('/departments/order/recommended', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
self::requirePermission('list_department_order_recommended');
|
|
// Get the user object
|
|
$user = (new authentication())->get_user();
|
|
// Check if the request was successful
|
|
if ($user) {
|
|
// Check if the required fields are set
|
|
self::requireParameters(['id']);
|
|
self::requireType((int)self::getParameter('id'), self::TYPE_INT());
|
|
// Get the order
|
|
$order = (new orders_o())->select((int)self::getParameter('id'));
|
|
$order->requireSelected();
|
|
// Check if the user is allowed to view the recommended order for the department
|
|
self::requireDepartmentAccess($order->department_id->value());
|
|
// Get the recommended order
|
|
$recommended_order = $order->getRecommendedOrder();
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, $user->id, 'LIST_DEPARTMENT_ORDER_RECOMMENDED', 'Successfully listed the recommended department order');
|
|
// Return the recommended order
|
|
$response->success($recommended_order);
|
|
} else {
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, 0, 'LIST_DEPARTMENT_ORDER_RECOMMENDED', 'No user found, or invalid session');
|
|
// Return an error
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
},
|
|
[
|
|
'list_department_order_recommended' => 'List the recommended department order',
|
|
'order_access_:id' => 'Access the order',
|
|
'department_access_:id' => 'Access the department'
|
|
]
|
|
);
|
|
|
|
self::get('/departments/weekly-results', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
self::requirePermission('view_department_weekly_results');
|
|
// Get the user object
|
|
$user = (new authentication())->get_user();
|
|
// Check if the request was successful
|
|
if ($user) {
|
|
// Get the department results for the week
|
|
$departments_o = new departments_o();
|
|
$weeks = 3;
|
|
$results = [];
|
|
for ($i = 0; $i < $weeks; $i++) {
|
|
// Get the week number
|
|
$week_number = date('W', strtotime("-$i week"));
|
|
// Skip the next week, only show show weeks where at least monday at 00:00:00 is in the past, to prevent showing incomplete data for the current week
|
|
// Get the weeks monday
|
|
$week_start = strtotime("-$i week Monday");
|
|
if ($week_start < strtotime('now')) {
|
|
$week_monday = date('Y-m-d 00:00:00', $week_start);
|
|
// Get the weeks sunday from monday
|
|
$week_sunday = date('Y-m-d 23:59:59', strtotime("$week_monday +6 days"));
|
|
$results[$week_number] = [
|
|
'week_number' => $week_number,
|
|
'week_monday' => $week_monday,
|
|
'week_sunday' => $week_sunday,
|
|
'results' => $departments_o->sendSlackInternalStatisticNotification(
|
|
$week_monday,
|
|
$week_sunday,
|
|
[],
|
|
// Default value
|
|
[
|
|
25,
|
|
[23, 24], // Used to merge two products into one percentage (Spot Free)
|
|
22,
|
|
27,
|
|
21,
|
|
26
|
|
],
|
|
true // Return the results instead of sending the notification (This is used to show the results in the frontend, instead of sending them to slack.
|
|
)
|
|
];
|
|
}
|
|
}
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, $user->id, 'VIEW_DEPARTMENT_WEEKLY_RESULTS', 'Successfully viewed department weekly results');
|
|
// Return the results
|
|
$response->success($results);
|
|
} else {
|
|
// Log the incident
|
|
(new logs_o())->add('departments', 'global', 1, 0, 'VIEW_DEPARTMENT_WEEKLY_RESULTS', 'No user found, or invalid session');
|
|
// Return an error
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
},
|
|
[
|
|
'view_department_weekly_results' => 'View department weekly results'
|
|
]
|
|
);
|
|
}
|
|
protected function syncDepartmentSelfServeRelayStates(int $departmentId, bool $enabled): void
|
|
{
|
|
$selfserve = new selfserve();
|
|
$lanes = (new department_lanes_o())->getDepartmentLanes($departmentId);
|
|
|
|
foreach ($lanes as $department_lane) {
|
|
$lane_id = (int)$department_lane->id;
|
|
if ($lane_id <= 0) {
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
$lane = $selfserve->lane($lane_id);
|
|
} catch (\Throwable) {
|
|
continue;
|
|
}
|
|
|
|
if (!$enabled) {
|
|
// Self-serve disabled: restore normal/manual relay operation.
|
|
$this->setOptionalLaneRelayState($lane, 'relay_machine_program_picker_id', static function () use ($lane): void {
|
|
$lane->setMachineProgramPickerRelayStatusForDepartmentOperation(true);
|
|
});
|
|
$this->setOptionalLaneRelayState($lane, 'relay_machine_cleaner_id', static function () use ($lane): void {
|
|
$lane->setMachineCleanerRelayStatusForDepartmentOperation(true);
|
|
});
|
|
$this->setOptionalLaneRelayState($lane, 'relay_machine_id', static function () use ($lane): void {
|
|
$lane->setMachineRelayStatusForDepartmentOperation(true);
|
|
});
|
|
continue;
|
|
}
|
|
|
|
if (!$department_lane->isSelfServeEnabled()) {
|
|
continue;
|
|
}
|
|
|
|
// Self-serve enabled: lances must be usable; machine-only relays stay off.
|
|
$this->setOptionalLaneRelayState($lane, 'relay_machine_program_picker_id', static function () use ($lane): void {
|
|
$lane->setMachineProgramPickerRelayStatus(false);
|
|
});
|
|
$this->setOptionalLaneRelayState($lane, 'relay_machine_cleaner_id', static function () use ($lane): void {
|
|
$lane->setMachineCleanerRelayStatusHard(true);
|
|
});
|
|
try {
|
|
$lane->setMachineRelayStatus(false);
|
|
} catch (\Throwable) {}
|
|
}
|
|
}
|
|
|
|
protected function setOptionalLaneRelayState(object $lane, string $relayProperty, callable $callback): void
|
|
{
|
|
if (
|
|
empty($lane->department_lane)
|
|
|| !isset($lane->department_lane->{$relayProperty})
|
|
|| !is_object($lane->department_lane->{$relayProperty})
|
|
|| !method_exists($lane->department_lane->{$relayProperty}, 'value')
|
|
) {
|
|
return;
|
|
}
|
|
|
|
$relay_id = trim((string)$lane->department_lane->{$relayProperty}->value());
|
|
if ($relay_id === '') {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$callback();
|
|
} catch (\Throwable) {
|
|
// Best effort only; this endpoint should still update the department variable.
|
|
}
|
|
}
|
|
|
|
private function buildDepartmentSelfServeEnabledPayload(int $departmentId, bool $enabled): array
|
|
{
|
|
$nextDeactivationAt = $enabled
|
|
? $this->getDepartmentSelfServeAutoDeactivationAt($departmentId)
|
|
: null;
|
|
|
|
return [
|
|
'enabled' => $enabled,
|
|
'auto_deactivation' => [
|
|
'at' => $nextDeactivationAt?->format(DATE_ATOM),
|
|
'timezone' => 'Europe/Copenhagen',
|
|
'label' => $nextDeactivationAt === null
|
|
? 'NEVER'
|
|
: $nextDeactivationAt->format('Y-m-d H:i:s'),
|
|
],
|
|
];
|
|
}
|
|
|
|
private function getDepartmentSelfServeAutoDeactivationAt(int $departmentId): ?DateTimeImmutable
|
|
{
|
|
try {
|
|
$openingHours = new department_time_bookings_opening_hours_o();
|
|
if (!$openingHours->selectExistingByDepartment($departmentId)) {
|
|
return null;
|
|
}
|
|
|
|
return $openingHours->getNextOpeningStart(
|
|
new DateTimeImmutable('now', new DateTimeZone('Europe/Copenhagen'))
|
|
);
|
|
} catch (\Throwable) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|