From 2502352dafa99d32c78d541f413c851a6486d886 Mon Sep 17 00:00:00 2001 From: Thomas Fink Date: Fri, 20 Sep 2024 13:05:03 +0200 Subject: [PATCH 01/10] endpoint working --- zmscitizenapi/bootstrap.php | 2 + .../Controllers/AppointmentReserve.php | 143 +++++++++++++++++- .../Services/AppointmentService.php | 2 +- .../Services/AvailableAppointmentsService.php | 49 ++++-- .../OfficesServicesRelationsService.php | 38 +++-- .../Zmscitizenapi/Services/ProcessService.php | 28 +++- .../Zmscitizenapi/AppointmentReserveTest.php | 4 +- .../AvailableAppointmentsListTest.php | 2 +- 8 files changed, 236 insertions(+), 32 deletions(-) diff --git a/zmscitizenapi/bootstrap.php b/zmscitizenapi/bootstrap.php index e088a568a..708e14373 100644 --- a/zmscitizenapi/bootstrap.php +++ b/zmscitizenapi/bootstrap.php @@ -22,6 +22,8 @@ // Set option for environment, routing, logging and templating \BO\Slim\Bootstrap::init(); +\App::$slim->addBodyParsingMiddleware(); + \App::$http = new \BO\Zmsclient\Http(\App::ZMS_API_URL); //\BO\Zmsclient\Psr7\Client::$curlopt = \App::$http_curl_config; diff --git a/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php b/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php index 6c91f09f1..efadf5062 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php +++ b/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php @@ -2,15 +2,154 @@ namespace BO\Zmscitizenapi\Controllers; +use BO\Zmscitizenapi\Application; use BO\Zmscitizenapi\BaseController; -use BO\Slim\Render; +use BO\Zmscitizenapi\Services\CaptchaService; +use BO\Zmscitizenapi\Services\ScopesService; +use BO\Zmscitizenapi\Services\OfficesServicesRelationsService; +use BO\Zmscitizenapi\Services\AvailableAppointmentsService; +use BO\Zmscitizenapi\Services\AppointmentService; +use BO\Zmscitizenapi\Services\ProcessService; +use BO\Zmscitizenapi\Helper\UtilityHelper; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; class AppointmentReserve extends BaseController { + protected $captchaService; + protected $scopesService; + protected $officesServicesRelationsService; + protected $availableAppointmentsService; + protected $appointmentService; + protected $utilityHelper; + protected $processService; + + public function __construct() + { + $this->captchaService = new CaptchaService(); + $this->scopesService = new ScopesService(); + $this->officesServicesRelationsService = new OfficesServicesRelationsService(); + $this->availableAppointmentsService = new AvailableAppointmentsService(); + $this->processService = new ProcessService(\App::$http); + $this->appointmentService = new AppointmentService($this->processService); + $this->utilityHelper = new UtilityHelper(); + } + + // This method signature matches the BaseController's method signature public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { - return Render::withJson($response, []); + // Cast RequestInterface to ServerRequestInterface + $request = $request instanceof ServerRequestInterface ? $request : null; + + if (!$request) { + return $this->createJsonResponse($response, [ + 'error' => 'Invalid request object', + 'status' => 400 + ], 400); + } + + // Get the body input + $body = $request->getParsedBody(); + if (is_null($body)) { + return $this->createJsonResponse($response, [ + 'error' => 'Invalid or missing request body', + 'status' => 400 + ], 400); + } + + $officeId = $body['officeId'] ?? null; + $serviceIds = $body['serviceId'] ?? []; + $serviceCounts = $body['serviceCount'] ?? [1]; + $captchaSolution = $body['captchaSolution'] ?? null; + $timestamp = $body['timestamp'] ?? null; + + if (!$officeId || empty($serviceIds) || !$timestamp) { + return $this->createJsonResponse($response, [ + 'error' => 'Missing required fields', + 'status' => 400 + ], 400); + } + + try { + // Step 1: Validate the scope for the office and check if captcha is required + $providerScope = $this->scopesService->getScopeByOfficeId($officeId); + $captchaRequired = Application::$CAPTCHA_ENABLED === "1" && $providerScope['captchaActivatedRequired'] === "1"; + + // Step 2: If captcha is required, verify it + if ($captchaRequired) { + $captchaVerificationResult = $this->captchaService->verifyCaptcha($captchaSolution); + if (!$captchaVerificationResult['success']) { + return $this->createJsonResponse($response, [ + 'errorCode' => 'captchaVerificationFailed', + 'errorMessage' => 'Captcha verification failed', + 'lastModified' => round(microtime(true) * 1000) + ], 400); + } + } + + // Step 3: Validate the service-location combination + $serviceValidationResult = $this->officesServicesRelationsService->validateServiceLocationCombination($officeId, $serviceIds); + if ($serviceValidationResult['status'] !== 200) { + return $this->createJsonResponse($response, $serviceValidationResult, 400); + } + + // Step 4: Get available timeslots using the AvailableAppointmentsService + $freeAppointments = $this->availableAppointmentsService->getFreeAppointments([ + 'officeId' => $officeId, + 'serviceIds' => $serviceIds, + 'serviceCounts' => $serviceCounts, + 'date' => $this->utilityHelper->getInternalDateFromTimestamp($timestamp) + ]); + + //error_log(json_encode($freeAppointments)); + + + // **Step 5: Find the matching time slot based on the requested timestamp** + $selectedProcess = array_filter($freeAppointments, function ($process) use ($timestamp) { + // Ensure 'appointments' is set and is an array before accessing it + if (!isset($process['appointments']) || !is_array($process['appointments'])) { + return false; + } + // Find the appointment slot with the exact matching timestamp + return in_array($timestamp, array_column($process['appointments'], 'date')); + }); + + if (empty($selectedProcess)) { + return $this->createJsonResponse($response, [ + 'errorCode' => 'appointmentNotAvailable', + 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', + 'lastModified' => round(microtime(true) * 1000) + ], 404); + } + + // Step 6: Prepare the process for reservation + $selectedProcess = array_values($selectedProcess)[0]; + $selectedProcess['clients'] = [ + [ + 'email' => 'test@muenchen.de' // Use actual client data here + ] + ]; + + // Step 7: Reserve the appointment using the ProcessService + $reservedProcess = $this->processService->reserveTimeslot($selectedProcess, $serviceIds, $serviceCounts); + + // Step 8: Use the AppointmentService's getThinnedProcessData method + $thinnedProcessData = $this->appointmentService->getThinnedProcessData($reservedProcess); + + // Step 9: Return the thinned process data + return $this->createJsonResponse($response, [ + 'reservedProcess' => $thinnedProcessData, + 'officeId' => $officeId + ], 200); + + } catch (\Exception $e) { + error_log('Unexpected error: ' . $e->getMessage()); + return $this->createJsonResponse($response, [ + 'error' => 'Unexpected error', + 'message' => $e->getMessage() + ], 500); + } } + } diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/AppointmentService.php b/zmscitizenapi/src/Zmscitizenapi/Services/AppointmentService.php index 1cb59ea43..9f8e52256 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Services/AppointmentService.php +++ b/zmscitizenapi/src/Zmscitizenapi/Services/AppointmentService.php @@ -73,7 +73,7 @@ private function validateInputs($processId, $authKey) return $errors; } - private function getThinnedProcessData($myProcess) + public function getThinnedProcessData($myProcess) { if (!$myProcess || !isset($myProcess->id)) { return []; diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php b/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php index cd53d7669..5b74f50ec 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php +++ b/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php @@ -77,15 +77,16 @@ public function getFreeAppointments(array $params) } try { - // Fetch available timeslots - $freeSlots = $this->getFreeTimeslots( + $processService = new ProcessService(\App::$http); + + $freeSlots = $processService->getFreeTimeslots( [$office], $requests, $params['date'], $params['date'] ); - return $this->processFreeSlots($freeSlots); + return $freeSlots['data']; } catch (\Exception $e) { error_log('Error in AvailableAppointmentsService: ' . $e->getMessage()); @@ -144,43 +145,63 @@ private function validateQueryParams($date, $officeId, $serviceIds, $serviceCoun private function processFreeSlots($freeSlots) { - if (empty($freeSlots)) { + // Check if $freeSlots is iterable (array or object that can be traversed) + if (empty($freeSlots) || !is_iterable($freeSlots)) { return [ 'appointmentTimestamps' => [], 'errorCode' => 'appointmentNotAvailable', - 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar', + 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', 'status' => 404, ]; } - + $currentTimestamp = time(); $appointmentTimestamps = []; - + + // Iterate over the slots and process appointments foreach ($freeSlots as $slot) { + //error_log("Processing slot: " . json_encode($slot)); // Debugging + + // Check if the slot has an appointments array and it is iterable + if (!isset($slot->appointments) || !is_iterable($slot->appointments)) { + continue; + } + + // Iterate over appointments and extract the timestamp foreach ($slot->appointments as $appointment) { - $timestamp = (int)$appointment->date; - if (!in_array($timestamp, $appointmentTimestamps) && $timestamp > $currentTimestamp) { - $appointmentTimestamps[] = $timestamp; + //error_log("Processing appointment: " . json_encode($appointment)); // Debugging + + if (isset($appointment->date)) { + $timestamp = (int)$appointment->date; + + // Ensure we only add future timestamps and avoid duplicates + if (!in_array($timestamp, $appointmentTimestamps) && $timestamp > $currentTimestamp) { + $appointmentTimestamps[] = $timestamp; + } } } } - + if (empty($appointmentTimestamps)) { return [ 'appointmentTimestamps' => [], 'errorCode' => 'appointmentNotAvailable', - 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar', + 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', 'status' => 404, ]; } - + + // Sort the timestamps and return the response sort($appointmentTimestamps); - + return [ 'appointmentTimestamps' => $appointmentTimestamps, 'lastModified' => round(microtime(true) * 1000), 'status' => 200, ]; } + + + } diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/OfficesServicesRelationsService.php b/zmscitizenapi/src/Zmscitizenapi/Services/OfficesServicesRelationsService.php index aedf672c8..e1d076292 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Services/OfficesServicesRelationsService.php +++ b/zmscitizenapi/src/Zmscitizenapi/Services/OfficesServicesRelationsService.php @@ -113,13 +113,13 @@ private function getScopeForProvider($sources, $providerId) public function validateServiceLocationCombination($officeId, array $serviceIds) { - // Fetch all available services for the given officeId + + $availableServices = $this->getServicesProvidedAtOffice($officeId); $availableServiceIds = array_map(function ($service) { return $service['id']; }, $availableServices); - // Check if there are any invalid service IDs $invalidServiceIds = array_filter($serviceIds, function ($serviceId) use ($availableServiceIds) { return !in_array($serviceId, $availableServiceIds); }); @@ -143,23 +143,41 @@ public function validateServiceLocationCombination($officeId, array $serviceIds) public function getServicesProvidedAtOffice($officeId) { + // Fetch the request relation list (assuming it's of type RequestRelationList) $sources = \App::$http->readGetResult('/source/' . \App::$source_name . '/', [ 'resolveReferences' => 2, ])->getEntity(); - - $requestList = $sources->getRequestList() ?? []; - $requestRelationList = $sources->getRequestRelationList() ?? []; - - $serviceIds = array_filter($requestRelationList, function ($relation) use ($officeId) { + + $requestRelationList = $sources->getRequestRelationList(); + + // Manually iterate over the RequestRelationList to convert it to an array + $requestRelationArray = []; + foreach ($requestRelationList as $relation) { + $requestRelationArray[] = $relation; + } + + // Now apply array_filter to the array we built + $serviceIds = array_filter($requestRelationArray, function ($relation) use ($officeId) { return $relation->provider->id === $officeId; }); - + $serviceIds = array_map(function ($relation) { return $relation->request->id; }, $serviceIds); - - return array_filter($requestList, function ($request) use ($serviceIds) { + + // Manually iterate over the RequestList to convert it to an array + $requestList = $sources->getRequestList(); + $requestArray = []; + foreach ($requestList as $request) { + $requestArray[] = $request; + } + + // Return the filtered request array + return array_filter($requestArray, function ($request) use ($serviceIds) { return in_array($request->id, $serviceIds); }); } + + + } diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/ProcessService.php b/zmscitizenapi/src/Zmscitizenapi/Services/ProcessService.php index 1ba0b7125..cc330fb4c 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Services/ProcessService.php +++ b/zmscitizenapi/src/Zmscitizenapi/Services/ProcessService.php @@ -104,7 +104,31 @@ public function getFreeTimeslots($providers, $requests, $firstDay, $lastDay) 'providers' => $providers, 'requests' => $requests, ]; - - return $this->httpClient->readPostResult($requestUrl, $dataPayload)->getEntity(); + + // error_log(json_encode($dataPayload)); + + // Fetch the response from the httpClient + $result = $this->httpClient->readPostResult($requestUrl, $dataPayload); + + // Use a method to get the response (replace getResponse() with the actual method if different) + $psr7Response = $result->getResponse(); + + // Fetch the body from the PSR-7 response as a stream, and convert it to a string + $responseBody = (string) $psr7Response->getBody(); + + // Log the full response body for debugging + //error_log("Full response body: " . $responseBody); + + // Convert the body to an associative array if it's JSON + $decodedBody = json_decode($responseBody, true); + + // Return the decoded response body + return $decodedBody; } + + + + + + } diff --git a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php index ec999ccb0..967faf45f 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php @@ -1,6 +1,6 @@ renderJson(method: 'POST'); $this->assertEqualsCanonicalizing([], $responseData); } -} +}*/ diff --git a/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php b/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php index d40e1f28b..da6802ac5 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php @@ -68,7 +68,7 @@ public function testEmptyAppointments() $this->assertEquals('appointmentNotAvailable', $responseBody['errorCode']); $this->assertArrayHasKey('errorMessage', $responseBody); - $this->assertEquals('Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar', $responseBody['errorMessage']); + $this->assertEquals('Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', $responseBody['errorMessage']); $this->assertArrayHasKey('appointmentTimestamps', $responseBody); $this->assertEmpty($responseBody['appointmentTimestamps']); From 26c0230209ba4264a6c70b1748276e809e73ae37 Mon Sep 17 00:00:00 2001 From: Thomas Fink Date: Mon, 23 Sep 2024 15:20:37 +0200 Subject: [PATCH 02/10] fix unit tests --- .../Services/AvailableAppointmentsService.php | 11 +---- .../AvailableAppointmentsListTest.php | 44 ++++++++++--------- .../fixtures/GET_appointments.json | 2 +- 3 files changed, 25 insertions(+), 32 deletions(-) diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php b/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php index 5b74f50ec..cd822a05a 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php +++ b/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php @@ -145,7 +145,6 @@ private function validateQueryParams($date, $officeId, $serviceIds, $serviceCoun private function processFreeSlots($freeSlots) { - // Check if $freeSlots is iterable (array or object that can be traversed) if (empty($freeSlots) || !is_iterable($freeSlots)) { return [ 'appointmentTimestamps' => [], @@ -158,30 +157,22 @@ private function processFreeSlots($freeSlots) $currentTimestamp = time(); $appointmentTimestamps = []; - // Iterate over the slots and process appointments foreach ($freeSlots as $slot) { - //error_log("Processing slot: " . json_encode($slot)); // Debugging - - // Check if the slot has an appointments array and it is iterable + if (!isset($slot->appointments) || !is_iterable($slot->appointments)) { continue; } - // Iterate over appointments and extract the timestamp foreach ($slot->appointments as $appointment) { - //error_log("Processing appointment: " . json_encode($appointment)); // Debugging - if (isset($appointment->date)) { $timestamp = (int)$appointment->date; - // Ensure we only add future timestamps and avoid duplicates if (!in_array($timestamp, $appointmentTimestamps) && $timestamp > $currentTimestamp) { $appointmentTimestamps[] = $timestamp; } } } } - if (empty($appointmentTimestamps)) { return [ 'appointmentTimestamps' => [], diff --git a/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php b/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php index da6802ac5..8c8bf2c07 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php @@ -17,28 +17,30 @@ public function testRendering() ] ] ); - + $parameters = [ - 'date' => '2024-09-21', + 'date' => '3000-09-21', 'officeId' => '10546', 'serviceId' => '1063423', 'serviceCount' => '1', ]; - + $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - - $this->assertEquals(200, $response->getStatusCode()); - - $this->assertArrayHasKey('appointmentTimestamps', $responseBody); - $this->assertNotEmpty($responseBody['appointmentTimestamps']); - $this->assertTrue(is_array($responseBody['appointmentTimestamps'])); - $this->assertTrue(count($responseBody['appointmentTimestamps']) > 0); - $this->assertTrue(is_numeric($responseBody['appointmentTimestamps'][0])); - - $this->assertArrayHasKey('lastModified', $responseBody); - $this->assertTrue(is_numeric($responseBody['lastModified'])); + + $this->assertEquals(200, $response->getStatusCode(), 'Expected a 200 OK response.'); + + $this->assertArrayHasKey('appointmentTimestamps', $responseBody, 'Expected appointmentTimestamps in response.'); + $this->assertNotEmpty($responseBody['appointmentTimestamps'], 'Expected non-empty appointmentTimestamps.'); + $this->assertTrue(is_array($responseBody['appointmentTimestamps']), 'Expected appointmentTimestamps to be an array.'); + + $this->assertTrue(count($responseBody['appointmentTimestamps']) > 0, 'Expected more than 0 timestamps.'); + $this->assertTrue(is_numeric($responseBody['appointmentTimestamps'][0]), 'Expected numeric timestamps.'); + + $this->assertArrayHasKey('lastModified', $responseBody, 'Expected lastModified in response.'); + $this->assertTrue(is_numeric($responseBody['lastModified']), 'Expected lastModified to be a numeric timestamp.'); } + public function testEmptyAppointments() { @@ -53,7 +55,7 @@ public function testEmptyAppointments() ); $parameters = [ - 'date' => '2024-09-21', + 'date' => '3000-09-21', 'officeId' => '10546', 'serviceId' => '1063423', 'serviceCount' => '1', @@ -96,7 +98,7 @@ public function testDateMissing() public function testOfficeIdMissing() { $parameters = [ - 'date' => '2024-09-21', + 'date' => '3000-09-21', 'serviceId' => '1063423', 'serviceCount' => '1', ]; @@ -115,7 +117,7 @@ public function testOfficeIdMissing() public function testServiceIdMissing() { $parameters = [ - 'date' => '2024-09-21', + 'date' => '3000-09-21', 'officeId' => '10546', 'serviceCount' => '1', ]; @@ -134,7 +136,7 @@ public function testServiceIdMissing() public function testServiceCountMissing() { $parameters = [ - 'date' => '2024-09-21', + 'date' => '3000-09-21', 'officeId' => '10546', 'serviceId' => '1063423', ]; @@ -219,7 +221,7 @@ public function testDateAndServiceCountMissing() public function testOfficeIdAndServiceIdMissing() { $parameters = [ - 'date' => '2024-09-21', + 'date' => '3000-09-21', 'serviceCount' => '1', ]; @@ -241,7 +243,7 @@ public function testOfficeIdAndServiceIdMissing() public function testOfficeIdAndServiceCountMissing() { $parameters = [ - 'date' => '2024-09-21', + 'date' => '3000-09-21', 'serviceId' => '1063423', ]; @@ -263,7 +265,7 @@ public function testOfficeIdAndServiceCountMissing() public function testServiceIdAndServiceCountMissing() { $parameters = [ - 'date' => '2024-09-21', + 'date' => '3000-09-21', 'officeId' => '10546', ]; diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_appointments.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_appointments.json index 5de67844b..3d45a1452 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_appointments.json +++ b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_appointments.json @@ -14,7 +14,7 @@ "customTextfield": "", "appointments": [ { - "date": "1726894800", + "date": "32526616522", "scope": { "id": "39", "source": "dldb" From 5248ce3f99f8df46a1c4df4ba078c504e5bb324e Mon Sep 17 00:00:00 2001 From: Thomas Fink Date: Tue, 24 Sep 2024 17:45:28 +0200 Subject: [PATCH 03/10] one working test for post-reserve --- .../Controllers/AppointmentReserve.php | 9 +- .../Services/AvailableAppointmentsService.php | 4 +- .../Zmscitizenapi/Services/ProcessService.php | 74 +- .../Zmscitizenapi/AppointmentReserveTest.php | 51 +- .../fixtures/GET_appointments.json | 4 +- .../fixtures/GET_appointments_free.json | 111 + .../fixtures/GET_free_timeslots.json | 167 ++ .../GET_freeprocesslist_20160527.json | 626 ++++++ .../fixtures/GetFreeProcessList.json | 1990 +++++++++++++++++ .../fixtures/POST_SourceGet_dldb.json | 142 ++ .../fixtures/POST_reserve_timeslot.json | 98 + 11 files changed, 3232 insertions(+), 44 deletions(-) create mode 100644 zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_appointments_free.json create mode 100644 zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_free_timeslots.json create mode 100644 zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_freeprocesslist_20160527.json create mode 100644 zmscitizenapi/tests/Zmscitizenapi/fixtures/GetFreeProcessList.json create mode 100644 zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_SourceGet_dldb.json create mode 100644 zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_reserve_timeslot.json diff --git a/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php b/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php index efadf5062..5e587a582 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php +++ b/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php @@ -49,7 +49,6 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo ], 400); } - // Get the body input $body = $request->getParsedBody(); if (is_null($body)) { return $this->createJsonResponse($response, [ @@ -73,7 +72,7 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo try { // Step 1: Validate the scope for the office and check if captcha is required - $providerScope = $this->scopesService->getScopeByOfficeId($officeId); + $providerScope = $this->scopesService->getScopeByOfficeId($officeId); // we need to mock the scope $captchaRequired = Application::$CAPTCHA_ENABLED === "1" && $providerScope['captchaActivatedRequired'] === "1"; // Step 2: If captcha is required, verify it @@ -94,6 +93,7 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo return $this->createJsonResponse($response, $serviceValidationResult, 400); } + // Step 4: Get available timeslots using the AvailableAppointmentsService $freeAppointments = $this->availableAppointmentsService->getFreeAppointments([ 'officeId' => $officeId, @@ -102,9 +102,6 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo 'date' => $this->utilityHelper->getInternalDateFromTimestamp($timestamp) ]); - //error_log(json_encode($freeAppointments)); - - // **Step 5: Find the matching time slot based on the requested timestamp** $selectedProcess = array_filter($freeAppointments, function ($process) use ($timestamp) { // Ensure 'appointments' is set and is an array before accessing it @@ -127,7 +124,7 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo $selectedProcess = array_values($selectedProcess)[0]; $selectedProcess['clients'] = [ [ - 'email' => 'test@muenchen.de' // Use actual client data here + 'email' => 'test@muenchen.de' ] ]; diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php b/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php index cd822a05a..dd2227673 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php +++ b/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php @@ -158,12 +158,12 @@ private function processFreeSlots($freeSlots) $appointmentTimestamps = []; foreach ($freeSlots as $slot) { - if (!isset($slot->appointments) || !is_iterable($slot->appointments)) { continue; } foreach ($slot->appointments as $appointment) { + if (isset($appointment->date)) { $timestamp = (int)$appointment->date; @@ -173,6 +173,7 @@ private function processFreeSlots($freeSlots) } } } + if (empty($appointmentTimestamps)) { return [ 'appointmentTimestamps' => [], @@ -182,7 +183,6 @@ private function processFreeSlots($freeSlots) ]; } - // Sort the timestamps and return the response sort($appointmentTimestamps); return [ diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/ProcessService.php b/zmscitizenapi/src/Zmscitizenapi/Services/ProcessService.php index cc330fb4c..4a638cdd3 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Services/ProcessService.php +++ b/zmscitizenapi/src/Zmscitizenapi/Services/ProcessService.php @@ -2,6 +2,9 @@ namespace BO\Zmscitizenapi\Services; +use BO\Zmsentities\Calendar as CalendarEntity; +use BO\Zmsentities\Process as ProcessEntity; + class ProcessService { protected $httpClient; @@ -24,7 +27,7 @@ public function getProcessById($processId, $authKey) public function reserveTimeslot($appointmentProcess, $serviceIds, $serviceCounts) { $requests = []; - + foreach ($serviceIds as $index => $serviceId) { $count = intval($serviceCounts[$index]); for ($i = 0; $i < $count; $i++) { @@ -35,10 +38,29 @@ public function reserveTimeslot($appointmentProcess, $serviceIds, $serviceCounts } } - $appointmentProcess['requests'] = $requests; + $processEntity = new ProcessEntity(); + + $processEntity->appointments = $appointmentProcess['appointments'] ?? []; + $processEntity->authKey = $appointmentProcess['authKey'] ?? null; + $processEntity->clients = $appointmentProcess['clients'] ?? []; + + $processEntity->scope = $appointmentProcess['scope'] ?? null; + $processEntity->requests = $requests; + $processEntity->lastChange = $appointmentProcess['lastChange'] ?? time(); + - return $this->httpClient->readPostResult('/process/status/reserved/', $appointmentProcess)->getEntity(); + $processEntity->createIP = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1'; + $processEntity->createTimestamp = time(); + + if (isset($appointmentProcess['queue'])) { + $processEntity->queue = $appointmentProcess['queue']; + } + + $result = $this->httpClient->readPostResult('/process/status/reserved/', $processEntity); + + return $result->getEntity(); } + public function submitClientData($process) { @@ -104,31 +126,27 @@ public function getFreeTimeslots($providers, $requests, $firstDay, $lastDay) 'providers' => $providers, 'requests' => $requests, ]; - - // error_log(json_encode($dataPayload)); - - // Fetch the response from the httpClient - $result = $this->httpClient->readPostResult($requestUrl, $dataPayload); - - // Use a method to get the response (replace getResponse() with the actual method if different) + + $calendar = new CalendarEntity(); + $calendar->firstDay = $firstDay; + $calendar->lastDay = $lastDay; + $calendar->providers = $providers; + $calendar->requests = $requests; + + + $result = \App::$http->readPostResult('/process/status/free/', $calendar); + if (!$result || !method_exists($result, 'getCollection')) { + throw new \Exception('Invalid response from API'); + } + $psr7Response = $result->getResponse(); - - // Fetch the body from the PSR-7 response as a stream, and convert it to a string - $responseBody = (string) $psr7Response->getBody(); - - // Log the full response body for debugging - //error_log("Full response body: " . $responseBody); - - // Convert the body to an associative array if it's JSON - $decodedBody = json_decode($responseBody, true); - - // Return the decoded response body - return $decodedBody; + $responseBody = (string) $psr7Response->getBody(); + + return json_decode($responseBody, true); } - - - - - - + + + + + } diff --git a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php index 967faf45f..0947f961e 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php @@ -1,14 +1,53 @@ renderJson(method: 'POST'); - $this->assertEqualsCanonicalizing([], $responseData); + public function testRendering() + { + $this->setApiCalls( + [ + [ + 'function' => 'readGetResult', + 'url' => '/source/unittest/', + 'parameters' => [ + 'resolveReferences' => 2, + ], + 'response' => $this->readFixture("POST_SourceGet_dldb.json"), + ], + [ + 'function' => 'readPostResult', + 'url' => '/process/status/free/', + 'response' => $this->readFixture("GET_appointments_free.json") + ], + [ + 'function' => 'readPostResult', + 'url' => '/process/status/reserved/', + 'response' => $this->readFixture("POST_reserve_timeslot.json") + ] + ] + ); + + $parameters = [ + 'officeId' => '10546', + 'serviceId' => ['1063423'], + 'serviceCount' => [1], + 'timestamp' => "32526616522", + 'captchaSolution' => null + ]; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string)$response->getBody(), true); + + $this->assertEquals(200, $response->getStatusCode(), 'Expected a 200 OK response.'); + $this->assertArrayHasKey('reservedProcess', $responseBody, 'Expected reservedProcess in response.'); + $this->assertArrayHasKey('officeId', $responseBody, 'Expected officeId in response.'); + $this->assertEquals('10546', $responseBody['officeId'], 'Expected correct officeId.'); + $this->assertEquals('test@muenchen.de', $responseBody['reservedProcess']['email'], 'Expected test@muenchen.de email.'); } -}*/ +} diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_appointments.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_appointments.json index 3d45a1452..322b9e35d 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_appointments.json +++ b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_appointments.json @@ -16,7 +16,7 @@ { "date": "32526616522", "scope": { - "id": "39", + "id": "58", "source": "dldb" }, "availability": { @@ -76,7 +76,7 @@ }, "reminderTimestamp": 0, "scope": { - "id": "39", + "id": "58", "source": "dldb", "contact": { "name": "Gewerbeamt (KVR-III\/21)", diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_appointments_free.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_appointments_free.json new file mode 100644 index 000000000..322b9e35d --- /dev/null +++ b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_appointments_free.json @@ -0,0 +1,111 @@ +{ + "$schema": "https://localhost/terminvereinbarung/api/2/", + "meta": { + "$schema": "https://schema.berlin.de/queuemanagement/metaresult.json", + "error": false, + "exception": null, + "generated": "2024-08-29T13:55:41+02:00", + "server": "Zmsapi-ENV" + }, + "data": { + "0": { + "$schema": "https:\/\/schema.berlin.de\/queuemanagement\/process.json", + "amendment": "", + "customTextfield": "", + "appointments": [ + { + "date": "32526616522", + "scope": { + "id": "58", + "source": "dldb" + }, + "availability": { + "id": 0, + "weekday": { + "sunday": 0, + "monday": 0, + "tuesday": 0, + "wednesday": 0, + "thursday": 0, + "friday": 0, + "saturday": 0 + }, + "repeat": { + "afterWeeks": 1, + "weekOfMonth": 0 + }, + "bookable": { + "startInDays": 1, + "endInDays": 60 + }, + "workstationCount": { + "public": 0, + "callcenter": 0, + "intern": 0 + }, + "lastChange": 0, + "multipleSlotsAllowed": true, + "slotTimeInMinutes": 10, + "startDate": 0, + "endDate": 0, + "startTime": "0:00", + "endTime": "23:59", + "type": "appointment" + }, + "slotCount": "4" + } + ], + "apiclient": { + "shortname": "default" + }, + "authKey": "", + "createIP": "", + "createTimestamp": 1725635464, + "id": 0, + "archiveId": 0, + "queue": { + "$schema": "https:\/\/schema.berlin.de\/queuemanagement\/queue.json", + "arrivalTime": 0, + "callCount": 0, + "callTime": 0, + "number": 0, + "waitingTimeEstimate": 0, + "waitingTimeOptimistic": 0, + "waitingTime": 0, + "wayTime": 0 + }, + "reminderTimestamp": 0, + "scope": { + "id": "58", + "source": "dldb", + "contact": { + "name": "Gewerbeamt (KVR-III\/21)", + "street": "Implerstra\u00dfe 11", + "email": "", + "country": "Germany" + }, + "provider": { + "id": "10546", + "source": "dldb", + "contact": { + "city": "Muenchen", + "country": "Germany", + "name": "Gewerbeamt (KVR-III\/21)", + "postalCode": "81371", + "region": "Muenchen", + "street": "Implerstra\u00dfe", + "streetNumber": "11" + }, + "link": "https:\/\/service.berlin.de\/standort\/10546\/", + "name": "Gewerbeamt (KVR-III\/21)", + "displayName": "Gewerbeamt" + }, + "hint": "", + "lastChange": 1724883487, + "shortName": "" + }, + "status": "free", + "lastChange": 1725635464 + } + } +} \ No newline at end of file diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_free_timeslots.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_free_timeslots.json new file mode 100644 index 000000000..07bc979b4 --- /dev/null +++ b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_free_timeslots.json @@ -0,0 +1,167 @@ +{ + "$schema": "https://localhost/terminvereinbarung/api/2/", + "meta": { + "$schema": "https://schema.berlin.de/queuemanagement/metaresult.json", + "error": false, + "generated": "2019-02-08T14:45:15+01:00", + "server": "Zmsapi-ENV (v2.19.02-38-g0ba2cba)" + }, + "data": { + "amendment": "", + "appointmentTimestamps": [ + 1727241600, + 1727241900, + 1727242200, + 1727242500, + 1727242800, + 1727243100, + 1727243400, + 1727243700, + 1727244000, + 1727244300, + 1727244600, + 1727244900, + 1727245200, + 1727245500, + 1727245800, + 1727246100, + 1727246400, + 1727246700, + 1727247000, + 1727247300, + 1727247600, + 1727247900, + 1727248200, + 1727248500, + 1727248800, + 1727249100, + 1727249400, + 1727249700, + 1727250000, + 1727250300, + 1727250600, + 1727250900, + 1727251200, + 1727251500, + 1727251800, + 1727252100, + 1727252400, + 1727252700, + 1727253000, + 1727253300, + 1727253600, + 1727253900, + 1727254200, + 1727254500, + 1727254800, + 1727255100, + 1727255400, + 1727255700, + 1727256000, + 1727256300, + 1727256600, + 1727256900, + 1727257200, + 1727257500, + 1727257800, + 1727258100, + 1727258400, + 1727258700, + 1727259000, + 1727259300, + 1727259600, + 1727259900, + 1727260200, + 1727260500, + 1727260800, + 1727261100, + 1727261400, + 1727261700, + 1727262000, + 1727262300, + 1727262600, + 1727262900, + 1727263200, + 1727263500, + 1727263800, + 1727264100, + 1727264400, + 1727264700, + 1727265000, + 1727265300, + 1727265600, + 1727265900, + 1727266200, + 1727266500, + 1727266800, + 1727267100, + 1727267400, + 1727267700, + 1727268000, + 1727268300, + 1727268600, + 1727268900, + 1727269200, + 1727269500, + 1727269800, + 1727270100, + 1727270400, + 1727270700, + 1727271000, + 1727271300, + 1727271600, + 1727271900, + 1727272200, + 1727272500, + 1727272800, + 1727273100, + 1727273400, + 1727273700, + 1727274000, + 1727274300, + 1727274600, + 1727274900, + 1727275200, + 1727275500, + 1727275800, + 1727276100, + 1727276400, + 1727276700, + 1727277000, + 1727277300, + 1727277600, + 1727277900, + 1727278200, + 1727278500, + 1727278800, + 1727279100, + 1727279400, + 1727279700, + 1727280000, + 1727280300, + 1727280600, + 1727280900, + 1727281200, + 1727281500, + 1727281800, + 1727282100, + 1727282400, + 1727282700, + 1727283000, + 1727283300, + 1727283600, + 1727283900, + 1727284200, + 1727284500, + 1727284800, + 1727285100, + 1727285400, + 1727285700, + 1727286000, + 1727286300, + 32526616522 + ], + "lastModified": 1727162779840, + "status": 200 + } +} \ No newline at end of file diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_freeprocesslist_20160527.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_freeprocesslist_20160527.json new file mode 100644 index 000000000..7e5bc8909 --- /dev/null +++ b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_freeprocesslist_20160527.json @@ -0,0 +1,626 @@ +{ + "$schema": "https://localhost/terminvereinbarung/api/2/", + "meta": { + "$schema": "https://schema.berlin.de/queuemanagement/metaresult.json", + "error": false, + "exception": null, + "generated": "2016-09-13T13:55:41+02:00", + "server": "Zmsapi-ENV" + }, + "data": { + "0": { + "$schema": "https://schema.berlin.de/queuemanagement/process.json", + "amendment": "", + "appointments": [{ + "$schema": "https://schema.berlin.de/queuemanagement/appointment.json", + "scope": { + "$schema": "https://schema.berlin.de/queuemanagement/scope.json", + "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", + "id": "141", + "contact": { + "name": "Bürgeramt Heerstraße", + "street": "Heerstr. 12, 14052 Berlin", + "email": "", + "country": "Germany" + }, + "preferences": { + "appointment": { + "deallocationDuration": "10", + "infoForAppointment": "", + "endInDaysDefault": "60", + "multipleSlotsEnabled": "0", + "reservationDuration": "20", + "startInDaysDefault": "0" + }, + "client": { + "alternateAppointmentUrl": "", + "amendmentActivated": "0", + "amendmentLabel": "", + "emailRequired": "0", + "adminMailOnAppointment": "0", + "adminMailOnDeleted": "0", + "telephoneActivated": "0", + "telephoneRequired": "0" + }, + "notifications": { + "confirmationContent": "", + "enabled": "1", + "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", + "headsUpTime": "30" + }, + "pickup": { + "alternateName": "Ausgabe", + "isDefault": "0" + }, + "queue": { + "callCountMax": "0", + "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", + "firstNumber": "1", + "lastNumber": "499", + "processingTimeAverage": "15", + "publishWaitingTimeEnabled": "1", + "statisticsEnabled": "1" + }, + "survey": { + "emailContent": "", + "enabled": "0", + "label": "" + }, + "ticketprinter": { + "confirmationEnabled": "0", + "deactivatedText": "", + "notificationsAmendmentEnabled": "0", + "notificationsDelay": "0" + }, + "workstation": { + "emergencyEnabled": "1" + } + }, + "shortName": "", + "status": { + "emergency": { + "acceptedByWorkstation": "-1", + "activated": "0", + "calledByWorkstation": "-1" + }, + "queue": { + "ghostWorkstationCount": "-1", + "givenNumberCount": "46", + "lastGivenNumber": "47", + "lastGivenNumberTimestamp": "1447925159" + }, + "ticketprinter": { + "deactivated": "0" + } + }, + "provider": { + "id": "122217", + "contact": { + "email": "test@example.com", + "city": "Berlin", + "country": "Germany", + "name": "Bürgeramt Heerstraße", + "postalCode": "14052", + "region": "Berlin", + "street": "Heerstr.", + "streetNumber": "12" + }, + "source": "dldb", + "link": "https://service.berlin.de/standort/122217/", + "name": "Bürgeramt Heerstraße" + }, + "department": { + "id": "74", + "contact": { + "city": "Berlin", + "street": "Otto-Suhr-Allee 100, 10585 Berlin", + "country": "Germany", + "name": "" + }, + "email": "test@example.com", + "name": "Bürgeramt", + "preferences": { + "notifications": { + "enabled": null, + "identification": null, + "sendConfirmationEnabled": null, + "sendReminderEnabled": null + } + } + } + }, + "availability": { + "$schema": "https://schema.berlin.de/queuemanagement/availability.json", + "id": "94678", + "weekday": { + "monday": "0", + "tuesday": "0", + "wednesday": "0", + "thursday": "0", + "friday": "32", + "saturday": "0", + "sunday": "0" + }, + "repeat": { + "afterWeeks": "1", + "weekOfMonth": "0" + }, + "bookable": { + "startInDays": "0", + "endInDays": "60" + }, + "workstationCount": { + "public": "2", + "callcenter": "2", + "intern": "2" + }, + "multipleSlotsAllowed": "0", + "slotTimeInMinutes": "10", + "startDate": "1463954400", + "endDate": "1609365600", + "startTime": "08:00:00", + "endTime": "13:50:00", + "department": { + "id": "74", + "contact": { + "city": "Berlin", + "street": "Otto-Suhr-Allee 100, 10585 Berlin", + "country": "Germany", + "name": "" + }, + "email": "test@example.com", + "name": "Bürgeramt", + "preferences": { + "notifications": { + "enabled": null, + "identification": null, + "sendConfirmationEnabled": null, + "sendReminderEnabled": null + } + } + } + }, + "slotCount": 1, + "date": "1464340800" + }], + "authKey": "", + "clients": [], + "createIP": "", + "createTimestamp": "", + "id": 0, + "queue": [], + "reminderTimestamp": 0, + "requests": [{ + "$schema": "https://schema.berlin.de/queuemanagement/request.json", + "id": "120703", + "link": "https://service.berlin.de/dienstleistung/120703/", + "name": "Personalausweis beantragen", + "source": "dldb" + }], + "scope": { + "$schema": "https://schema.berlin.de/queuemanagement/scope.json", + "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", + "id": "141", + "contact": { + "name": "Bürgeramt Heerstraße", + "street": "Heerstr. 12, 14052 Berlin", + "email": "", + "country": "Germany" + }, + "preferences": { + "appointment": { + "deallocationDuration": "10", + "infoForAppointment": "", + "endInDaysDefault": "60", + "multipleSlotsEnabled": "0", + "reservationDuration": "20", + "startInDaysDefault": "0" + }, + "client": { + "alternateAppointmentUrl": "", + "amendmentActivated": "0", + "amendmentLabel": "", + "emailRequired": "0", + "adminMailOnAppointment": "0", + "adminMailOnDeleted": "0", + "telephoneActivated": "0", + "telephoneRequired": "0" + }, + "notifications": { + "confirmationContent": "", + "enabled": "1", + "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", + "headsUpTime": "30" + }, + "pickup": { + "alternateName": "Ausgabe", + "isDefault": "0" + }, + "queue": { + "callCountMax": "0", + "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", + "firstNumber": "1", + "lastNumber": "499", + "processingTimeAverage": "15", + "publishWaitingTimeEnabled": "1", + "statisticsEnabled": "1" + }, + "survey": { + "emailContent": "", + "enabled": "0", + "label": "" + }, + "ticketprinter": { + "confirmationEnabled": "0", + "deactivatedText": "", + "notificationsAmendmentEnabled": "0", + "notificationsDelay": "0" + }, + "workstation": { + "emergencyEnabled": "1" + } + }, + "shortName": "", + "status": { + "emergency": { + "acceptedByWorkstation": "-1", + "activated": "0", + "calledByWorkstation": "-1" + }, + "queue": { + "ghostWorkstationCount": "-1", + "givenNumberCount": "46", + "lastGivenNumber": "47", + "lastGivenNumberTimestamp": "1447925159" + }, + "ticketprinter": { + "deactivated": "0" + } + }, + "provider": { + "id": "122217", + "contact": { + "email": "test@example.com", + "city": "Berlin", + "country": "Germany", + "name": "Bürgeramt Heerstraße", + "postalCode": "14052", + "region": "Berlin", + "street": "Heerstr.", + "streetNumber": "12" + }, + "source": "dldb", + "link": "https://service.berlin.de/standort/122217/", + "name": "Bürgeramt Heerstraße" + }, + "department": { + "id": "74", + "contact": { + "city": "Berlin", + "street": "Otto-Suhr-Allee 100, 10585 Berlin", + "country": "Germany", + "name": "" + }, + "email": "test@example.com", + "name": "Bürgeramt", + "preferences": { + "notifications": { + "enabled": null, + "identification": null, + "sendConfirmationEnabled": null, + "sendReminderEnabled": null + } + } + } + }, + "status": "" + }, + "1": { + "$schema": "https://schema.berlin.de/queuemanagement/process.json", + "amendment": "", + "appointments": [{ + "$schema": "https://schema.berlin.de/queuemanagement/appointment.json", + "scope": { + "$schema": "https://schema.berlin.de/queuemanagement/scope.json", + "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", + "id": "141", + "contact": { + "name": "Bürgeramt Heerstraße", + "street": "Heerstr. 12, 14052 Berlin", + "email": "", + "country": "Germany" + }, + "preferences": { + "appointment": { + "deallocationDuration": "10", + "infoForAppointment": "", + "endInDaysDefault": "60", + "multipleSlotsEnabled": "0", + "reservationDuration": "20", + "startInDaysDefault": "0" + }, + "client": { + "alternateAppointmentUrl": "", + "amendmentActivated": "0", + "amendmentLabel": "", + "emailRequired": "0", + "adminMailOnAppointment": "0", + "adminMailOnDeleted": "0", + "telephoneActivated": "0", + "telephoneRequired": "0" + }, + "notifications": { + "confirmationContent": "", + "enabled": "1", + "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", + "headsUpTime": "30" + }, + "pickup": { + "alternateName": "Ausgabe", + "isDefault": "0" + }, + "queue": { + "callCountMax": "0", + "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", + "firstNumber": "1", + "lastNumber": "499", + "processingTimeAverage": "15", + "publishWaitingTimeEnabled": "1", + "statisticsEnabled": "1" + }, + "survey": { + "emailContent": "", + "enabled": "0", + "label": "" + }, + "ticketprinter": { + "confirmationEnabled": "0", + "deactivatedText": "", + "notificationsAmendmentEnabled": "0", + "notificationsDelay": "0" + }, + "workstation": { + "emergencyEnabled": "1" + } + }, + "shortName": "", + "status": { + "emergency": { + "acceptedByWorkstation": "-1", + "activated": "0", + "calledByWorkstation": "-1" + }, + "queue": { + "ghostWorkstationCount": "-1", + "givenNumberCount": "46", + "lastGivenNumber": "47", + "lastGivenNumberTimestamp": "1447925159" + }, + "ticketprinter": { + "deactivated": "0" + } + }, + "provider": { + "id": "122217", + "contact": { + "email": "test@example.com", + "city": "Berlin", + "country": "Germany", + "name": "Bürgeramt Heerstraße", + "postalCode": "14052", + "region": "Berlin", + "street": "Heerstr.", + "streetNumber": "12" + }, + "source": "dldb", + "link": "https://service.berlin.de/standort/122217/", + "name": "Bürgeramt Heerstraße" + }, + "department": { + "id": "74", + "contact": { + "city": "Berlin", + "street": "Otto-Suhr-Allee 100, 10585 Berlin", + "country": "Germany", + "name": "" + }, + "email": "test@example.com", + "name": "Bürgeramt", + "preferences": { + "notifications": { + "enabled": null, + "identification": null, + "sendConfirmationEnabled": null, + "sendReminderEnabled": null + } + } + } + }, + "availability": { + "$schema": "https://schema.berlin.de/queuemanagement/availability.json", + "id": "94678", + "weekday": { + "monday": "0", + "tuesday": "0", + "wednesday": "0", + "thursday": "0", + "friday": "32", + "saturday": "0", + "sunday": "0" + }, + "repeat": { + "afterWeeks": "1", + "weekOfMonth": "0" + }, + "bookable": { + "startInDays": "0", + "endInDays": "60" + }, + "workstationCount": { + "public": "2", + "callcenter": "2", + "intern": "2" + }, + "multipleSlotsAllowed": "0", + "slotTimeInMinutes": "10", + "startDate": "1463954400", + "endDate": "1609365600", + "startTime": "08:00:00", + "endTime": "13:50:00", + "department": { + "id": "74", + "contact": { + "city": "Berlin", + "street": "Otto-Suhr-Allee 100, 10585 Berlin", + "country": "Germany", + "name": "" + }, + "email": "test@example.com", + "name": "Bürgeramt", + "preferences": { + "notifications": { + "enabled": null, + "identification": null, + "sendConfirmationEnabled": null, + "sendReminderEnabled": null + } + } + } + }, + "slotCount": 1, + "date": "1464342000" + }], + "authKey": "", + "clients": [], + "createIP": "", + "createTimestamp": "", + "id": 0, + "queue": [], + "reminderTimestamp": 0, + "requests": [{ + "$schema": "https://schema.berlin.de/queuemanagement/request.json", + "id": "120703", + "link": "https://service.berlin.de/dienstleistung/120703/", + "name": "Personalausweis beantragen", + "source": "dldb" + }], + "scope": { + "$schema": "https://schema.berlin.de/queuemanagement/scope.json", + "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", + "id": "141", + "contact": { + "name": "Bürgeramt Heerstraße", + "street": "Heerstr. 12, 14052 Berlin", + "email": "", + "country": "Germany" + }, + "preferences": { + "appointment": { + "deallocationDuration": "10", + "infoForAppointment": "", + "endInDaysDefault": "60", + "multipleSlotsEnabled": "0", + "reservationDuration": "20", + "startInDaysDefault": "0" + }, + "client": { + "alternateAppointmentUrl": "", + "amendmentActivated": "0", + "amendmentLabel": "", + "emailRequired": "0", + "adminMailOnAppointment": "0", + "adminMailOnDeleted": "0", + "telephoneActivated": "0", + "telephoneRequired": "0" + }, + "notifications": { + "confirmationContent": "", + "enabled": "1", + "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", + "headsUpTime": "30" + }, + "pickup": { + "alternateName": "Ausgabe", + "isDefault": "0" + }, + "queue": { + "callCountMax": "0", + "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", + "firstNumber": "1", + "lastNumber": "499", + "processingTimeAverage": "15", + "publishWaitingTimeEnabled": "1", + "statisticsEnabled": "1" + }, + "survey": { + "emailContent": "", + "enabled": "0", + "label": "" + }, + "ticketprinter": { + "confirmationEnabled": "0", + "deactivatedText": "", + "notificationsAmendmentEnabled": "0", + "notificationsDelay": "0" + }, + "workstation": { + "emergencyEnabled": "1" + } + }, + "shortName": "", + "status": { + "emergency": { + "acceptedByWorkstation": "-1", + "activated": "0", + "calledByWorkstation": "-1" + }, + "queue": { + "ghostWorkstationCount": "-1", + "givenNumberCount": "46", + "lastGivenNumber": "47", + "lastGivenNumberTimestamp": "1447925159" + }, + "ticketprinter": { + "deactivated": "0" + } + }, + "provider": { + "id": "122217", + "contact": { + "email": "test@example.com", + "city": "Berlin", + "country": "Germany", + "name": "Bürgeramt Heerstraße", + "postalCode": "14052", + "region": "Berlin", + "street": "Heerstr.", + "streetNumber": "12" + }, + "source": "dldb", + "link": "https://service.berlin.de/standort/122217/", + "name": "Bürgeramt Heerstraße" + }, + "department": { + "id": "74", + "contact": { + "city": "Berlin", + "street": "Otto-Suhr-Allee 100, 10585 Berlin", + "country": "Germany", + "name": "" + }, + "email": "test@example.com", + "name": "Bürgeramt", + "preferences": { + "notifications": { + "enabled": null, + "identification": null, + "sendConfirmationEnabled": null, + "sendReminderEnabled": null + } + } + } + }, + "status": "" + } + } +} diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GetFreeProcessList.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GetFreeProcessList.json new file mode 100644 index 000000000..e0ac3443a --- /dev/null +++ b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GetFreeProcessList.json @@ -0,0 +1,1990 @@ +{ + "0": { + "$schema": "https://schema.berlin.de/queuemanagement/process.json", + "amendment": "", + "appointments": [ + { + "scope": { + "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", + "id": "141", + "contact": { + "name": "Bürgeramt Heerstraße", + "street": "Heerstr. 12, 14052 Berlin", + "email": "", + "country": "Germany" + }, + "preferences": { + "appointment": { + "deallocationDuration": "10", + "infoForAppointment": "", + "endInDaysDefault": "60", + "multipleSlotsEnabled": "0", + "reservationDuration": "20", + "startInDaysDefault": "0" + }, + "client": { + "alternateAppointmentUrl": "", + "amendmentActivated": "0", + "amendmentLabel": "", + "emailRequired": "0", + "telephoneActivated": "0", + "telephoneRequired": "0" + }, + "notifications": { + "confirmationContent": "", + "enabled": "1", + "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", + "headsUpTime": "30" + }, + "pickup": { + "alternateName": "Ausgabe", + "isDefault": "0" + }, + "queue": { + "callCountMax": "0", + "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", + "firstNumber": "1", + "lastNumber": "499", + "processingTimeAverage": "15", + "publishWaitingTimeEnabled": "1", + "statisticsEnabled": "1" + }, + "survey": { + "emailContent": "", + "enabled": "0", + "label": "" + }, + "ticketprinter": { + "confirmationEnabled": "0", + "deactivatedText": "", + "notificationsAmendmentEnabled": "0", + "notificationsDelay": "0" + }, + "workstation": { + "emergencyEnabled": "1" + } + }, + "shortName": "", + "status": { + "emergency": { + "acceptedByWorkstation": "-1", + "activated": "0", + "calledByWorkstation": "-1" + }, + "queue": { + "ghostWorkstationCount": "-1", + "givenNumberCount": "46", + "lastGivenNumber": "47", + "lastGivenNumberTimestamp": "1458774000" + }, + "ticketprinter": { + "deactivated": "0" + } + }, + "provider": { + "id": "122217", + "contact": { + "email": "test@example.com", + "city": "Berlin", + "country": "Germany", + "name": "Bürgeramt Heerstraße", + "postalCode": "14052", + "region": "Berlin", + "street": "Heerstr.", + "streetNumber": "12" + }, + "source": "dldb", + "link": "https://service.berlin.de/standort/122217/", + "name": "Bürgeramt Heerstraße", + "displayName":"001" + }, + "dayoff": [ + { + "date": "1458860400", + "name": "Karfreitag" + }, + { + "date": "1459116000", + "name": "Ostermontag" + }, + { + "date": "1462053600", + "name": "Maifeiertag" + }, + { + "date": "1462399200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1463349600", + "name": "Pfingstmontag" + }, + { + "date": "1475445600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1482620400", + "name": "1. Weihnachtstag" + }, + { + "date": "1482706800", + "name": "2. Weihnachtstag" + }, + { + "date": "1483225200", + "name": "Neujahr" + }, + { + "date": "1492120800", + "name": "Karfreitag" + }, + { + "date": "1492380000", + "name": "Ostermontag" + }, + { + "date": "1493589600", + "name": "Maifeiertag" + }, + { + "date": "1495663200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1496613600", + "name": "Pfingstmontag" + }, + { + "date": "1506981600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1514156400", + "name": "1. Weihnachtstag" + }, + { + "date": "1514242800", + "name": "2. Weihnachtstag" + }, + { + "date": "1514761200", + "name": "Neujahr" + }, + { + "date": "1522360800", + "name": "Karfreitag" + }, + { + "date": "1522620000", + "name": "Ostermontag" + }, + { + "date": "1525125600", + "name": "Maifeiertag" + }, + { + "date": "1525903200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1526853600", + "name": "Pfingstmontag" + }, + { + "date": "1538517600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1545692400", + "name": "1. Weihnachtstag" + }, + { + "date": "1545778800", + "name": "2. Weihnachtstag" + }, + { + "date": "1546297200", + "name": "Neujahr" + }, + { + "date": "1555624800", + "name": "Karfreitag" + }, + { + "date": "1555884000", + "name": "Ostermontag" + }, + { + "date": "1556661600", + "name": "Maifeiertag" + }, + { + "date": "1559167200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1560117600", + "name": "Pfingstmontag" + }, + { + "date": "1570053600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1577228400", + "name": "1. Weihnachtstag" + }, + { + "date": "1577314800", + "name": "2. Weihnachtstag" + }, + { + "date": "1577833200", + "name": "Neujahr" + }, + { + "date": "1586469600", + "name": "Karfreitag" + }, + { + "date": "1586728800", + "name": "Ostermontag" + }, + { + "date": "1588284000", + "name": "Maifeiertag" + }, + { + "date": "1590012000", + "name": "Christi Himmelfahrt" + }, + { + "date": "1590962400", + "name": "Pfingstmontag" + }, + { + "date": "1601676000", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1608850800", + "name": "1. Weihnachtstag" + }, + { + "date": "1608937200", + "name": "2. Weihnachtstag" + }, + { + "date": "1609455600", + "name": "Neujahr" + }, + { + "date": "1617314400", + "name": "Karfreitag" + }, + { + "date": "1617573600", + "name": "Ostermontag" + }, + { + "date": "1619820000", + "name": "Maifeiertag" + }, + { + "date": "1620856800", + "name": "Christi Himmelfahrt" + }, + { + "date": "1621807200", + "name": "Pfingstmontag" + }, + { + "date": "1633212000", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1640386800", + "name": "1. Weihnachtstag" + }, + { + "date": "1640473200", + "name": "2. Weihnachtstag" + }, + { + "date": "1478041200", + "name": "Personalversammlung" + } + ] + }, + "availability": { + "id": "94678", + "weekday": { + "monday": "0", + "tuesday": "0", + "wednesday": "0", + "thursday": "0", + "friday": "32", + "saturday": "0", + "sunday": "0" + }, + "repeat": { + "afterWeeks": "1", + "weekOfMonth": "0" + }, + "bookable": { + "startInDays": "0", + "endInDays": "60" + }, + "workstationCount": { + "public": "2", + "callcenter": "2", + "intern": "2" + }, + "multipleSlotsAllowed": "0", + "slotTimeInMinutes": "10", + "startDate": "1463954400", + "endDate": "1609369200", + "startTime": "08:00:00", + "endTime": "13:50:00", + "type": "appointment", + "scope": { + "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", + "id": "141", + "contact": { + "name": "Bürgeramt Heerstraße", + "street": "Heerstr. 12, 14052 Berlin", + "email": "", + "country": "Germany" + }, + "preferences": { + "appointment": { + "deallocationDuration": "10", + "infoForAppointment": "", + "endInDaysDefault": "60", + "multipleSlotsEnabled": "0", + "reservationDuration": "20", + "startInDaysDefault": "0" + }, + "client": { + "alternateAppointmentUrl": "", + "amendmentActivated": "0", + "amendmentLabel": "", + "emailRequired": "0", + "telephoneActivated": "0", + "telephoneRequired": "0" + }, + "notifications": { + "confirmationContent": "", + "enabled": "1", + "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", + "headsUpTime": "30" + }, + "pickup": { + "alternateName": "Ausgabe", + "isDefault": "0" + }, + "queue": { + "callCountMax": "0", + "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", + "firstNumber": "1", + "lastNumber": "499", + "processingTimeAverage": "15", + "publishWaitingTimeEnabled": "1", + "statisticsEnabled": "1" + }, + "survey": { + "emailContent": "", + "enabled": "0", + "label": "" + }, + "ticketprinter": { + "confirmationEnabled": "0", + "deactivatedText": "", + "notificationsAmendmentEnabled": "0", + "notificationsDelay": "0" + }, + "workstation": { + "emergencyEnabled": "1" + } + }, + "shortName": "", + "status": { + "emergency": { + "acceptedByWorkstation": "-1", + "activated": "0", + "calledByWorkstation": "-1" + }, + "queue": { + "ghostWorkstationCount": "-1", + "givenNumberCount": "46", + "lastGivenNumber": "47", + "lastGivenNumberTimestamp": "1458774000" + }, + "ticketprinter": { + "deactivated": "0" + } + }, + "provider": { + "id": "122217", + "contact": { + "email": "test@example.com", + "city": "Berlin", + "country": "Germany", + "name": "Bürgeramt Heerstraße", + "postalCode": "14052", + "region": "Berlin", + "street": "Heerstr.", + "streetNumber": "12" + }, + "source": "dldb", + "link": "https://service.berlin.de/standort/122217/", + "name": "Bürgeramt Heerstraße", + "displayName":"001" + }, + "dayoff": [ + { + "date": "1458860400", + "name": "Karfreitag" + }, + { + "date": "1459116000", + "name": "Ostermontag" + }, + { + "date": "1462053600", + "name": "Maifeiertag" + }, + { + "date": "1462399200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1463349600", + "name": "Pfingstmontag" + }, + { + "date": "1475445600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1482620400", + "name": "1. Weihnachtstag" + }, + { + "date": "1482706800", + "name": "2. Weihnachtstag" + }, + { + "date": "1483225200", + "name": "Neujahr" + }, + { + "date": "1492120800", + "name": "Karfreitag" + }, + { + "date": "1492380000", + "name": "Ostermontag" + }, + { + "date": "1493589600", + "name": "Maifeiertag" + }, + { + "date": "1495663200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1496613600", + "name": "Pfingstmontag" + }, + { + "date": "1506981600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1514156400", + "name": "1. Weihnachtstag" + }, + { + "date": "1514242800", + "name": "2. Weihnachtstag" + }, + { + "date": "1514761200", + "name": "Neujahr" + }, + { + "date": "1522360800", + "name": "Karfreitag" + }, + { + "date": "1522620000", + "name": "Ostermontag" + }, + { + "date": "1525125600", + "name": "Maifeiertag" + }, + { + "date": "1525903200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1526853600", + "name": "Pfingstmontag" + }, + { + "date": "1538517600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1545692400", + "name": "1. Weihnachtstag" + }, + { + "date": "1545778800", + "name": "2. Weihnachtstag" + }, + { + "date": "1546297200", + "name": "Neujahr" + }, + { + "date": "1555624800", + "name": "Karfreitag" + }, + { + "date": "1555884000", + "name": "Ostermontag" + }, + { + "date": "1556661600", + "name": "Maifeiertag" + }, + { + "date": "1559167200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1560117600", + "name": "Pfingstmontag" + }, + { + "date": "1570053600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1577228400", + "name": "1. Weihnachtstag" + }, + { + "date": "1577314800", + "name": "2. Weihnachtstag" + }, + { + "date": "1577833200", + "name": "Neujahr" + }, + { + "date": "1586469600", + "name": "Karfreitag" + }, + { + "date": "1586728800", + "name": "Ostermontag" + }, + { + "date": "1588284000", + "name": "Maifeiertag" + }, + { + "date": "1590012000", + "name": "Christi Himmelfahrt" + }, + { + "date": "1590962400", + "name": "Pfingstmontag" + }, + { + "date": "1601676000", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1608850800", + "name": "1. Weihnachtstag" + }, + { + "date": "1608937200", + "name": "2. Weihnachtstag" + }, + { + "date": "1609455600", + "name": "Neujahr" + }, + { + "date": "1617314400", + "name": "Karfreitag" + }, + { + "date": "1617573600", + "name": "Ostermontag" + }, + { + "date": "1619820000", + "name": "Maifeiertag" + }, + { + "date": "1620856800", + "name": "Christi Himmelfahrt" + }, + { + "date": "1621807200", + "name": "Pfingstmontag" + }, + { + "date": "1633212000", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1640386800", + "name": "1. Weihnachtstag" + }, + { + "date": "1640473200", + "name": "2. Weihnachtstag" + }, + { + "date": "1478041200", + "name": "Personalversammlung" + } + ] + } + }, + "slotCount": 1, + "date": "1464340800" + } + ], + "authKey": "", + "createIP": "", + "createTimestamp": "", + "id": 0, + "reminderTimestamp": 0, + "requests": [ + { + "id": "120703", + "link": "https://service.berlin.de/dienstleistung/120703/", + "name": "Personalausweis beantragen", + "source": "dldb" + } + ], + "scope": { + "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", + "id": "141", + "contact": { + "name": "Bürgeramt Heerstraße", + "street": "Heerstr. 12, 14052 Berlin", + "email": "", + "country": "Germany" + }, + "preferences": { + "appointment": { + "deallocationDuration": "10", + "infoForAppointment": "", + "endInDaysDefault": "60", + "multipleSlotsEnabled": "0", + "reservationDuration": "20", + "startInDaysDefault": "0" + }, + "client": { + "alternateAppointmentUrl": "", + "amendmentActivated": "0", + "amendmentLabel": "", + "emailRequired": "0", + "telephoneActivated": "0", + "telephoneRequired": "0" + }, + "notifications": { + "confirmationContent": "", + "enabled": "1", + "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", + "headsUpTime": "30" + }, + "pickup": { + "alternateName": "Ausgabe", + "isDefault": "0" + }, + "queue": { + "callCountMax": "0", + "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", + "firstNumber": "1", + "lastNumber": "499", + "processingTimeAverage": "15", + "publishWaitingTimeEnabled": "1", + "statisticsEnabled": "1" + }, + "survey": { + "emailContent": "", + "enabled": "0", + "label": "" + }, + "ticketprinter": { + "confirmationEnabled": "0", + "deactivatedText": "", + "notificationsAmendmentEnabled": "0", + "notificationsDelay": "0" + }, + "workstation": { + "emergencyEnabled": "1" + } + }, + "shortName": "", + "status": { + "emergency": { + "acceptedByWorkstation": "-1", + "activated": "0", + "calledByWorkstation": "-1" + }, + "queue": { + "ghostWorkstationCount": "-1", + "givenNumberCount": "46", + "lastGivenNumber": "47", + "lastGivenNumberTimestamp": "1458774000" + }, + "ticketprinter": { + "deactivated": "0" + } + }, + "provider": { + "id": "122217", + "source": "dldb", + "displayName":"001", + "contact": { + "city": "Berlin", + "country": "Germany", + "name": "Bürgeramt Heerstraße", + "postalCode": "14052", + "region": "Berlin", + "street": "Heerstr.", + "streetNumber": "12" + }, + "link": "https://service.berlin.de/standort/122217/", + "name": "Bürgeramt Heerstraße" + }, + "dayoff": [ + { + "date": "1458860400", + "name": "Karfreitag" + }, + { + "date": "1459116000", + "name": "Ostermontag" + }, + { + "date": "1462053600", + "name": "Maifeiertag" + }, + { + "date": "1462399200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1463349600", + "name": "Pfingstmontag" + }, + { + "date": "1475445600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1482620400", + "name": "1. Weihnachtstag" + }, + { + "date": "1482706800", + "name": "2. Weihnachtstag" + }, + { + "date": "1483225200", + "name": "Neujahr" + }, + { + "date": "1492120800", + "name": "Karfreitag" + }, + { + "date": "1492380000", + "name": "Ostermontag" + }, + { + "date": "1493589600", + "name": "Maifeiertag" + }, + { + "date": "1495663200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1496613600", + "name": "Pfingstmontag" + }, + { + "date": "1506981600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1514156400", + "name": "1. Weihnachtstag" + }, + { + "date": "1514242800", + "name": "2. Weihnachtstag" + }, + { + "date": "1514761200", + "name": "Neujahr" + }, + { + "date": "1522360800", + "name": "Karfreitag" + }, + { + "date": "1522620000", + "name": "Ostermontag" + }, + { + "date": "1525125600", + "name": "Maifeiertag" + }, + { + "date": "1525903200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1526853600", + "name": "Pfingstmontag" + }, + { + "date": "1538517600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1545692400", + "name": "1. Weihnachtstag" + }, + { + "date": "1545778800", + "name": "2. Weihnachtstag" + }, + { + "date": "1546297200", + "name": "Neujahr" + }, + { + "date": "1555624800", + "name": "Karfreitag" + }, + { + "date": "1555884000", + "name": "Ostermontag" + }, + { + "date": "1556661600", + "name": "Maifeiertag" + }, + { + "date": "1559167200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1560117600", + "name": "Pfingstmontag" + }, + { + "date": "1570053600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1577228400", + "name": "1. Weihnachtstag" + }, + { + "date": "1577314800", + "name": "2. Weihnachtstag" + }, + { + "date": "1577833200", + "name": "Neujahr" + }, + { + "date": "1586469600", + "name": "Karfreitag" + }, + { + "date": "1586728800", + "name": "Ostermontag" + }, + { + "date": "1588284000", + "name": "Maifeiertag" + }, + { + "date": "1590012000", + "name": "Christi Himmelfahrt" + }, + { + "date": "1590962400", + "name": "Pfingstmontag" + }, + { + "date": "1601676000", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1608850800", + "name": "1. Weihnachtstag" + }, + { + "date": "1608937200", + "name": "2. Weihnachtstag" + }, + { + "date": "1609455600", + "name": "Neujahr" + }, + { + "date": "1617314400", + "name": "Karfreitag" + }, + { + "date": "1617573600", + "name": "Ostermontag" + }, + { + "date": "1619820000", + "name": "Maifeiertag" + }, + { + "date": "1620856800", + "name": "Christi Himmelfahrt" + }, + { + "date": "1621807200", + "name": "Pfingstmontag" + }, + { + "date": "1633212000", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1640386800", + "name": "1. Weihnachtstag" + }, + { + "date": "1640473200", + "name": "2. Weihnachtstag" + }, + { + "date": "1478041200", + "name": "Personalversammlung" + } + ] + }, + "status": "" + }, + "1": { + "$schema": "https://schema.berlin.de/queuemanagement/process.json", + "amendment": "", + "appointments": [ + { + "scope": { + "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", + "id": "141", + "contact": { + "name": "Bürgeramt Heerstraße", + "street": "Heerstr. 12, 14052 Berlin", + "email": "", + "country": "Germany" + }, + "preferences": { + "appointment": { + "deallocationDuration": "10", + "infoForAppointment": "", + "endInDaysDefault": "60", + "multipleSlotsEnabled": "0", + "reservationDuration": "20", + "startInDaysDefault": "0" + }, + "client": { + "alternateAppointmentUrl": "", + "amendmentActivated": "0", + "amendmentLabel": "", + "emailRequired": "0", + "telephoneActivated": "0", + "telephoneRequired": "0" + }, + "notifications": { + "confirmationContent": "", + "enabled": "1", + "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", + "headsUpTime": "30" + }, + "pickup": { + "alternateName": "Ausgabe", + "isDefault": "0" + }, + "queue": { + "callCountMax": "0", + "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", + "firstNumber": "1", + "lastNumber": "499", + "processingTimeAverage": "15", + "publishWaitingTimeEnabled": "1", + "statisticsEnabled": "1" + }, + "survey": { + "emailContent": "", + "enabled": "0", + "label": "" + }, + "ticketprinter": { + "confirmationEnabled": "0", + "deactivatedText": "", + "notificationsAmendmentEnabled": "0", + "notificationsDelay": "0" + }, + "workstation": { + "emergencyEnabled": "1" + } + }, + "shortName": "", + "status": { + "emergency": { + "acceptedByWorkstation": "-1", + "activated": "0", + "calledByWorkstation": "-1" + }, + "queue": { + "ghostWorkstationCount": "-1", + "givenNumberCount": "46", + "lastGivenNumber": "47", + "lastGivenNumberTimestamp": "1458774000" + }, + "ticketprinter": { + "deactivated": "0" + } + }, + "provider": { + "id": "122217", + "contact": { + "email": "test@example.com", + "city": "Berlin", + "country": "Germany", + "name": "Bürgeramt Heerstraße", + "postalCode": "14052", + "region": "Berlin", + "street": "Heerstr.", + "streetNumber": "12" + }, + "source": "dldb", + "link": "https://service.berlin.de/standort/122217/", + "name": "Bürgeramt Heerstraße", + "displayName":"001" + }, + "dayoff": [ + { + "date": "1458860400", + "name": "Karfreitag" + }, + { + "date": "1459116000", + "name": "Ostermontag" + }, + { + "date": "1462053600", + "name": "Maifeiertag" + }, + { + "date": "1462399200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1463349600", + "name": "Pfingstmontag" + }, + { + "date": "1475445600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1482620400", + "name": "1. Weihnachtstag" + }, + { + "date": "1482706800", + "name": "2. Weihnachtstag" + }, + { + "date": "1483225200", + "name": "Neujahr" + }, + { + "date": "1492120800", + "name": "Karfreitag" + }, + { + "date": "1492380000", + "name": "Ostermontag" + }, + { + "date": "1493589600", + "name": "Maifeiertag" + }, + { + "date": "1495663200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1496613600", + "name": "Pfingstmontag" + }, + { + "date": "1506981600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1514156400", + "name": "1. Weihnachtstag" + }, + { + "date": "1514242800", + "name": "2. Weihnachtstag" + }, + { + "date": "1514761200", + "name": "Neujahr" + }, + { + "date": "1522360800", + "name": "Karfreitag" + }, + { + "date": "1522620000", + "name": "Ostermontag" + }, + { + "date": "1525125600", + "name": "Maifeiertag" + }, + { + "date": "1525903200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1526853600", + "name": "Pfingstmontag" + }, + { + "date": "1538517600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1545692400", + "name": "1. Weihnachtstag" + }, + { + "date": "1545778800", + "name": "2. Weihnachtstag" + }, + { + "date": "1546297200", + "name": "Neujahr" + }, + { + "date": "1555624800", + "name": "Karfreitag" + }, + { + "date": "1555884000", + "name": "Ostermontag" + }, + { + "date": "1556661600", + "name": "Maifeiertag" + }, + { + "date": "1559167200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1560117600", + "name": "Pfingstmontag" + }, + { + "date": "1570053600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1577228400", + "name": "1. Weihnachtstag" + }, + { + "date": "1577314800", + "name": "2. Weihnachtstag" + }, + { + "date": "1577833200", + "name": "Neujahr" + }, + { + "date": "1586469600", + "name": "Karfreitag" + }, + { + "date": "1586728800", + "name": "Ostermontag" + }, + { + "date": "1588284000", + "name": "Maifeiertag" + }, + { + "date": "1590012000", + "name": "Christi Himmelfahrt" + }, + { + "date": "1590962400", + "name": "Pfingstmontag" + }, + { + "date": "1601676000", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1608850800", + "name": "1. Weihnachtstag" + }, + { + "date": "1608937200", + "name": "2. Weihnachtstag" + }, + { + "date": "1609455600", + "name": "Neujahr" + }, + { + "date": "1617314400", + "name": "Karfreitag" + }, + { + "date": "1617573600", + "name": "Ostermontag" + }, + { + "date": "1619820000", + "name": "Maifeiertag" + }, + { + "date": "1620856800", + "name": "Christi Himmelfahrt" + }, + { + "date": "1621807200", + "name": "Pfingstmontag" + }, + { + "date": "1633212000", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1640386800", + "name": "1. Weihnachtstag" + }, + { + "date": "1640473200", + "name": "2. Weihnachtstag" + }, + { + "date": "1478041200", + "name": "Personalversammlung" + } + ] + }, + "availability": { + "id": "94678", + "weekday": { + "monday": "0", + "tuesday": "0", + "wednesday": "0", + "thursday": "0", + "friday": "32", + "saturday": "0", + "sunday": "0" + }, + "repeat": { + "afterWeeks": "1", + "weekOfMonth": "0" + }, + "bookable": { + "startInDays": "0", + "endInDays": "60" + }, + "workstationCount": { + "public": "2", + "callcenter": "2", + "intern": "2" + }, + "multipleSlotsAllowed": "0", + "slotTimeInMinutes": "10", + "startDate": "1463954400", + "endDate": "1609369200", + "startTime": "08:00:00", + "endTime": "13:50:00", + "type": "appointment", + "scope": { + "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", + "id": "141", + "contact": { + "name": "Bürgeramt Heerstraße", + "street": "Heerstr. 12, 14052 Berlin", + "email": "", + "country": "Germany" + }, + "preferences": { + "appointment": { + "deallocationDuration": "10", + "infoForAppointment": "", + "endInDaysDefault": "60", + "multipleSlotsEnabled": "0", + "reservationDuration": "20", + "startInDaysDefault": "0" + }, + "client": { + "alternateAppointmentUrl": "", + "amendmentActivated": "0", + "amendmentLabel": "", + "emailRequired": "0", + "telephoneActivated": "0", + "telephoneRequired": "0" + }, + "notifications": { + "confirmationContent": "", + "enabled": "1", + "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", + "headsUpTime": "30" + }, + "pickup": { + "alternateName": "Ausgabe", + "isDefault": "0" + }, + "queue": { + "callCountMax": "0", + "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", + "firstNumber": "1", + "lastNumber": "499", + "processingTimeAverage": "15", + "publishWaitingTimeEnabled": "1", + "statisticsEnabled": "1" + }, + "survey": { + "emailContent": "", + "enabled": "0", + "label": "" + }, + "ticketprinter": { + "confirmationEnabled": "0", + "deactivatedText": "", + "notificationsAmendmentEnabled": "0", + "notificationsDelay": "0" + }, + "workstation": { + "emergencyEnabled": "1" + } + }, + "shortName": "", + "status": { + "emergency": { + "acceptedByWorkstation": "-1", + "activated": "0", + "calledByWorkstation": "-1" + }, + "queue": { + "ghostWorkstationCount": "-1", + "givenNumberCount": "46", + "lastGivenNumber": "47", + "lastGivenNumberTimestamp": "1458774000" + }, + "ticketprinter": { + "deactivated": "0" + } + }, + "provider": { + "id": "122217", + "contact": { + "email": "test@example.com", + "city": "Berlin", + "country": "Germany", + "name": "Bürgeramt Heerstraße", + "postalCode": "14052", + "region": "Berlin", + "street": "Heerstr.", + "streetNumber": "12" + }, + "source": "dldb", + "link": "https://service.berlin.de/standort/122217/", + "name": "Bürgeramt Heerstraße", + "displayName":"001" + }, + "dayoff": [ + { + "date": "1458860400", + "name": "Karfreitag" + }, + { + "date": "1459116000", + "name": "Ostermontag" + }, + { + "date": "1462053600", + "name": "Maifeiertag" + }, + { + "date": "1462399200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1463349600", + "name": "Pfingstmontag" + }, + { + "date": "1475445600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1482620400", + "name": "1. Weihnachtstag" + }, + { + "date": "1482706800", + "name": "2. Weihnachtstag" + }, + { + "date": "1483225200", + "name": "Neujahr" + }, + { + "date": "1492120800", + "name": "Karfreitag" + }, + { + "date": "1492380000", + "name": "Ostermontag" + }, + { + "date": "1493589600", + "name": "Maifeiertag" + }, + { + "date": "1495663200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1496613600", + "name": "Pfingstmontag" + }, + { + "date": "1506981600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1514156400", + "name": "1. Weihnachtstag" + }, + { + "date": "1514242800", + "name": "2. Weihnachtstag" + }, + { + "date": "1514761200", + "name": "Neujahr" + }, + { + "date": "1522360800", + "name": "Karfreitag" + }, + { + "date": "1522620000", + "name": "Ostermontag" + }, + { + "date": "1525125600", + "name": "Maifeiertag" + }, + { + "date": "1525903200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1526853600", + "name": "Pfingstmontag" + }, + { + "date": "1538517600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1545692400", + "name": "1. Weihnachtstag" + }, + { + "date": "1545778800", + "name": "2. Weihnachtstag" + }, + { + "date": "1546297200", + "name": "Neujahr" + }, + { + "date": "1555624800", + "name": "Karfreitag" + }, + { + "date": "1555884000", + "name": "Ostermontag" + }, + { + "date": "1556661600", + "name": "Maifeiertag" + }, + { + "date": "1559167200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1560117600", + "name": "Pfingstmontag" + }, + { + "date": "1570053600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1577228400", + "name": "1. Weihnachtstag" + }, + { + "date": "1577314800", + "name": "2. Weihnachtstag" + }, + { + "date": "1577833200", + "name": "Neujahr" + }, + { + "date": "1586469600", + "name": "Karfreitag" + }, + { + "date": "1586728800", + "name": "Ostermontag" + }, + { + "date": "1588284000", + "name": "Maifeiertag" + }, + { + "date": "1590012000", + "name": "Christi Himmelfahrt" + }, + { + "date": "1590962400", + "name": "Pfingstmontag" + }, + { + "date": "1601676000", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1608850800", + "name": "1. Weihnachtstag" + }, + { + "date": "1608937200", + "name": "2. Weihnachtstag" + }, + { + "date": "1609455600", + "name": "Neujahr" + }, + { + "date": "1617314400", + "name": "Karfreitag" + }, + { + "date": "1617573600", + "name": "Ostermontag" + }, + { + "date": "1619820000", + "name": "Maifeiertag" + }, + { + "date": "1620856800", + "name": "Christi Himmelfahrt" + }, + { + "date": "1621807200", + "name": "Pfingstmontag" + }, + { + "date": "1633212000", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1640386800", + "name": "1. Weihnachtstag" + }, + { + "date": "1640473200", + "name": "2. Weihnachtstag" + }, + { + "date": "1478041200", + "name": "Personalversammlung" + } + ] + } + }, + "slotCount": 1, + "date": "1464342000" + } + ], + "authKey": "", + "createIP": "", + "createTimestamp": "", + "id": 0, + "reminderTimestamp": 0, + "requests": [ + { + "id": "999999", + "link": "https://service.berlin.de/dienstleistung/999999/", + "name": "Unit test request", + "source": "dldb" + } + ], + "scope": { + "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", + "id": "141", + "contact": { + "name": "Bürgeramt Heerstraße", + "street": "Heerstr. 12, 14052 Berlin", + "email": "", + "country": "Germany" + }, + "preferences": { + "appointment": { + "deallocationDuration": "10", + "infoForAppointment": "", + "endInDaysDefault": "60", + "multipleSlotsEnabled": "0", + "reservationDuration": "20", + "startInDaysDefault": "0" + }, + "client": { + "alternateAppointmentUrl": "", + "amendmentActivated": "0", + "amendmentLabel": "", + "emailRequired": "0", + "telephoneActivated": "0", + "telephoneRequired": "0" + }, + "notifications": { + "confirmationContent": "", + "enabled": "1", + "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", + "headsUpTime": "30" + }, + "pickup": { + "alternateName": "Ausgabe", + "isDefault": "0" + }, + "queue": { + "callCountMax": "0", + "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", + "firstNumber": "1", + "lastNumber": "499", + "processingTimeAverage": "15", + "publishWaitingTimeEnabled": "1", + "statisticsEnabled": "1" + }, + "survey": { + "emailContent": "", + "enabled": "0", + "label": "" + }, + "ticketprinter": { + "confirmationEnabled": "0", + "deactivatedText": "", + "notificationsAmendmentEnabled": "0", + "notificationsDelay": "0" + }, + "workstation": { + "emergencyEnabled": "1" + } + }, + "shortName": "", + "status": { + "emergency": { + "acceptedByWorkstation": "-1", + "activated": "0", + "calledByWorkstation": "-1" + }, + "queue": { + "ghostWorkstationCount": "-1", + "givenNumberCount": "46", + "lastGivenNumber": "47", + "lastGivenNumberTimestamp": "1458774000" + }, + "ticketprinter": { + "deactivated": "0" + } + }, + "provider": { + "id": "122217", + "source": "dldb", + "contact": { + "city": "Berlin", + "country": "Germany", + "name": "Bürgeramt Heerstraße", + "postalCode": "14052", + "region": "Berlin", + "street": "Heerstr.", + "streetNumber": "12" + }, + "link": "https://service.berlin.de/standort/122217/", + "name": "Bürgeramt Heerstraße", + "displayName":"001" + }, + "dayoff": [ + { + "date": "1458860400", + "name": "Karfreitag" + }, + { + "date": "1459116000", + "name": "Ostermontag" + }, + { + "date": "1462053600", + "name": "Maifeiertag" + }, + { + "date": "1462399200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1463349600", + "name": "Pfingstmontag" + }, + { + "date": "1475445600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1482620400", + "name": "1. Weihnachtstag" + }, + { + "date": "1482706800", + "name": "2. Weihnachtstag" + }, + { + "date": "1483225200", + "name": "Neujahr" + }, + { + "date": "1492120800", + "name": "Karfreitag" + }, + { + "date": "1492380000", + "name": "Ostermontag" + }, + { + "date": "1493589600", + "name": "Maifeiertag" + }, + { + "date": "1495663200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1496613600", + "name": "Pfingstmontag" + }, + { + "date": "1506981600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1514156400", + "name": "1. Weihnachtstag" + }, + { + "date": "1514242800", + "name": "2. Weihnachtstag" + }, + { + "date": "1514761200", + "name": "Neujahr" + }, + { + "date": "1522360800", + "name": "Karfreitag" + }, + { + "date": "1522620000", + "name": "Ostermontag" + }, + { + "date": "1525125600", + "name": "Maifeiertag" + }, + { + "date": "1525903200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1526853600", + "name": "Pfingstmontag" + }, + { + "date": "1538517600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1545692400", + "name": "1. Weihnachtstag" + }, + { + "date": "1545778800", + "name": "2. Weihnachtstag" + }, + { + "date": "1546297200", + "name": "Neujahr" + }, + { + "date": "1555624800", + "name": "Karfreitag" + }, + { + "date": "1555884000", + "name": "Ostermontag" + }, + { + "date": "1556661600", + "name": "Maifeiertag" + }, + { + "date": "1559167200", + "name": "Christi Himmelfahrt" + }, + { + "date": "1560117600", + "name": "Pfingstmontag" + }, + { + "date": "1570053600", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1577228400", + "name": "1. Weihnachtstag" + }, + { + "date": "1577314800", + "name": "2. Weihnachtstag" + }, + { + "date": "1577833200", + "name": "Neujahr" + }, + { + "date": "1586469600", + "name": "Karfreitag" + }, + { + "date": "1586728800", + "name": "Ostermontag" + }, + { + "date": "1588284000", + "name": "Maifeiertag" + }, + { + "date": "1590012000", + "name": "Christi Himmelfahrt" + }, + { + "date": "1590962400", + "name": "Pfingstmontag" + }, + { + "date": "1601676000", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1608850800", + "name": "1. Weihnachtstag" + }, + { + "date": "1608937200", + "name": "2. Weihnachtstag" + }, + { + "date": "1609455600", + "name": "Neujahr" + }, + { + "date": "1617314400", + "name": "Karfreitag" + }, + { + "date": "1617573600", + "name": "Ostermontag" + }, + { + "date": "1619820000", + "name": "Maifeiertag" + }, + { + "date": "1620856800", + "name": "Christi Himmelfahrt" + }, + { + "date": "1621807200", + "name": "Pfingstmontag" + }, + { + "date": "1633212000", + "name": "Tag der Deutschen Einheit" + }, + { + "date": "1640386800", + "name": "1. Weihnachtstag" + }, + { + "date": "1640473200", + "name": "2. Weihnachtstag" + }, + { + "date": "1478041200", + "name": "Personalversammlung" + } + ] + }, + "status": "" + } + } diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_SourceGet_dldb.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_SourceGet_dldb.json new file mode 100644 index 000000000..441188813 --- /dev/null +++ b/zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_SourceGet_dldb.json @@ -0,0 +1,142 @@ +{ + "$schema": "https://localhost/terminvereinbarung/api/2/", + "meta": { + "$schema": "https://schema.berlin.de/queuemanagement/metaresult.json", + "error": false, + "generated": "2019-02-08T14:45:15+01:00", + "server": "Zmsapi-ENV (v2.19.02-38-g0ba2cba)" + }, + "data": { + "$schema": "https://schema.berlin.de/queuemanagement/source.json", + "source": "unittest", + "contact": { + "name": "BerlinOnline Stadtportal GmbH", + "email": "test@example.com" + }, + "providers": [ + { + "id": "10546", + "source": "dldb", + "contact": { + "city": "Muenchen", + "country": "Germany", + "name": "Gewerbeamt (KVR-III\/21)", + "postalCode": "81371", + "region": "Muenchen", + "street": "Implerstra\u00dfe", + "streetNumber": "11" + }, + "link": "https:\/\/service.berlin.de\/standort\/10546\/", + "name": "Gewerbeamt (KVR-III\/21)", + "displayName": "Gewerbeamt" + } + ], + "requests": [ + { + "id": "1063423", + "link": "https:\/\/service.berlin.de\/dienstleistung\/1063423\/", + "name": "Gewerbe anmelden \/ Zweitschrift beantragen", + "group": "Sonstiges", + "source": "dldb" + } + ], + "scopes": [ + { + "id": "58", + "source": "dldb", + "contact": { + "name": "Gewerbeamt (KVR-III\/21)", + "street": "Implerstra\u00dfe 11", + "email": "", + "country": "Germany" + }, + "provider": { + "id": "10546", + "source": "dldb" + }, + "hint": "", + "lastChange": 1724192287, + "shortName": "Gewerbemeldungen", + "preferences": { + "client": { + "telephoneActivated": "0", + "telephoneRequired": "1", + "customTextfieldActivated": "0", + "customTextfieldRequired": "1", + "customTextfieldLabel": "", + "captchaActivatedRequired": "0" + } + } + } + ], + "days": [ + { + "$schema": "https://schema.berlin.de/queuemanagement/day.json", + "year": "2024", + "month": "08", + "day": "21", + "status": "bookable", + "freeAppointments": { + "public": 10, + "intern": 5, + "callcenter": 0, + "type": "sum" + } + }, + { + "$schema": "https://schema.berlin.de/queuemanagement/day.json", + "year": "2024", + "month": "08", + "day": "22", + "status": "bookable", + "freeAppointments": { + "public": 15, + "intern": 10, + "callcenter": 0, + "type": "sum" + } + }, + { + "$schema": "https://schema.berlin.de/queuemanagement/day.json", + "year": "2024", + "month": "08", + "day": "23", + "status": "bookable", + "freeAppointments": { + "public": 12, + "intern": 7, + "callcenter": 0, + "type": "sum" + } + } + ], + "firstDay": { + "year": "2024", + "month": "08", + "day": "21" + }, + "lastDay": { + "year": "2024", + "month": "08", + "day": "23" + }, + "freeProcesses": [], + "label": "Unittest Source", + "editable": "1", + "lastChange": 1549546997, + "requestrelation": [ + { + "provider": { + "id": "10546", + "source": "unittest" + }, + "request": { + "id": "1063423", + "$ref": "/request/unittest/1/" + }, + "source": "unittest", + "slots": "2" + } + ] + } +} \ No newline at end of file diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_reserve_timeslot.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_reserve_timeslot.json new file mode 100644 index 000000000..653d8bc02 --- /dev/null +++ b/zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_reserve_timeslot.json @@ -0,0 +1,98 @@ +{ + "$schema": "https://localhost/terminvereinbarung/api/2/", + "meta": { + "$schema": "https://schema.berlin.de/queuemanagement/metaresult.json", + "error": false, + "generated": "2024-09-24T16:48:37+02:00", + "server": "Zmsapi-ENV ()" + }, + "data": { + "$schema": "https://schema.berlin.de/queuemanagement/process.json", + "amendment": "", + "customTextfield": "", + "appointments": [ + { + "date": 32526616522, + "scope": { + "id": "58", + "source": "dldb" + }, + "availability": { + "id": 0, + "weekday": { + "sunday": 0, + "monday": 0, + "tuesday": 0, + "wednesday": 0, + "thursday": 0, + "friday": 0, + "saturday": 0 + }, + "repeat": { + "afterWeeks": 1, + "weekOfMonth": 0 + }, + "bookable": { + "startInDays": 1, + "endInDays": 60 + }, + "workstationCount": { + "public": 0, + "callcenter": 0, + "intern": 0 + }, + "lastChange": 0, + "multipleSlotsAllowed": true, + "slotTimeInMinutes": 10, + "startDate": 0, + "endDate": 0, + "startTime": "0:00", + "endTime": "23:59", + "type": "appointment" + }, + "slotCount": "4" + } + ], + "apiclient": { + "shortname": "default" + }, + "authKey": "b93e", + "clients": [ + { + "familyName": "", + "email": "test@muenchen.de", + "emailSendCount": "0", + "notificationsSendCount": "0", + "surveyAccepted": "0", + "telephone": "" + } + ], + "createIP": "", + "createTimestamp": 1727189317, + "id": "101142", + "archiveId": 0, + "queue": { + "$schema": "https:\/\/schema.berlin.de\/queuemanagement\/queue.json", + "arrivalTime": 1727691300, + "callCount": "0", + "callTime": 0, + "number": "101142", + "waitingTimeEstimate": 0, + "waitingTimeOptimistic": 0, + "waitingTime": null, + "wayTime": null, + "status": "reserved", + "lastCallTime": 0, + "destination": null, + "destinationHint": null, + "withAppointment": "1" + }, + "reminderTimestamp": "0", + "scope": { + "id": "58", + "source": "dldb" + }, + "status": "reserved", + "lastChange": 1727189317 + } +} \ No newline at end of file From ec64d2b23fdb349d45822b9f36f417fef968b812 Mon Sep 17 00:00:00 2001 From: Thomas Fink Date: Tue, 24 Sep 2024 17:47:54 +0200 Subject: [PATCH 04/10] some clean up --- .../Zmscitizenapi/AppointmentReserveTest.php | 2 +- .../fixtures/GET_free_timeslots.json | 167 ----- .../GET_freeprocesslist_20160527.json | 626 ------------------ ...b.json => GET_reserve_SourceGet_dldb.json} | 0 4 files changed, 1 insertion(+), 794 deletions(-) delete mode 100644 zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_free_timeslots.json delete mode 100644 zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_freeprocesslist_20160527.json rename zmscitizenapi/tests/Zmscitizenapi/fixtures/{POST_SourceGet_dldb.json => GET_reserve_SourceGet_dldb.json} (100%) diff --git a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php index 0947f961e..981c9fe46 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php @@ -18,7 +18,7 @@ public function testRendering() 'parameters' => [ 'resolveReferences' => 2, ], - 'response' => $this->readFixture("POST_SourceGet_dldb.json"), + 'response' => $this->readFixture("GET_reserve_SourceGet_dldb.json"), ], [ 'function' => 'readPostResult', diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_free_timeslots.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_free_timeslots.json deleted file mode 100644 index 07bc979b4..000000000 --- a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_free_timeslots.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "$schema": "https://localhost/terminvereinbarung/api/2/", - "meta": { - "$schema": "https://schema.berlin.de/queuemanagement/metaresult.json", - "error": false, - "generated": "2019-02-08T14:45:15+01:00", - "server": "Zmsapi-ENV (v2.19.02-38-g0ba2cba)" - }, - "data": { - "amendment": "", - "appointmentTimestamps": [ - 1727241600, - 1727241900, - 1727242200, - 1727242500, - 1727242800, - 1727243100, - 1727243400, - 1727243700, - 1727244000, - 1727244300, - 1727244600, - 1727244900, - 1727245200, - 1727245500, - 1727245800, - 1727246100, - 1727246400, - 1727246700, - 1727247000, - 1727247300, - 1727247600, - 1727247900, - 1727248200, - 1727248500, - 1727248800, - 1727249100, - 1727249400, - 1727249700, - 1727250000, - 1727250300, - 1727250600, - 1727250900, - 1727251200, - 1727251500, - 1727251800, - 1727252100, - 1727252400, - 1727252700, - 1727253000, - 1727253300, - 1727253600, - 1727253900, - 1727254200, - 1727254500, - 1727254800, - 1727255100, - 1727255400, - 1727255700, - 1727256000, - 1727256300, - 1727256600, - 1727256900, - 1727257200, - 1727257500, - 1727257800, - 1727258100, - 1727258400, - 1727258700, - 1727259000, - 1727259300, - 1727259600, - 1727259900, - 1727260200, - 1727260500, - 1727260800, - 1727261100, - 1727261400, - 1727261700, - 1727262000, - 1727262300, - 1727262600, - 1727262900, - 1727263200, - 1727263500, - 1727263800, - 1727264100, - 1727264400, - 1727264700, - 1727265000, - 1727265300, - 1727265600, - 1727265900, - 1727266200, - 1727266500, - 1727266800, - 1727267100, - 1727267400, - 1727267700, - 1727268000, - 1727268300, - 1727268600, - 1727268900, - 1727269200, - 1727269500, - 1727269800, - 1727270100, - 1727270400, - 1727270700, - 1727271000, - 1727271300, - 1727271600, - 1727271900, - 1727272200, - 1727272500, - 1727272800, - 1727273100, - 1727273400, - 1727273700, - 1727274000, - 1727274300, - 1727274600, - 1727274900, - 1727275200, - 1727275500, - 1727275800, - 1727276100, - 1727276400, - 1727276700, - 1727277000, - 1727277300, - 1727277600, - 1727277900, - 1727278200, - 1727278500, - 1727278800, - 1727279100, - 1727279400, - 1727279700, - 1727280000, - 1727280300, - 1727280600, - 1727280900, - 1727281200, - 1727281500, - 1727281800, - 1727282100, - 1727282400, - 1727282700, - 1727283000, - 1727283300, - 1727283600, - 1727283900, - 1727284200, - 1727284500, - 1727284800, - 1727285100, - 1727285400, - 1727285700, - 1727286000, - 1727286300, - 32526616522 - ], - "lastModified": 1727162779840, - "status": 200 - } -} \ No newline at end of file diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_freeprocesslist_20160527.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_freeprocesslist_20160527.json deleted file mode 100644 index 7e5bc8909..000000000 --- a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_freeprocesslist_20160527.json +++ /dev/null @@ -1,626 +0,0 @@ -{ - "$schema": "https://localhost/terminvereinbarung/api/2/", - "meta": { - "$schema": "https://schema.berlin.de/queuemanagement/metaresult.json", - "error": false, - "exception": null, - "generated": "2016-09-13T13:55:41+02:00", - "server": "Zmsapi-ENV" - }, - "data": { - "0": { - "$schema": "https://schema.berlin.de/queuemanagement/process.json", - "amendment": "", - "appointments": [{ - "$schema": "https://schema.berlin.de/queuemanagement/appointment.json", - "scope": { - "$schema": "https://schema.berlin.de/queuemanagement/scope.json", - "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", - "id": "141", - "contact": { - "name": "Bürgeramt Heerstraße", - "street": "Heerstr. 12, 14052 Berlin", - "email": "", - "country": "Germany" - }, - "preferences": { - "appointment": { - "deallocationDuration": "10", - "infoForAppointment": "", - "endInDaysDefault": "60", - "multipleSlotsEnabled": "0", - "reservationDuration": "20", - "startInDaysDefault": "0" - }, - "client": { - "alternateAppointmentUrl": "", - "amendmentActivated": "0", - "amendmentLabel": "", - "emailRequired": "0", - "adminMailOnAppointment": "0", - "adminMailOnDeleted": "0", - "telephoneActivated": "0", - "telephoneRequired": "0" - }, - "notifications": { - "confirmationContent": "", - "enabled": "1", - "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", - "headsUpTime": "30" - }, - "pickup": { - "alternateName": "Ausgabe", - "isDefault": "0" - }, - "queue": { - "callCountMax": "0", - "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", - "firstNumber": "1", - "lastNumber": "499", - "processingTimeAverage": "15", - "publishWaitingTimeEnabled": "1", - "statisticsEnabled": "1" - }, - "survey": { - "emailContent": "", - "enabled": "0", - "label": "" - }, - "ticketprinter": { - "confirmationEnabled": "0", - "deactivatedText": "", - "notificationsAmendmentEnabled": "0", - "notificationsDelay": "0" - }, - "workstation": { - "emergencyEnabled": "1" - } - }, - "shortName": "", - "status": { - "emergency": { - "acceptedByWorkstation": "-1", - "activated": "0", - "calledByWorkstation": "-1" - }, - "queue": { - "ghostWorkstationCount": "-1", - "givenNumberCount": "46", - "lastGivenNumber": "47", - "lastGivenNumberTimestamp": "1447925159" - }, - "ticketprinter": { - "deactivated": "0" - } - }, - "provider": { - "id": "122217", - "contact": { - "email": "test@example.com", - "city": "Berlin", - "country": "Germany", - "name": "Bürgeramt Heerstraße", - "postalCode": "14052", - "region": "Berlin", - "street": "Heerstr.", - "streetNumber": "12" - }, - "source": "dldb", - "link": "https://service.berlin.de/standort/122217/", - "name": "Bürgeramt Heerstraße" - }, - "department": { - "id": "74", - "contact": { - "city": "Berlin", - "street": "Otto-Suhr-Allee 100, 10585 Berlin", - "country": "Germany", - "name": "" - }, - "email": "test@example.com", - "name": "Bürgeramt", - "preferences": { - "notifications": { - "enabled": null, - "identification": null, - "sendConfirmationEnabled": null, - "sendReminderEnabled": null - } - } - } - }, - "availability": { - "$schema": "https://schema.berlin.de/queuemanagement/availability.json", - "id": "94678", - "weekday": { - "monday": "0", - "tuesday": "0", - "wednesday": "0", - "thursday": "0", - "friday": "32", - "saturday": "0", - "sunday": "0" - }, - "repeat": { - "afterWeeks": "1", - "weekOfMonth": "0" - }, - "bookable": { - "startInDays": "0", - "endInDays": "60" - }, - "workstationCount": { - "public": "2", - "callcenter": "2", - "intern": "2" - }, - "multipleSlotsAllowed": "0", - "slotTimeInMinutes": "10", - "startDate": "1463954400", - "endDate": "1609365600", - "startTime": "08:00:00", - "endTime": "13:50:00", - "department": { - "id": "74", - "contact": { - "city": "Berlin", - "street": "Otto-Suhr-Allee 100, 10585 Berlin", - "country": "Germany", - "name": "" - }, - "email": "test@example.com", - "name": "Bürgeramt", - "preferences": { - "notifications": { - "enabled": null, - "identification": null, - "sendConfirmationEnabled": null, - "sendReminderEnabled": null - } - } - } - }, - "slotCount": 1, - "date": "1464340800" - }], - "authKey": "", - "clients": [], - "createIP": "", - "createTimestamp": "", - "id": 0, - "queue": [], - "reminderTimestamp": 0, - "requests": [{ - "$schema": "https://schema.berlin.de/queuemanagement/request.json", - "id": "120703", - "link": "https://service.berlin.de/dienstleistung/120703/", - "name": "Personalausweis beantragen", - "source": "dldb" - }], - "scope": { - "$schema": "https://schema.berlin.de/queuemanagement/scope.json", - "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", - "id": "141", - "contact": { - "name": "Bürgeramt Heerstraße", - "street": "Heerstr. 12, 14052 Berlin", - "email": "", - "country": "Germany" - }, - "preferences": { - "appointment": { - "deallocationDuration": "10", - "infoForAppointment": "", - "endInDaysDefault": "60", - "multipleSlotsEnabled": "0", - "reservationDuration": "20", - "startInDaysDefault": "0" - }, - "client": { - "alternateAppointmentUrl": "", - "amendmentActivated": "0", - "amendmentLabel": "", - "emailRequired": "0", - "adminMailOnAppointment": "0", - "adminMailOnDeleted": "0", - "telephoneActivated": "0", - "telephoneRequired": "0" - }, - "notifications": { - "confirmationContent": "", - "enabled": "1", - "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", - "headsUpTime": "30" - }, - "pickup": { - "alternateName": "Ausgabe", - "isDefault": "0" - }, - "queue": { - "callCountMax": "0", - "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", - "firstNumber": "1", - "lastNumber": "499", - "processingTimeAverage": "15", - "publishWaitingTimeEnabled": "1", - "statisticsEnabled": "1" - }, - "survey": { - "emailContent": "", - "enabled": "0", - "label": "" - }, - "ticketprinter": { - "confirmationEnabled": "0", - "deactivatedText": "", - "notificationsAmendmentEnabled": "0", - "notificationsDelay": "0" - }, - "workstation": { - "emergencyEnabled": "1" - } - }, - "shortName": "", - "status": { - "emergency": { - "acceptedByWorkstation": "-1", - "activated": "0", - "calledByWorkstation": "-1" - }, - "queue": { - "ghostWorkstationCount": "-1", - "givenNumberCount": "46", - "lastGivenNumber": "47", - "lastGivenNumberTimestamp": "1447925159" - }, - "ticketprinter": { - "deactivated": "0" - } - }, - "provider": { - "id": "122217", - "contact": { - "email": "test@example.com", - "city": "Berlin", - "country": "Germany", - "name": "Bürgeramt Heerstraße", - "postalCode": "14052", - "region": "Berlin", - "street": "Heerstr.", - "streetNumber": "12" - }, - "source": "dldb", - "link": "https://service.berlin.de/standort/122217/", - "name": "Bürgeramt Heerstraße" - }, - "department": { - "id": "74", - "contact": { - "city": "Berlin", - "street": "Otto-Suhr-Allee 100, 10585 Berlin", - "country": "Germany", - "name": "" - }, - "email": "test@example.com", - "name": "Bürgeramt", - "preferences": { - "notifications": { - "enabled": null, - "identification": null, - "sendConfirmationEnabled": null, - "sendReminderEnabled": null - } - } - } - }, - "status": "" - }, - "1": { - "$schema": "https://schema.berlin.de/queuemanagement/process.json", - "amendment": "", - "appointments": [{ - "$schema": "https://schema.berlin.de/queuemanagement/appointment.json", - "scope": { - "$schema": "https://schema.berlin.de/queuemanagement/scope.json", - "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", - "id": "141", - "contact": { - "name": "Bürgeramt Heerstraße", - "street": "Heerstr. 12, 14052 Berlin", - "email": "", - "country": "Germany" - }, - "preferences": { - "appointment": { - "deallocationDuration": "10", - "infoForAppointment": "", - "endInDaysDefault": "60", - "multipleSlotsEnabled": "0", - "reservationDuration": "20", - "startInDaysDefault": "0" - }, - "client": { - "alternateAppointmentUrl": "", - "amendmentActivated": "0", - "amendmentLabel": "", - "emailRequired": "0", - "adminMailOnAppointment": "0", - "adminMailOnDeleted": "0", - "telephoneActivated": "0", - "telephoneRequired": "0" - }, - "notifications": { - "confirmationContent": "", - "enabled": "1", - "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", - "headsUpTime": "30" - }, - "pickup": { - "alternateName": "Ausgabe", - "isDefault": "0" - }, - "queue": { - "callCountMax": "0", - "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", - "firstNumber": "1", - "lastNumber": "499", - "processingTimeAverage": "15", - "publishWaitingTimeEnabled": "1", - "statisticsEnabled": "1" - }, - "survey": { - "emailContent": "", - "enabled": "0", - "label": "" - }, - "ticketprinter": { - "confirmationEnabled": "0", - "deactivatedText": "", - "notificationsAmendmentEnabled": "0", - "notificationsDelay": "0" - }, - "workstation": { - "emergencyEnabled": "1" - } - }, - "shortName": "", - "status": { - "emergency": { - "acceptedByWorkstation": "-1", - "activated": "0", - "calledByWorkstation": "-1" - }, - "queue": { - "ghostWorkstationCount": "-1", - "givenNumberCount": "46", - "lastGivenNumber": "47", - "lastGivenNumberTimestamp": "1447925159" - }, - "ticketprinter": { - "deactivated": "0" - } - }, - "provider": { - "id": "122217", - "contact": { - "email": "test@example.com", - "city": "Berlin", - "country": "Germany", - "name": "Bürgeramt Heerstraße", - "postalCode": "14052", - "region": "Berlin", - "street": "Heerstr.", - "streetNumber": "12" - }, - "source": "dldb", - "link": "https://service.berlin.de/standort/122217/", - "name": "Bürgeramt Heerstraße" - }, - "department": { - "id": "74", - "contact": { - "city": "Berlin", - "street": "Otto-Suhr-Allee 100, 10585 Berlin", - "country": "Germany", - "name": "" - }, - "email": "test@example.com", - "name": "Bürgeramt", - "preferences": { - "notifications": { - "enabled": null, - "identification": null, - "sendConfirmationEnabled": null, - "sendReminderEnabled": null - } - } - } - }, - "availability": { - "$schema": "https://schema.berlin.de/queuemanagement/availability.json", - "id": "94678", - "weekday": { - "monday": "0", - "tuesday": "0", - "wednesday": "0", - "thursday": "0", - "friday": "32", - "saturday": "0", - "sunday": "0" - }, - "repeat": { - "afterWeeks": "1", - "weekOfMonth": "0" - }, - "bookable": { - "startInDays": "0", - "endInDays": "60" - }, - "workstationCount": { - "public": "2", - "callcenter": "2", - "intern": "2" - }, - "multipleSlotsAllowed": "0", - "slotTimeInMinutes": "10", - "startDate": "1463954400", - "endDate": "1609365600", - "startTime": "08:00:00", - "endTime": "13:50:00", - "department": { - "id": "74", - "contact": { - "city": "Berlin", - "street": "Otto-Suhr-Allee 100, 10585 Berlin", - "country": "Germany", - "name": "" - }, - "email": "test@example.com", - "name": "Bürgeramt", - "preferences": { - "notifications": { - "enabled": null, - "identification": null, - "sendConfirmationEnabled": null, - "sendReminderEnabled": null - } - } - } - }, - "slotCount": 1, - "date": "1464342000" - }], - "authKey": "", - "clients": [], - "createIP": "", - "createTimestamp": "", - "id": 0, - "queue": [], - "reminderTimestamp": 0, - "requests": [{ - "$schema": "https://schema.berlin.de/queuemanagement/request.json", - "id": "120703", - "link": "https://service.berlin.de/dienstleistung/120703/", - "name": "Personalausweis beantragen", - "source": "dldb" - }], - "scope": { - "$schema": "https://schema.berlin.de/queuemanagement/scope.json", - "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", - "id": "141", - "contact": { - "name": "Bürgeramt Heerstraße", - "street": "Heerstr. 12, 14052 Berlin", - "email": "", - "country": "Germany" - }, - "preferences": { - "appointment": { - "deallocationDuration": "10", - "infoForAppointment": "", - "endInDaysDefault": "60", - "multipleSlotsEnabled": "0", - "reservationDuration": "20", - "startInDaysDefault": "0" - }, - "client": { - "alternateAppointmentUrl": "", - "amendmentActivated": "0", - "amendmentLabel": "", - "emailRequired": "0", - "adminMailOnAppointment": "0", - "adminMailOnDeleted": "0", - "telephoneActivated": "0", - "telephoneRequired": "0" - }, - "notifications": { - "confirmationContent": "", - "enabled": "1", - "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", - "headsUpTime": "30" - }, - "pickup": { - "alternateName": "Ausgabe", - "isDefault": "0" - }, - "queue": { - "callCountMax": "0", - "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", - "firstNumber": "1", - "lastNumber": "499", - "processingTimeAverage": "15", - "publishWaitingTimeEnabled": "1", - "statisticsEnabled": "1" - }, - "survey": { - "emailContent": "", - "enabled": "0", - "label": "" - }, - "ticketprinter": { - "confirmationEnabled": "0", - "deactivatedText": "", - "notificationsAmendmentEnabled": "0", - "notificationsDelay": "0" - }, - "workstation": { - "emergencyEnabled": "1" - } - }, - "shortName": "", - "status": { - "emergency": { - "acceptedByWorkstation": "-1", - "activated": "0", - "calledByWorkstation": "-1" - }, - "queue": { - "ghostWorkstationCount": "-1", - "givenNumberCount": "46", - "lastGivenNumber": "47", - "lastGivenNumberTimestamp": "1447925159" - }, - "ticketprinter": { - "deactivated": "0" - } - }, - "provider": { - "id": "122217", - "contact": { - "email": "test@example.com", - "city": "Berlin", - "country": "Germany", - "name": "Bürgeramt Heerstraße", - "postalCode": "14052", - "region": "Berlin", - "street": "Heerstr.", - "streetNumber": "12" - }, - "source": "dldb", - "link": "https://service.berlin.de/standort/122217/", - "name": "Bürgeramt Heerstraße" - }, - "department": { - "id": "74", - "contact": { - "city": "Berlin", - "street": "Otto-Suhr-Allee 100, 10585 Berlin", - "country": "Germany", - "name": "" - }, - "email": "test@example.com", - "name": "Bürgeramt", - "preferences": { - "notifications": { - "enabled": null, - "identification": null, - "sendConfirmationEnabled": null, - "sendReminderEnabled": null - } - } - } - }, - "status": "" - } - } -} diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_SourceGet_dldb.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_reserve_SourceGet_dldb.json similarity index 100% rename from zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_SourceGet_dldb.json rename to zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_reserve_SourceGet_dldb.json From d3347197496dbb482e77949e95c0ddcb2468f71a Mon Sep 17 00:00:00 2001 From: Thomas Fink Date: Thu, 26 Sep 2024 13:39:14 +0200 Subject: [PATCH 05/10] feat(ZMS-2517): fix up response for the reserve post request --- .../Controllers/AppointmentReserve.php | 33 +- .../Zmscitizenapi/Services/ScopesService.php | 25 +- .../Zmscitizenapi/AppointmentReserveTest.php | 19 +- .../tests/Zmscitizenapi/ScopeByIdGetTest.php | 8 +- .../tests/Zmscitizenapi/ScopesListTest.php | 6 +- .../fixtures/GET_SourceGet_dldb.json | 6 +- .../fixtures/GET_reserve_SourceGet_dldb.json | 1 + .../fixtures/GetFreeProcessList.json | 1990 ----------------- .../fixtures/POST_reserve_timeslot.json | 2 + 9 files changed, 66 insertions(+), 2024 deletions(-) delete mode 100644 zmscitizenapi/tests/Zmscitizenapi/fixtures/GetFreeProcessList.json diff --git a/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php b/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php index 5e587a582..4668de9f7 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php +++ b/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php @@ -36,10 +36,8 @@ public function __construct() $this->utilityHelper = new UtilityHelper(); } - // This method signature matches the BaseController's method signature public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { - // Cast RequestInterface to ServerRequestInterface $request = $request instanceof ServerRequestInterface ? $request : null; if (!$request) { @@ -71,11 +69,9 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo } try { - // Step 1: Validate the scope for the office and check if captcha is required - $providerScope = $this->scopesService->getScopeByOfficeId($officeId); // we need to mock the scope + $providerScope = $this->scopesService->getScopeByOfficeId($officeId); $captchaRequired = Application::$CAPTCHA_ENABLED === "1" && $providerScope['captchaActivatedRequired'] === "1"; - // Step 2: If captcha is required, verify it if ($captchaRequired) { $captchaVerificationResult = $this->captchaService->verifyCaptcha($captchaSolution); if (!$captchaVerificationResult['success']) { @@ -87,14 +83,11 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo } } - // Step 3: Validate the service-location combination $serviceValidationResult = $this->officesServicesRelationsService->validateServiceLocationCombination($officeId, $serviceIds); if ($serviceValidationResult['status'] !== 200) { return $this->createJsonResponse($response, $serviceValidationResult, 400); } - - // Step 4: Get available timeslots using the AvailableAppointmentsService $freeAppointments = $this->availableAppointmentsService->getFreeAppointments([ 'officeId' => $officeId, 'serviceIds' => $serviceIds, @@ -102,13 +95,10 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo 'date' => $this->utilityHelper->getInternalDateFromTimestamp($timestamp) ]); - // **Step 5: Find the matching time slot based on the requested timestamp** $selectedProcess = array_filter($freeAppointments, function ($process) use ($timestamp) { - // Ensure 'appointments' is set and is an array before accessing it if (!isset($process['appointments']) || !is_array($process['appointments'])) { return false; } - // Find the appointment slot with the exact matching timestamp return in_array($timestamp, array_column($process['appointments'], 'date')); }); @@ -120,7 +110,6 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo ], 404); } - // Step 6: Prepare the process for reservation $selectedProcess = array_values($selectedProcess)[0]; $selectedProcess['clients'] = [ [ @@ -128,17 +117,21 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo ] ]; - // Step 7: Reserve the appointment using the ProcessService $reservedProcess = $this->processService->reserveTimeslot($selectedProcess, $serviceIds, $serviceCounts); - // Step 8: Use the AppointmentService's getThinnedProcessData method + if ($reservedProcess && $reservedProcess->scope && $reservedProcess->scope->id) { + $scopeIds = [$reservedProcess->scope->id]; + $scopesData = $this->scopesService->getScopeByIds($scopeIds); + + if ($scopesData['status'] === 200 && isset($scopesData['scopes']['scopes']) && !empty($scopesData['scopes']['scopes'])) { + $reservedProcess->scope = $this->scopesService->mapScope($scopesData['scopes']['scopes'][0]); + } + } + $thinnedProcessData = $this->appointmentService->getThinnedProcessData($reservedProcess); - - // Step 9: Return the thinned process data - return $this->createJsonResponse($response, [ - 'reservedProcess' => $thinnedProcessData, - 'officeId' => $officeId - ], 200); + $thinnedProcessData = array_merge($thinnedProcessData, ['officeId' => $officeId]); + + return $this->createJsonResponse($response, $thinnedProcessData, 200); } catch (\Exception $e) { error_log('Unexpected error: ' . $e->getMessage()); diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/ScopesService.php b/zmscitizenapi/src/Zmscitizenapi/Services/ScopesService.php index 7391a841d..49846a680 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Services/ScopesService.php +++ b/zmscitizenapi/src/Zmscitizenapi/Services/ScopesService.php @@ -23,7 +23,8 @@ public function getScopes() "customTextfieldActivated" => $scope->getCustomTextfieldActivated(), "customTextfieldRequired" => $scope->getCustomTextfieldRequired(), "customTextfieldLabel" => $scope->getCustomTextfieldLabel(), - "captchaActivatedRequired" => $scope->getCaptchaActivatedRequired() + "captchaActivatedRequired" => $scope->getCaptchaActivatedRequired(), + "displayInfo" => $scope->getDisplayInfo() ]; } @@ -66,7 +67,8 @@ public function getScopeByIds(array $scopeIds) "customTextfieldActivated" => $scopeItem->getCustomTextfieldActivated(), "customTextfieldRequired" => $scopeItem->getCustomTextfieldRequired(), "customTextfieldLabel" => $scopeItem->getCustomTextfieldLabel(), - "captchaActivatedRequired" => $scopeItem->getCaptchaActivatedRequired() + "captchaActivatedRequired" => $scopeItem->getCaptchaActivatedRequired(), + "displayInfo" => $scopeItem->getDisplayInfo() ]; $found = true; break; @@ -119,4 +121,23 @@ public function getScopeByOfficeId($officeId) ]; } } + + public function mapScope($scope) + { + return [ + 'id' => $scope['id'] ?? null, + 'provider' => [ + 'id' => $scope['provider']['id'] ?? null, + 'source' => $scope['provider']['source'] ?? null, + ], + 'shortName' => $scope['shortName'] ?? null, + 'telephoneActivated' => $scope['telephoneActivated'] ?? null, + 'telephoneRequired' => $scope['telephoneRequired'] ?? null, + 'customTextfieldActivated' => $scope['customTextfieldActivated'] ?? null, + 'customTextfieldRequired' => $scope['customTextfieldRequired'] ?? null, + 'customTextfieldLabel' => $scope['customTextfieldLabel'] ?? null, + 'captchaActivatedRequired' => $scope['captchaActivatedRequired'] ?? null, + 'displayInfo' => $scope['displayInfo'] ?? null, + ]; + } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php index 981c9fe46..354c69fb5 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php @@ -36,18 +36,25 @@ public function testRendering() $parameters = [ 'officeId' => '10546', 'serviceId' => ['1063423'], - 'serviceCount' => [1], + 'serviceCount' => [0], 'timestamp' => "32526616522", 'captchaSolution' => null ]; $response = $this->render([], $parameters, [], 'POST'); $responseBody = json_decode((string)$response->getBody(), true); - $this->assertEquals(200, $response->getStatusCode(), 'Expected a 200 OK response.'); - $this->assertArrayHasKey('reservedProcess', $responseBody, 'Expected reservedProcess in response.'); - $this->assertArrayHasKey('officeId', $responseBody, 'Expected officeId in response.'); - $this->assertEquals('10546', $responseBody['officeId'], 'Expected correct officeId.'); - $this->assertEquals('test@muenchen.de', $responseBody['reservedProcess']['email'], 'Expected test@muenchen.de email.'); + $this->assertArrayHasKey('processId', $responseBody, 'Expected processId in response.'); + $this->assertArrayHasKey('email', $responseBody, 'Expected email in response.'); + $this->assertEquals('test@muenchen.de', $responseBody['email'], 'Expected test@muenchen.de email.'); + $this->assertArrayHasKey('authKey', $responseBody, 'Expected authKey in response.'); + $this->assertEquals('b93e', $responseBody['authKey'], 'Expected correct authKey.'); + $this->assertArrayHasKey('timestamp', $responseBody, 'Expected timestamp in response.'); + $this->assertEquals('32526616522', $responseBody['timestamp'], 'Expected correct timestamp.'); + $this->assertArrayHasKey('scope', $responseBody, 'Expected scope in response.'); + $this->assertEquals('58', $responseBody['scope']['id'], 'Expected correct scope id.'); + $this->assertEquals('dldb', $responseBody['scope']['provider']['source'], 'Expected correct provider source.'); + $this->assertArrayHasKey('serviceCount', $responseBody, 'Expected serviceCount in response.'); + $this->assertEquals(0, $responseBody['serviceCount'], 'Expected serviceCount to be 0.'); } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/ScopeByIdGetTest.php b/zmscitizenapi/tests/Zmscitizenapi/ScopeByIdGetTest.php index f3ab70d3a..48e0e4f09 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/ScopeByIdGetTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/ScopeByIdGetTest.php @@ -39,6 +39,7 @@ public function testRendering() 'customTextfieldRequired' => '0', 'customTextfieldLabel' => 'Custom Label', 'captchaActivatedRequired' => '1', + 'displayInfo' => null ] ] ]; @@ -75,6 +76,7 @@ public function testRenderingMulti() 'customTextfieldRequired' => '0', 'customTextfieldLabel' => 'Custom Label', 'captchaActivatedRequired' => '1', + 'displayInfo' => null ], [ 'id' => '2', @@ -89,6 +91,7 @@ public function testRenderingMulti() 'customTextfieldRequired' => '1', 'customTextfieldLabel' => '', 'captchaActivatedRequired' => '0', + 'displayInfo' => null ], ] ]; @@ -133,7 +136,6 @@ public function testNoScopeIdProvided() $this->assertEquals(400, $response->getStatusCode()); } - public function testPartialResultsWithWarning() { $this->setApiCalls([ @@ -164,6 +166,7 @@ public function testPartialResultsWithWarning() 'customTextfieldRequired' => '0', 'customTextfieldLabel' => 'Custom Label', 'captchaActivatedRequired' => '1', + 'displayInfo' => null ] ], 'warning' => 'The following scopeId(s) were not found: 99' @@ -171,7 +174,7 @@ public function testPartialResultsWithWarning() $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); $this->assertEquals(200, $response->getStatusCode()); } - + public function testDuplicateScopeIds() { $this->setApiCalls([ @@ -204,6 +207,7 @@ public function testDuplicateScopeIds() 'customTextfieldRequired' => '0', 'customTextfieldLabel' => 'Custom Label', 'captchaActivatedRequired' => '1', + 'displayInfo' => null ] ] ]; diff --git a/zmscitizenapi/tests/Zmscitizenapi/ScopesListTest.php b/zmscitizenapi/tests/Zmscitizenapi/ScopesListTest.php index de3ee8fa0..f8126ff45 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/ScopesListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/ScopesListTest.php @@ -34,7 +34,8 @@ public function testRendering() { "customTextfieldActivated" => "1", "customTextfieldRequired" => "0", "customTextfieldLabel" => "Custom Label", - "captchaActivatedRequired" => "1" + "captchaActivatedRequired" => "1", + "displayInfo" => null ], [ "id" => "2", @@ -49,7 +50,8 @@ public function testRendering() { "customTextfieldActivated" => "0", "customTextfieldRequired" => "1", "customTextfieldLabel" => "", - "captchaActivatedRequired" => "0" + "captchaActivatedRequired" => "0", + "displayInfo" => null ] ] ]; diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_SourceGet_dldb.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_SourceGet_dldb.json index dc19f7ce0..e49ecf422 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_SourceGet_dldb.json +++ b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_SourceGet_dldb.json @@ -91,7 +91,8 @@ "customTextfieldActivated": "1", "customTextfieldRequired": "0", "customTextfieldLabel": "Custom Label", - "captchaActivatedRequired": "1" + "captchaActivatedRequired": "1", + "displayInfo": "Infos zum Standort." } } }, @@ -109,7 +110,8 @@ "customTextfieldActivated": "0", "customTextfieldRequired": "1", "customTextfieldLabel": "", - "captchaActivatedRequired": "0" + "captchaActivatedRequired": "0", + "displayInfo": "Infos zum Standort." } } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_reserve_SourceGet_dldb.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_reserve_SourceGet_dldb.json index 441188813..9344088f9 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_reserve_SourceGet_dldb.json +++ b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GET_reserve_SourceGet_dldb.json @@ -57,6 +57,7 @@ "hint": "", "lastChange": 1724192287, "shortName": "Gewerbemeldungen", + "displayInfo": "Infos zum Standort.", "preferences": { "client": { "telephoneActivated": "0", diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GetFreeProcessList.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/GetFreeProcessList.json deleted file mode 100644 index e0ac3443a..000000000 --- a/zmscitizenapi/tests/Zmscitizenapi/fixtures/GetFreeProcessList.json +++ /dev/null @@ -1,1990 +0,0 @@ -{ - "0": { - "$schema": "https://schema.berlin.de/queuemanagement/process.json", - "amendment": "", - "appointments": [ - { - "scope": { - "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", - "id": "141", - "contact": { - "name": "Bürgeramt Heerstraße", - "street": "Heerstr. 12, 14052 Berlin", - "email": "", - "country": "Germany" - }, - "preferences": { - "appointment": { - "deallocationDuration": "10", - "infoForAppointment": "", - "endInDaysDefault": "60", - "multipleSlotsEnabled": "0", - "reservationDuration": "20", - "startInDaysDefault": "0" - }, - "client": { - "alternateAppointmentUrl": "", - "amendmentActivated": "0", - "amendmentLabel": "", - "emailRequired": "0", - "telephoneActivated": "0", - "telephoneRequired": "0" - }, - "notifications": { - "confirmationContent": "", - "enabled": "1", - "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", - "headsUpTime": "30" - }, - "pickup": { - "alternateName": "Ausgabe", - "isDefault": "0" - }, - "queue": { - "callCountMax": "0", - "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", - "firstNumber": "1", - "lastNumber": "499", - "processingTimeAverage": "15", - "publishWaitingTimeEnabled": "1", - "statisticsEnabled": "1" - }, - "survey": { - "emailContent": "", - "enabled": "0", - "label": "" - }, - "ticketprinter": { - "confirmationEnabled": "0", - "deactivatedText": "", - "notificationsAmendmentEnabled": "0", - "notificationsDelay": "0" - }, - "workstation": { - "emergencyEnabled": "1" - } - }, - "shortName": "", - "status": { - "emergency": { - "acceptedByWorkstation": "-1", - "activated": "0", - "calledByWorkstation": "-1" - }, - "queue": { - "ghostWorkstationCount": "-1", - "givenNumberCount": "46", - "lastGivenNumber": "47", - "lastGivenNumberTimestamp": "1458774000" - }, - "ticketprinter": { - "deactivated": "0" - } - }, - "provider": { - "id": "122217", - "contact": { - "email": "test@example.com", - "city": "Berlin", - "country": "Germany", - "name": "Bürgeramt Heerstraße", - "postalCode": "14052", - "region": "Berlin", - "street": "Heerstr.", - "streetNumber": "12" - }, - "source": "dldb", - "link": "https://service.berlin.de/standort/122217/", - "name": "Bürgeramt Heerstraße", - "displayName":"001" - }, - "dayoff": [ - { - "date": "1458860400", - "name": "Karfreitag" - }, - { - "date": "1459116000", - "name": "Ostermontag" - }, - { - "date": "1462053600", - "name": "Maifeiertag" - }, - { - "date": "1462399200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1463349600", - "name": "Pfingstmontag" - }, - { - "date": "1475445600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1482620400", - "name": "1. Weihnachtstag" - }, - { - "date": "1482706800", - "name": "2. Weihnachtstag" - }, - { - "date": "1483225200", - "name": "Neujahr" - }, - { - "date": "1492120800", - "name": "Karfreitag" - }, - { - "date": "1492380000", - "name": "Ostermontag" - }, - { - "date": "1493589600", - "name": "Maifeiertag" - }, - { - "date": "1495663200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1496613600", - "name": "Pfingstmontag" - }, - { - "date": "1506981600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1514156400", - "name": "1. Weihnachtstag" - }, - { - "date": "1514242800", - "name": "2. Weihnachtstag" - }, - { - "date": "1514761200", - "name": "Neujahr" - }, - { - "date": "1522360800", - "name": "Karfreitag" - }, - { - "date": "1522620000", - "name": "Ostermontag" - }, - { - "date": "1525125600", - "name": "Maifeiertag" - }, - { - "date": "1525903200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1526853600", - "name": "Pfingstmontag" - }, - { - "date": "1538517600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1545692400", - "name": "1. Weihnachtstag" - }, - { - "date": "1545778800", - "name": "2. Weihnachtstag" - }, - { - "date": "1546297200", - "name": "Neujahr" - }, - { - "date": "1555624800", - "name": "Karfreitag" - }, - { - "date": "1555884000", - "name": "Ostermontag" - }, - { - "date": "1556661600", - "name": "Maifeiertag" - }, - { - "date": "1559167200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1560117600", - "name": "Pfingstmontag" - }, - { - "date": "1570053600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1577228400", - "name": "1. Weihnachtstag" - }, - { - "date": "1577314800", - "name": "2. Weihnachtstag" - }, - { - "date": "1577833200", - "name": "Neujahr" - }, - { - "date": "1586469600", - "name": "Karfreitag" - }, - { - "date": "1586728800", - "name": "Ostermontag" - }, - { - "date": "1588284000", - "name": "Maifeiertag" - }, - { - "date": "1590012000", - "name": "Christi Himmelfahrt" - }, - { - "date": "1590962400", - "name": "Pfingstmontag" - }, - { - "date": "1601676000", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1608850800", - "name": "1. Weihnachtstag" - }, - { - "date": "1608937200", - "name": "2. Weihnachtstag" - }, - { - "date": "1609455600", - "name": "Neujahr" - }, - { - "date": "1617314400", - "name": "Karfreitag" - }, - { - "date": "1617573600", - "name": "Ostermontag" - }, - { - "date": "1619820000", - "name": "Maifeiertag" - }, - { - "date": "1620856800", - "name": "Christi Himmelfahrt" - }, - { - "date": "1621807200", - "name": "Pfingstmontag" - }, - { - "date": "1633212000", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1640386800", - "name": "1. Weihnachtstag" - }, - { - "date": "1640473200", - "name": "2. Weihnachtstag" - }, - { - "date": "1478041200", - "name": "Personalversammlung" - } - ] - }, - "availability": { - "id": "94678", - "weekday": { - "monday": "0", - "tuesday": "0", - "wednesday": "0", - "thursday": "0", - "friday": "32", - "saturday": "0", - "sunday": "0" - }, - "repeat": { - "afterWeeks": "1", - "weekOfMonth": "0" - }, - "bookable": { - "startInDays": "0", - "endInDays": "60" - }, - "workstationCount": { - "public": "2", - "callcenter": "2", - "intern": "2" - }, - "multipleSlotsAllowed": "0", - "slotTimeInMinutes": "10", - "startDate": "1463954400", - "endDate": "1609369200", - "startTime": "08:00:00", - "endTime": "13:50:00", - "type": "appointment", - "scope": { - "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", - "id": "141", - "contact": { - "name": "Bürgeramt Heerstraße", - "street": "Heerstr. 12, 14052 Berlin", - "email": "", - "country": "Germany" - }, - "preferences": { - "appointment": { - "deallocationDuration": "10", - "infoForAppointment": "", - "endInDaysDefault": "60", - "multipleSlotsEnabled": "0", - "reservationDuration": "20", - "startInDaysDefault": "0" - }, - "client": { - "alternateAppointmentUrl": "", - "amendmentActivated": "0", - "amendmentLabel": "", - "emailRequired": "0", - "telephoneActivated": "0", - "telephoneRequired": "0" - }, - "notifications": { - "confirmationContent": "", - "enabled": "1", - "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", - "headsUpTime": "30" - }, - "pickup": { - "alternateName": "Ausgabe", - "isDefault": "0" - }, - "queue": { - "callCountMax": "0", - "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", - "firstNumber": "1", - "lastNumber": "499", - "processingTimeAverage": "15", - "publishWaitingTimeEnabled": "1", - "statisticsEnabled": "1" - }, - "survey": { - "emailContent": "", - "enabled": "0", - "label": "" - }, - "ticketprinter": { - "confirmationEnabled": "0", - "deactivatedText": "", - "notificationsAmendmentEnabled": "0", - "notificationsDelay": "0" - }, - "workstation": { - "emergencyEnabled": "1" - } - }, - "shortName": "", - "status": { - "emergency": { - "acceptedByWorkstation": "-1", - "activated": "0", - "calledByWorkstation": "-1" - }, - "queue": { - "ghostWorkstationCount": "-1", - "givenNumberCount": "46", - "lastGivenNumber": "47", - "lastGivenNumberTimestamp": "1458774000" - }, - "ticketprinter": { - "deactivated": "0" - } - }, - "provider": { - "id": "122217", - "contact": { - "email": "test@example.com", - "city": "Berlin", - "country": "Germany", - "name": "Bürgeramt Heerstraße", - "postalCode": "14052", - "region": "Berlin", - "street": "Heerstr.", - "streetNumber": "12" - }, - "source": "dldb", - "link": "https://service.berlin.de/standort/122217/", - "name": "Bürgeramt Heerstraße", - "displayName":"001" - }, - "dayoff": [ - { - "date": "1458860400", - "name": "Karfreitag" - }, - { - "date": "1459116000", - "name": "Ostermontag" - }, - { - "date": "1462053600", - "name": "Maifeiertag" - }, - { - "date": "1462399200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1463349600", - "name": "Pfingstmontag" - }, - { - "date": "1475445600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1482620400", - "name": "1. Weihnachtstag" - }, - { - "date": "1482706800", - "name": "2. Weihnachtstag" - }, - { - "date": "1483225200", - "name": "Neujahr" - }, - { - "date": "1492120800", - "name": "Karfreitag" - }, - { - "date": "1492380000", - "name": "Ostermontag" - }, - { - "date": "1493589600", - "name": "Maifeiertag" - }, - { - "date": "1495663200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1496613600", - "name": "Pfingstmontag" - }, - { - "date": "1506981600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1514156400", - "name": "1. Weihnachtstag" - }, - { - "date": "1514242800", - "name": "2. Weihnachtstag" - }, - { - "date": "1514761200", - "name": "Neujahr" - }, - { - "date": "1522360800", - "name": "Karfreitag" - }, - { - "date": "1522620000", - "name": "Ostermontag" - }, - { - "date": "1525125600", - "name": "Maifeiertag" - }, - { - "date": "1525903200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1526853600", - "name": "Pfingstmontag" - }, - { - "date": "1538517600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1545692400", - "name": "1. Weihnachtstag" - }, - { - "date": "1545778800", - "name": "2. Weihnachtstag" - }, - { - "date": "1546297200", - "name": "Neujahr" - }, - { - "date": "1555624800", - "name": "Karfreitag" - }, - { - "date": "1555884000", - "name": "Ostermontag" - }, - { - "date": "1556661600", - "name": "Maifeiertag" - }, - { - "date": "1559167200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1560117600", - "name": "Pfingstmontag" - }, - { - "date": "1570053600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1577228400", - "name": "1. Weihnachtstag" - }, - { - "date": "1577314800", - "name": "2. Weihnachtstag" - }, - { - "date": "1577833200", - "name": "Neujahr" - }, - { - "date": "1586469600", - "name": "Karfreitag" - }, - { - "date": "1586728800", - "name": "Ostermontag" - }, - { - "date": "1588284000", - "name": "Maifeiertag" - }, - { - "date": "1590012000", - "name": "Christi Himmelfahrt" - }, - { - "date": "1590962400", - "name": "Pfingstmontag" - }, - { - "date": "1601676000", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1608850800", - "name": "1. Weihnachtstag" - }, - { - "date": "1608937200", - "name": "2. Weihnachtstag" - }, - { - "date": "1609455600", - "name": "Neujahr" - }, - { - "date": "1617314400", - "name": "Karfreitag" - }, - { - "date": "1617573600", - "name": "Ostermontag" - }, - { - "date": "1619820000", - "name": "Maifeiertag" - }, - { - "date": "1620856800", - "name": "Christi Himmelfahrt" - }, - { - "date": "1621807200", - "name": "Pfingstmontag" - }, - { - "date": "1633212000", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1640386800", - "name": "1. Weihnachtstag" - }, - { - "date": "1640473200", - "name": "2. Weihnachtstag" - }, - { - "date": "1478041200", - "name": "Personalversammlung" - } - ] - } - }, - "slotCount": 1, - "date": "1464340800" - } - ], - "authKey": "", - "createIP": "", - "createTimestamp": "", - "id": 0, - "reminderTimestamp": 0, - "requests": [ - { - "id": "120703", - "link": "https://service.berlin.de/dienstleistung/120703/", - "name": "Personalausweis beantragen", - "source": "dldb" - } - ], - "scope": { - "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", - "id": "141", - "contact": { - "name": "Bürgeramt Heerstraße", - "street": "Heerstr. 12, 14052 Berlin", - "email": "", - "country": "Germany" - }, - "preferences": { - "appointment": { - "deallocationDuration": "10", - "infoForAppointment": "", - "endInDaysDefault": "60", - "multipleSlotsEnabled": "0", - "reservationDuration": "20", - "startInDaysDefault": "0" - }, - "client": { - "alternateAppointmentUrl": "", - "amendmentActivated": "0", - "amendmentLabel": "", - "emailRequired": "0", - "telephoneActivated": "0", - "telephoneRequired": "0" - }, - "notifications": { - "confirmationContent": "", - "enabled": "1", - "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", - "headsUpTime": "30" - }, - "pickup": { - "alternateName": "Ausgabe", - "isDefault": "0" - }, - "queue": { - "callCountMax": "0", - "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", - "firstNumber": "1", - "lastNumber": "499", - "processingTimeAverage": "15", - "publishWaitingTimeEnabled": "1", - "statisticsEnabled": "1" - }, - "survey": { - "emailContent": "", - "enabled": "0", - "label": "" - }, - "ticketprinter": { - "confirmationEnabled": "0", - "deactivatedText": "", - "notificationsAmendmentEnabled": "0", - "notificationsDelay": "0" - }, - "workstation": { - "emergencyEnabled": "1" - } - }, - "shortName": "", - "status": { - "emergency": { - "acceptedByWorkstation": "-1", - "activated": "0", - "calledByWorkstation": "-1" - }, - "queue": { - "ghostWorkstationCount": "-1", - "givenNumberCount": "46", - "lastGivenNumber": "47", - "lastGivenNumberTimestamp": "1458774000" - }, - "ticketprinter": { - "deactivated": "0" - } - }, - "provider": { - "id": "122217", - "source": "dldb", - "displayName":"001", - "contact": { - "city": "Berlin", - "country": "Germany", - "name": "Bürgeramt Heerstraße", - "postalCode": "14052", - "region": "Berlin", - "street": "Heerstr.", - "streetNumber": "12" - }, - "link": "https://service.berlin.de/standort/122217/", - "name": "Bürgeramt Heerstraße" - }, - "dayoff": [ - { - "date": "1458860400", - "name": "Karfreitag" - }, - { - "date": "1459116000", - "name": "Ostermontag" - }, - { - "date": "1462053600", - "name": "Maifeiertag" - }, - { - "date": "1462399200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1463349600", - "name": "Pfingstmontag" - }, - { - "date": "1475445600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1482620400", - "name": "1. Weihnachtstag" - }, - { - "date": "1482706800", - "name": "2. Weihnachtstag" - }, - { - "date": "1483225200", - "name": "Neujahr" - }, - { - "date": "1492120800", - "name": "Karfreitag" - }, - { - "date": "1492380000", - "name": "Ostermontag" - }, - { - "date": "1493589600", - "name": "Maifeiertag" - }, - { - "date": "1495663200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1496613600", - "name": "Pfingstmontag" - }, - { - "date": "1506981600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1514156400", - "name": "1. Weihnachtstag" - }, - { - "date": "1514242800", - "name": "2. Weihnachtstag" - }, - { - "date": "1514761200", - "name": "Neujahr" - }, - { - "date": "1522360800", - "name": "Karfreitag" - }, - { - "date": "1522620000", - "name": "Ostermontag" - }, - { - "date": "1525125600", - "name": "Maifeiertag" - }, - { - "date": "1525903200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1526853600", - "name": "Pfingstmontag" - }, - { - "date": "1538517600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1545692400", - "name": "1. Weihnachtstag" - }, - { - "date": "1545778800", - "name": "2. Weihnachtstag" - }, - { - "date": "1546297200", - "name": "Neujahr" - }, - { - "date": "1555624800", - "name": "Karfreitag" - }, - { - "date": "1555884000", - "name": "Ostermontag" - }, - { - "date": "1556661600", - "name": "Maifeiertag" - }, - { - "date": "1559167200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1560117600", - "name": "Pfingstmontag" - }, - { - "date": "1570053600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1577228400", - "name": "1. Weihnachtstag" - }, - { - "date": "1577314800", - "name": "2. Weihnachtstag" - }, - { - "date": "1577833200", - "name": "Neujahr" - }, - { - "date": "1586469600", - "name": "Karfreitag" - }, - { - "date": "1586728800", - "name": "Ostermontag" - }, - { - "date": "1588284000", - "name": "Maifeiertag" - }, - { - "date": "1590012000", - "name": "Christi Himmelfahrt" - }, - { - "date": "1590962400", - "name": "Pfingstmontag" - }, - { - "date": "1601676000", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1608850800", - "name": "1. Weihnachtstag" - }, - { - "date": "1608937200", - "name": "2. Weihnachtstag" - }, - { - "date": "1609455600", - "name": "Neujahr" - }, - { - "date": "1617314400", - "name": "Karfreitag" - }, - { - "date": "1617573600", - "name": "Ostermontag" - }, - { - "date": "1619820000", - "name": "Maifeiertag" - }, - { - "date": "1620856800", - "name": "Christi Himmelfahrt" - }, - { - "date": "1621807200", - "name": "Pfingstmontag" - }, - { - "date": "1633212000", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1640386800", - "name": "1. Weihnachtstag" - }, - { - "date": "1640473200", - "name": "2. Weihnachtstag" - }, - { - "date": "1478041200", - "name": "Personalversammlung" - } - ] - }, - "status": "" - }, - "1": { - "$schema": "https://schema.berlin.de/queuemanagement/process.json", - "amendment": "", - "appointments": [ - { - "scope": { - "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", - "id": "141", - "contact": { - "name": "Bürgeramt Heerstraße", - "street": "Heerstr. 12, 14052 Berlin", - "email": "", - "country": "Germany" - }, - "preferences": { - "appointment": { - "deallocationDuration": "10", - "infoForAppointment": "", - "endInDaysDefault": "60", - "multipleSlotsEnabled": "0", - "reservationDuration": "20", - "startInDaysDefault": "0" - }, - "client": { - "alternateAppointmentUrl": "", - "amendmentActivated": "0", - "amendmentLabel": "", - "emailRequired": "0", - "telephoneActivated": "0", - "telephoneRequired": "0" - }, - "notifications": { - "confirmationContent": "", - "enabled": "1", - "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", - "headsUpTime": "30" - }, - "pickup": { - "alternateName": "Ausgabe", - "isDefault": "0" - }, - "queue": { - "callCountMax": "0", - "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", - "firstNumber": "1", - "lastNumber": "499", - "processingTimeAverage": "15", - "publishWaitingTimeEnabled": "1", - "statisticsEnabled": "1" - }, - "survey": { - "emailContent": "", - "enabled": "0", - "label": "" - }, - "ticketprinter": { - "confirmationEnabled": "0", - "deactivatedText": "", - "notificationsAmendmentEnabled": "0", - "notificationsDelay": "0" - }, - "workstation": { - "emergencyEnabled": "1" - } - }, - "shortName": "", - "status": { - "emergency": { - "acceptedByWorkstation": "-1", - "activated": "0", - "calledByWorkstation": "-1" - }, - "queue": { - "ghostWorkstationCount": "-1", - "givenNumberCount": "46", - "lastGivenNumber": "47", - "lastGivenNumberTimestamp": "1458774000" - }, - "ticketprinter": { - "deactivated": "0" - } - }, - "provider": { - "id": "122217", - "contact": { - "email": "test@example.com", - "city": "Berlin", - "country": "Germany", - "name": "Bürgeramt Heerstraße", - "postalCode": "14052", - "region": "Berlin", - "street": "Heerstr.", - "streetNumber": "12" - }, - "source": "dldb", - "link": "https://service.berlin.de/standort/122217/", - "name": "Bürgeramt Heerstraße", - "displayName":"001" - }, - "dayoff": [ - { - "date": "1458860400", - "name": "Karfreitag" - }, - { - "date": "1459116000", - "name": "Ostermontag" - }, - { - "date": "1462053600", - "name": "Maifeiertag" - }, - { - "date": "1462399200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1463349600", - "name": "Pfingstmontag" - }, - { - "date": "1475445600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1482620400", - "name": "1. Weihnachtstag" - }, - { - "date": "1482706800", - "name": "2. Weihnachtstag" - }, - { - "date": "1483225200", - "name": "Neujahr" - }, - { - "date": "1492120800", - "name": "Karfreitag" - }, - { - "date": "1492380000", - "name": "Ostermontag" - }, - { - "date": "1493589600", - "name": "Maifeiertag" - }, - { - "date": "1495663200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1496613600", - "name": "Pfingstmontag" - }, - { - "date": "1506981600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1514156400", - "name": "1. Weihnachtstag" - }, - { - "date": "1514242800", - "name": "2. Weihnachtstag" - }, - { - "date": "1514761200", - "name": "Neujahr" - }, - { - "date": "1522360800", - "name": "Karfreitag" - }, - { - "date": "1522620000", - "name": "Ostermontag" - }, - { - "date": "1525125600", - "name": "Maifeiertag" - }, - { - "date": "1525903200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1526853600", - "name": "Pfingstmontag" - }, - { - "date": "1538517600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1545692400", - "name": "1. Weihnachtstag" - }, - { - "date": "1545778800", - "name": "2. Weihnachtstag" - }, - { - "date": "1546297200", - "name": "Neujahr" - }, - { - "date": "1555624800", - "name": "Karfreitag" - }, - { - "date": "1555884000", - "name": "Ostermontag" - }, - { - "date": "1556661600", - "name": "Maifeiertag" - }, - { - "date": "1559167200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1560117600", - "name": "Pfingstmontag" - }, - { - "date": "1570053600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1577228400", - "name": "1. Weihnachtstag" - }, - { - "date": "1577314800", - "name": "2. Weihnachtstag" - }, - { - "date": "1577833200", - "name": "Neujahr" - }, - { - "date": "1586469600", - "name": "Karfreitag" - }, - { - "date": "1586728800", - "name": "Ostermontag" - }, - { - "date": "1588284000", - "name": "Maifeiertag" - }, - { - "date": "1590012000", - "name": "Christi Himmelfahrt" - }, - { - "date": "1590962400", - "name": "Pfingstmontag" - }, - { - "date": "1601676000", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1608850800", - "name": "1. Weihnachtstag" - }, - { - "date": "1608937200", - "name": "2. Weihnachtstag" - }, - { - "date": "1609455600", - "name": "Neujahr" - }, - { - "date": "1617314400", - "name": "Karfreitag" - }, - { - "date": "1617573600", - "name": "Ostermontag" - }, - { - "date": "1619820000", - "name": "Maifeiertag" - }, - { - "date": "1620856800", - "name": "Christi Himmelfahrt" - }, - { - "date": "1621807200", - "name": "Pfingstmontag" - }, - { - "date": "1633212000", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1640386800", - "name": "1. Weihnachtstag" - }, - { - "date": "1640473200", - "name": "2. Weihnachtstag" - }, - { - "date": "1478041200", - "name": "Personalversammlung" - } - ] - }, - "availability": { - "id": "94678", - "weekday": { - "monday": "0", - "tuesday": "0", - "wednesday": "0", - "thursday": "0", - "friday": "32", - "saturday": "0", - "sunday": "0" - }, - "repeat": { - "afterWeeks": "1", - "weekOfMonth": "0" - }, - "bookable": { - "startInDays": "0", - "endInDays": "60" - }, - "workstationCount": { - "public": "2", - "callcenter": "2", - "intern": "2" - }, - "multipleSlotsAllowed": "0", - "slotTimeInMinutes": "10", - "startDate": "1463954400", - "endDate": "1609369200", - "startTime": "08:00:00", - "endTime": "13:50:00", - "type": "appointment", - "scope": { - "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", - "id": "141", - "contact": { - "name": "Bürgeramt Heerstraße", - "street": "Heerstr. 12, 14052 Berlin", - "email": "", - "country": "Germany" - }, - "preferences": { - "appointment": { - "deallocationDuration": "10", - "infoForAppointment": "", - "endInDaysDefault": "60", - "multipleSlotsEnabled": "0", - "reservationDuration": "20", - "startInDaysDefault": "0" - }, - "client": { - "alternateAppointmentUrl": "", - "amendmentActivated": "0", - "amendmentLabel": "", - "emailRequired": "0", - "telephoneActivated": "0", - "telephoneRequired": "0" - }, - "notifications": { - "confirmationContent": "", - "enabled": "1", - "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", - "headsUpTime": "30" - }, - "pickup": { - "alternateName": "Ausgabe", - "isDefault": "0" - }, - "queue": { - "callCountMax": "0", - "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", - "firstNumber": "1", - "lastNumber": "499", - "processingTimeAverage": "15", - "publishWaitingTimeEnabled": "1", - "statisticsEnabled": "1" - }, - "survey": { - "emailContent": "", - "enabled": "0", - "label": "" - }, - "ticketprinter": { - "confirmationEnabled": "0", - "deactivatedText": "", - "notificationsAmendmentEnabled": "0", - "notificationsDelay": "0" - }, - "workstation": { - "emergencyEnabled": "1" - } - }, - "shortName": "", - "status": { - "emergency": { - "acceptedByWorkstation": "-1", - "activated": "0", - "calledByWorkstation": "-1" - }, - "queue": { - "ghostWorkstationCount": "-1", - "givenNumberCount": "46", - "lastGivenNumber": "47", - "lastGivenNumberTimestamp": "1458774000" - }, - "ticketprinter": { - "deactivated": "0" - } - }, - "provider": { - "id": "122217", - "contact": { - "email": "test@example.com", - "city": "Berlin", - "country": "Germany", - "name": "Bürgeramt Heerstraße", - "postalCode": "14052", - "region": "Berlin", - "street": "Heerstr.", - "streetNumber": "12" - }, - "source": "dldb", - "link": "https://service.berlin.de/standort/122217/", - "name": "Bürgeramt Heerstraße", - "displayName":"001" - }, - "dayoff": [ - { - "date": "1458860400", - "name": "Karfreitag" - }, - { - "date": "1459116000", - "name": "Ostermontag" - }, - { - "date": "1462053600", - "name": "Maifeiertag" - }, - { - "date": "1462399200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1463349600", - "name": "Pfingstmontag" - }, - { - "date": "1475445600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1482620400", - "name": "1. Weihnachtstag" - }, - { - "date": "1482706800", - "name": "2. Weihnachtstag" - }, - { - "date": "1483225200", - "name": "Neujahr" - }, - { - "date": "1492120800", - "name": "Karfreitag" - }, - { - "date": "1492380000", - "name": "Ostermontag" - }, - { - "date": "1493589600", - "name": "Maifeiertag" - }, - { - "date": "1495663200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1496613600", - "name": "Pfingstmontag" - }, - { - "date": "1506981600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1514156400", - "name": "1. Weihnachtstag" - }, - { - "date": "1514242800", - "name": "2. Weihnachtstag" - }, - { - "date": "1514761200", - "name": "Neujahr" - }, - { - "date": "1522360800", - "name": "Karfreitag" - }, - { - "date": "1522620000", - "name": "Ostermontag" - }, - { - "date": "1525125600", - "name": "Maifeiertag" - }, - { - "date": "1525903200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1526853600", - "name": "Pfingstmontag" - }, - { - "date": "1538517600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1545692400", - "name": "1. Weihnachtstag" - }, - { - "date": "1545778800", - "name": "2. Weihnachtstag" - }, - { - "date": "1546297200", - "name": "Neujahr" - }, - { - "date": "1555624800", - "name": "Karfreitag" - }, - { - "date": "1555884000", - "name": "Ostermontag" - }, - { - "date": "1556661600", - "name": "Maifeiertag" - }, - { - "date": "1559167200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1560117600", - "name": "Pfingstmontag" - }, - { - "date": "1570053600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1577228400", - "name": "1. Weihnachtstag" - }, - { - "date": "1577314800", - "name": "2. Weihnachtstag" - }, - { - "date": "1577833200", - "name": "Neujahr" - }, - { - "date": "1586469600", - "name": "Karfreitag" - }, - { - "date": "1586728800", - "name": "Ostermontag" - }, - { - "date": "1588284000", - "name": "Maifeiertag" - }, - { - "date": "1590012000", - "name": "Christi Himmelfahrt" - }, - { - "date": "1590962400", - "name": "Pfingstmontag" - }, - { - "date": "1601676000", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1608850800", - "name": "1. Weihnachtstag" - }, - { - "date": "1608937200", - "name": "2. Weihnachtstag" - }, - { - "date": "1609455600", - "name": "Neujahr" - }, - { - "date": "1617314400", - "name": "Karfreitag" - }, - { - "date": "1617573600", - "name": "Ostermontag" - }, - { - "date": "1619820000", - "name": "Maifeiertag" - }, - { - "date": "1620856800", - "name": "Christi Himmelfahrt" - }, - { - "date": "1621807200", - "name": "Pfingstmontag" - }, - { - "date": "1633212000", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1640386800", - "name": "1. Weihnachtstag" - }, - { - "date": "1640473200", - "name": "2. Weihnachtstag" - }, - { - "date": "1478041200", - "name": "Personalversammlung" - } - ] - } - }, - "slotCount": 1, - "date": "1464342000" - } - ], - "authKey": "", - "createIP": "", - "createTimestamp": "", - "id": 0, - "reminderTimestamp": 0, - "requests": [ - { - "id": "999999", - "link": "https://service.berlin.de/dienstleistung/999999/", - "name": "Unit test request", - "source": "dldb" - } - ], - "scope": { - "hint": "Bürgeramt | Nr. wird zum Termin aufgerufen", - "id": "141", - "contact": { - "name": "Bürgeramt Heerstraße", - "street": "Heerstr. 12, 14052 Berlin", - "email": "", - "country": "Germany" - }, - "preferences": { - "appointment": { - "deallocationDuration": "10", - "infoForAppointment": "", - "endInDaysDefault": "60", - "multipleSlotsEnabled": "0", - "reservationDuration": "20", - "startInDaysDefault": "0" - }, - "client": { - "alternateAppointmentUrl": "", - "amendmentActivated": "0", - "amendmentLabel": "", - "emailRequired": "0", - "telephoneActivated": "0", - "telephoneRequired": "0" - }, - "notifications": { - "confirmationContent": "", - "enabled": "1", - "headsUpContent": "Ihre Wartezeit beträgt noch ca. 30 Min., bitte informieren Sie sich über die Aufrufanzeige im Bürgeramt, in welchem Raum Sie erwartet werden. Wartenr:", - "headsUpTime": "30" - }, - "pickup": { - "alternateName": "Ausgabe", - "isDefault": "0" - }, - "queue": { - "callCountMax": "0", - "callDisplayText": "Herzlich Willkommen \r\nin Charlottenburg-Wilmersdorf\r\n=====================\r\nTIP: Termin statt Wartezeit!\r\n=====================\r\nNutzen Sie die Online Terminvergabe unter:\r\nhttp://www.berlin.de/ba-charlottenburg-wilmersdorf/org/buergerdienste/buergeraemter.html", - "firstNumber": "1", - "lastNumber": "499", - "processingTimeAverage": "15", - "publishWaitingTimeEnabled": "1", - "statisticsEnabled": "1" - }, - "survey": { - "emailContent": "", - "enabled": "0", - "label": "" - }, - "ticketprinter": { - "confirmationEnabled": "0", - "deactivatedText": "", - "notificationsAmendmentEnabled": "0", - "notificationsDelay": "0" - }, - "workstation": { - "emergencyEnabled": "1" - } - }, - "shortName": "", - "status": { - "emergency": { - "acceptedByWorkstation": "-1", - "activated": "0", - "calledByWorkstation": "-1" - }, - "queue": { - "ghostWorkstationCount": "-1", - "givenNumberCount": "46", - "lastGivenNumber": "47", - "lastGivenNumberTimestamp": "1458774000" - }, - "ticketprinter": { - "deactivated": "0" - } - }, - "provider": { - "id": "122217", - "source": "dldb", - "contact": { - "city": "Berlin", - "country": "Germany", - "name": "Bürgeramt Heerstraße", - "postalCode": "14052", - "region": "Berlin", - "street": "Heerstr.", - "streetNumber": "12" - }, - "link": "https://service.berlin.de/standort/122217/", - "name": "Bürgeramt Heerstraße", - "displayName":"001" - }, - "dayoff": [ - { - "date": "1458860400", - "name": "Karfreitag" - }, - { - "date": "1459116000", - "name": "Ostermontag" - }, - { - "date": "1462053600", - "name": "Maifeiertag" - }, - { - "date": "1462399200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1463349600", - "name": "Pfingstmontag" - }, - { - "date": "1475445600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1482620400", - "name": "1. Weihnachtstag" - }, - { - "date": "1482706800", - "name": "2. Weihnachtstag" - }, - { - "date": "1483225200", - "name": "Neujahr" - }, - { - "date": "1492120800", - "name": "Karfreitag" - }, - { - "date": "1492380000", - "name": "Ostermontag" - }, - { - "date": "1493589600", - "name": "Maifeiertag" - }, - { - "date": "1495663200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1496613600", - "name": "Pfingstmontag" - }, - { - "date": "1506981600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1514156400", - "name": "1. Weihnachtstag" - }, - { - "date": "1514242800", - "name": "2. Weihnachtstag" - }, - { - "date": "1514761200", - "name": "Neujahr" - }, - { - "date": "1522360800", - "name": "Karfreitag" - }, - { - "date": "1522620000", - "name": "Ostermontag" - }, - { - "date": "1525125600", - "name": "Maifeiertag" - }, - { - "date": "1525903200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1526853600", - "name": "Pfingstmontag" - }, - { - "date": "1538517600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1545692400", - "name": "1. Weihnachtstag" - }, - { - "date": "1545778800", - "name": "2. Weihnachtstag" - }, - { - "date": "1546297200", - "name": "Neujahr" - }, - { - "date": "1555624800", - "name": "Karfreitag" - }, - { - "date": "1555884000", - "name": "Ostermontag" - }, - { - "date": "1556661600", - "name": "Maifeiertag" - }, - { - "date": "1559167200", - "name": "Christi Himmelfahrt" - }, - { - "date": "1560117600", - "name": "Pfingstmontag" - }, - { - "date": "1570053600", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1577228400", - "name": "1. Weihnachtstag" - }, - { - "date": "1577314800", - "name": "2. Weihnachtstag" - }, - { - "date": "1577833200", - "name": "Neujahr" - }, - { - "date": "1586469600", - "name": "Karfreitag" - }, - { - "date": "1586728800", - "name": "Ostermontag" - }, - { - "date": "1588284000", - "name": "Maifeiertag" - }, - { - "date": "1590012000", - "name": "Christi Himmelfahrt" - }, - { - "date": "1590962400", - "name": "Pfingstmontag" - }, - { - "date": "1601676000", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1608850800", - "name": "1. Weihnachtstag" - }, - { - "date": "1608937200", - "name": "2. Weihnachtstag" - }, - { - "date": "1609455600", - "name": "Neujahr" - }, - { - "date": "1617314400", - "name": "Karfreitag" - }, - { - "date": "1617573600", - "name": "Ostermontag" - }, - { - "date": "1619820000", - "name": "Maifeiertag" - }, - { - "date": "1620856800", - "name": "Christi Himmelfahrt" - }, - { - "date": "1621807200", - "name": "Pfingstmontag" - }, - { - "date": "1633212000", - "name": "Tag der Deutschen Einheit" - }, - { - "date": "1640386800", - "name": "1. Weihnachtstag" - }, - { - "date": "1640473200", - "name": "2. Weihnachtstag" - }, - { - "date": "1478041200", - "name": "Personalversammlung" - } - ] - }, - "status": "" - } - } diff --git a/zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_reserve_timeslot.json b/zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_reserve_timeslot.json index 653d8bc02..f3d8f1840 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_reserve_timeslot.json +++ b/zmscitizenapi/tests/Zmscitizenapi/fixtures/POST_reserve_timeslot.json @@ -57,6 +57,7 @@ "shortname": "default" }, "authKey": "b93e", + "displayInfo": "Infos zum Standort.", "clients": [ { "familyName": "", @@ -70,6 +71,7 @@ "createIP": "", "createTimestamp": 1727189317, "id": "101142", + "serviceCount": 1, "archiveId": 0, "queue": { "$schema": "https:\/\/schema.berlin.de\/queuemanagement\/queue.json", From 0b9cc6e3ee2a96782cb148d2c058293ff2eeb315 Mon Sep 17 00:00:00 2001 From: Thomas Fink Date: Thu, 26 Sep 2024 14:34:15 +0200 Subject: [PATCH 06/10] feat(ZMS-2517): add more unit tests for validations --- .../Controllers/AppointmentReserve.php | 85 ++++-- .../Zmscitizenapi/AppointmentReserveTest.php | 242 +++++++++++++++++- 2 files changed, 306 insertions(+), 21 deletions(-) diff --git a/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php b/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php index 4668de9f7..25c2aa7ff 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php +++ b/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php @@ -40,20 +40,7 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo { $request = $request instanceof ServerRequestInterface ? $request : null; - if (!$request) { - return $this->createJsonResponse($response, [ - 'error' => 'Invalid request object', - 'status' => 400 - ], 400); - } - $body = $request->getParsedBody(); - if (is_null($body)) { - return $this->createJsonResponse($response, [ - 'error' => 'Invalid or missing request body', - 'status' => 400 - ], 400); - } $officeId = $body['officeId'] ?? null; $serviceIds = $body['serviceId'] ?? []; @@ -61,9 +48,59 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo $captchaSolution = $body['captchaSolution'] ?? null; $timestamp = $body['timestamp'] ?? null; - if (!$officeId || empty($serviceIds) || !$timestamp) { + $errors = []; + + if (!$officeId) { + $errors[] = [ + 'type' => 'field', + 'msg' => 'Missing officeId.', + 'path' => 'officeId', + 'location' => 'body' + ]; + } elseif (!is_numeric($officeId)) { + $errors[] = [ + 'type' => 'field', + 'msg' => 'Invalid officeId format. It should be a numeric value.', + 'path' => 'officeId', + 'location' => 'body' + ]; + } + + if (empty($serviceIds)) { + $errors[] = [ + 'type' => 'field', + 'msg' => 'Missing serviceId.', + 'path' => 'serviceId', + 'location' => 'body' + ]; + } elseif (!is_array($serviceIds) || array_filter($serviceIds, fn($id) => !is_numeric($id))) { + $errors[] = [ + 'type' => 'field', + 'msg' => 'Invalid serviceId format. It should be an array of numeric values.', + 'path' => 'serviceId', + 'location' => 'body' + ]; + } + + if (!$timestamp) { + $errors[] = [ + 'type' => 'field', + 'msg' => 'Missing timestamp.', + 'path' => 'timestamp', + 'location' => 'body' + ]; + } elseif (!is_numeric($timestamp) || $timestamp < 0) { + $errors[] = [ + 'type' => 'field', + 'msg' => 'Invalid timestamp format. It should be a positive numeric value.', + 'path' => 'timestamp', + 'location' => 'body' + ]; + } + + if (!empty($errors)) { return $this->createJsonResponse($response, [ - 'error' => 'Missing required fields', + 'errors' => $errors, 'status' => 400 ], 400); } @@ -88,6 +125,16 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo return $this->createJsonResponse($response, $serviceValidationResult, 400); } + try { + $internalDate = $this->utilityHelper->getInternalDateFromTimestamp($timestamp); + } catch (\Exception $e) { + return $this->createJsonResponse($response, [ + 'errorCode' => 'invalidTimestamp', + 'errorMessage' => 'The provided timestamp is invalid.', + 'lastModified' => round(microtime(true) * 1000) + ], 400); + } + $freeAppointments = $this->availableAppointmentsService->getFreeAppointments([ 'officeId' => $officeId, 'serviceIds' => $serviceIds, @@ -122,15 +169,15 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo if ($reservedProcess && $reservedProcess->scope && $reservedProcess->scope->id) { $scopeIds = [$reservedProcess->scope->id]; $scopesData = $this->scopesService->getScopeByIds($scopeIds); - + if ($scopesData['status'] === 200 && isset($scopesData['scopes']['scopes']) && !empty($scopesData['scopes']['scopes'])) { $reservedProcess->scope = $this->scopesService->mapScope($scopesData['scopes']['scopes'][0]); } - } - + } + $thinnedProcessData = $this->appointmentService->getThinnedProcessData($reservedProcess); $thinnedProcessData = array_merge($thinnedProcessData, ['officeId' => $officeId]); - + return $this->createJsonResponse($response, $thinnedProcessData, 200); } catch (\Exception $e) { diff --git a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php index 354c69fb5..cdad8bfd9 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php @@ -27,7 +27,7 @@ public function testRendering() ], [ 'function' => 'readPostResult', - 'url' => '/process/status/reserved/', + 'url' => '/process/status/reserved/', 'response' => $this->readFixture("POST_reserve_timeslot.json") ] ] @@ -42,7 +42,7 @@ public function testRendering() ]; $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string)$response->getBody(), true); + $responseBody = json_decode((string) $response->getBody(), true); $this->assertEquals(200, $response->getStatusCode(), 'Expected a 200 OK response.'); $this->assertArrayHasKey('processId', $responseBody, 'Expected processId in response.'); $this->assertArrayHasKey('email', $responseBody, 'Expected email in response.'); @@ -57,4 +57,242 @@ public function testRendering() $this->assertArrayHasKey('serviceCount', $responseBody, 'Expected serviceCount in response.'); $this->assertEquals(0, $responseBody['serviceCount'], 'Expected serviceCount to be 0.'); } + + public function testAppointmentNotAvailable() + { + $this->setApiCalls( + [ + [ + 'function' => 'readGetResult', + 'url' => '/source/unittest/', + 'parameters' => [ + 'resolveReferences' => 2, + ], + 'response' => $this->readFixture("GET_reserve_SourceGet_dldb.json"), + ], + [ + 'function' => 'readPostResult', + 'url' => '/process/status/free/', + 'response' => $this->readFixture("GET_appointments_free.json") + ] + ] + ); + + $parameters = [ + 'officeId' => '10546', + 'serviceId' => ['1063423'], + 'serviceCount' => [0], + 'timestamp' => "32526616300", + 'captchaSolution' => null + ]; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string) $response->getBody(), true); + + $this->assertEquals(404, $response->getStatusCode(), 'Expected a 404 Not Found response.'); + $this->assertArrayHasKey('errorCode', $responseBody, 'Expected errorCode in response.'); + $this->assertEquals('appointmentNotAvailable', $responseBody['errorCode'], 'Expected errorCode to be appointmentNotAvailable.'); + $this->assertArrayHasKey('errorMessage', $responseBody, 'Expected errorMessage in response.'); + } + + public function testMissingOfficeId() + { + $this->setApiCalls([]); + + $parameters = [ + 'serviceId' => ['1063423'], + 'serviceCount' => [0], + 'timestamp' => "32526616522", + 'captchaSolution' => null + ]; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string) $response->getBody(), true); + + $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); + $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); + $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); + $this->assertEquals('Missing officeId.', $responseBody['errors'][0]['msg'], 'Expected error message for missing officeId.'); + } + + public function testMissingServiceId() + { + $this->setApiCalls([]); + + $parameters = [ + 'officeId' => '10546', + 'serviceCount' => [0], + 'timestamp' => "32526616522", + 'captchaSolution' => null + ]; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string) $response->getBody(), true); + + $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); + $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); + $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); + $this->assertEquals('Missing serviceId.', $responseBody['errors'][0]['msg'], 'Expected error message for missing serviceId.'); + } + + public function testMissingTimestamp() + { + $this->setApiCalls([]); + + $parameters = [ + 'officeId' => '10546', + 'serviceId' => ['1063423'], + 'serviceCount' => [0], + 'captchaSolution' => null + ]; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string) $response->getBody(), true); + + $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); + $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); + $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); + $this->assertEquals('Missing timestamp.', $responseBody['errors'][0]['msg'], 'Expected error message for missing timestamp.'); + } + + public function testMissingOfficeIdAndServiceId() + { + $this->setApiCalls([]); + + $parameters = [ + 'serviceCount' => [0], + 'timestamp' => "32526616522", + 'captchaSolution' => null + ]; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string) $response->getBody(), true); + + $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); + $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); + $this->assertCount(2, $responseBody['errors'], 'Expected two errors in response.'); + $this->assertEquals('Missing officeId.', $responseBody['errors'][0]['msg'], 'Expected error message for missing officeId.'); + $this->assertEquals('Missing serviceId.', $responseBody['errors'][1]['msg'], 'Expected error message for missing serviceId.'); + } + + public function testMissingOfficeIdAndTimestamp() + { + $this->setApiCalls([]); + + $parameters = [ + 'serviceId' => ['1063423'], + 'serviceCount' => [0], + 'captchaSolution' => null + ]; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string) $response->getBody(), true); + + $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); + $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); + $this->assertCount(2, $responseBody['errors'], 'Expected two errors in response.'); + $this->assertEquals('Missing officeId.', $responseBody['errors'][0]['msg'], 'Expected error message for missing officeId.'); + $this->assertEquals('Missing timestamp.', $responseBody['errors'][1]['msg'], 'Expected error message for missing timestamp.'); + } + + public function testMissingServiceIdAndTimestamp() + { + $this->setApiCalls([]); + + $parameters = [ + 'officeId' => '10546', + 'serviceCount' => [0], + 'captchaSolution' => null + ]; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string) $response->getBody(), true); + + $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); + $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); + $this->assertCount(2, $responseBody['errors'], 'Expected two errors in response.'); + $this->assertEquals('Missing serviceId.', $responseBody['errors'][0]['msg'], 'Expected error message for missing serviceId.'); + $this->assertEquals('Missing timestamp.', $responseBody['errors'][1]['msg'], 'Expected error message for missing timestamp.'); + } + + public function testMissingAllFields() + { + $this->setApiCalls([]); + + $parameters = []; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string) $response->getBody(), true); + + $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); + $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); + $this->assertCount(3, $responseBody['errors'], 'Expected three errors in response.'); + $this->assertEquals('Missing officeId.', $responseBody['errors'][0]['msg'], 'Expected error message for missing officeId.'); + $this->assertEquals('Missing serviceId.', $responseBody['errors'][1]['msg'], 'Expected error message for missing serviceId.'); + $this->assertEquals('Missing timestamp.', $responseBody['errors'][2]['msg'], 'Expected error message for missing timestamp.'); + } + + public function testInvalidOfficeIdFormat() + { + $this->setApiCalls([]); + + $parameters = [ + 'officeId' => 'invalid_id', + 'serviceId' => ['1063423'], + 'serviceCount' => [0], + 'timestamp' => "32526616522", + 'captchaSolution' => null + ]; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string) $response->getBody(), true); + + $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); + $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); + $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); + $this->assertEquals('Invalid officeId format. It should be a numeric value.', $responseBody['errors'][0]['msg'], 'Expected error message for invalid officeId format.'); + } + + public function testInvalidServiceIdFormat() + { + $this->setApiCalls([]); + + $parameters = [ + 'officeId' => '10546', + 'serviceId' => ['invalid_service_id'], + 'serviceCount' => [0], + 'timestamp' => "32526616522", + 'captchaSolution' => null + ]; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string) $response->getBody(), true); + + $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); + $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); + $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); + $this->assertEquals('Invalid serviceId format. It should be an array of numeric values.', $responseBody['errors'][0]['msg'], 'Expected error message for invalid serviceId format.'); + } + + public function testInvalidTimestampFormat() + { + $this->setApiCalls([]); + + $parameters = [ + 'officeId' => '10546', + 'serviceId' => ['1063423'], + 'serviceCount' => [0], + 'timestamp' => 'invalid_timestamp', + 'captchaSolution' => null + ]; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string) $response->getBody(), true); + + $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); + $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); + $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); + $this->assertEquals('Invalid timestamp format. It should be a positive numeric value.', $responseBody['errors'][0]['msg'], 'Expected error message for invalid timestamp format.'); + } + } From b4aff8d7f0454cbc1912234e0747ec2d6ed8c1aa Mon Sep 17 00:00:00 2001 From: Thomas Fink Date: Thu, 26 Sep 2024 14:45:15 +0200 Subject: [PATCH 07/10] feat(ZMS-2517): add more unit tests for validations --- .../Controllers/AppointmentReserve.php | 9 ++++ .../Zmscitizenapi/AppointmentReserveTest.php | 41 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php b/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php index 25c2aa7ff..db42a00c2 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php +++ b/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentReserve.php @@ -98,6 +98,15 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo ]; } + if (!is_array($serviceCounts) || array_filter($serviceCounts, fn($count) => !is_numeric($count) || $count < 0)) { + $errors[] = [ + 'type' => 'field', + 'msg' => 'Invalid serviceCount format. It should be an array of non-negative numeric values.', + 'path' => 'serviceCount', + 'location' => 'body' + ]; + } + if (!empty($errors)) { return $this->createJsonResponse($response, [ 'errors' => $errors, diff --git a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php index cdad8bfd9..c81afcd6e 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php @@ -294,5 +294,46 @@ public function testInvalidTimestampFormat() $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); $this->assertEquals('Invalid timestamp format. It should be a positive numeric value.', $responseBody['errors'][0]['msg'], 'Expected error message for invalid timestamp format.'); } + public function testEmptyServiceIdArray() + { + $this->setApiCalls([]); + + $parameters = [ + 'officeId' => '10546', + 'serviceId' => [], + 'serviceCount' => [0], + 'timestamp' => "32526616522", + 'captchaSolution' => null + ]; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string) $response->getBody(), true); + + $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); + $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); + $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); + $this->assertEquals('Missing serviceId.', $responseBody['errors'][0]['msg'], 'Expected error message for empty serviceId array.'); + } + + public function testInvalidServiceCount() + { + $this->setApiCalls([]); + + $parameters = [ + 'officeId' => '10546', + 'serviceId' => ['1063423'], + 'serviceCount' => ['invalid'], + 'timestamp' => "32526616522", + 'captchaSolution' => null + ]; + + $response = $this->render([], $parameters, [], 'POST'); + $responseBody = json_decode((string) $response->getBody(), true); + + $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); + $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); + $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); + $this->assertEquals('Invalid serviceCount format. It should be an array of non-negative numeric values.', $responseBody['errors'][0]['msg'], 'Expected error message for invalid serviceCount.'); + } } From 8213ef535a21693d060b4168c24f24cfe3b9beab Mon Sep 17 00:00:00 2001 From: Thomas Fink Date: Thu, 26 Sep 2024 15:30:17 +0200 Subject: [PATCH 08/10] feat(ZMS-2517): Zmscitizenapi Refactor Part 1 of 3 move controllers back to root --- zmscitizenapi/routing.php | 32 +++++++++---------- .../{Controllers => }/AppointmentCancel.php | 2 +- .../{Controllers => }/AppointmentConfirm.php | 2 +- .../{Controllers => }/AppointmentGet.php | 2 +- .../AppointmentPreconfirm.php | 2 +- .../{Controllers => }/AppointmentReserve.php | 2 +- .../{Controllers => }/AppointmentUpdate.php | 2 +- .../AvailableAppointmentsList.php | 2 +- .../{Controllers => }/AvailableDaysList.php | 2 +- .../{Controllers => }/CaptchaGet.php | 2 +- .../OfficesByServiceList.php | 2 +- .../{Controllers => }/OfficesList.php | 2 +- .../OfficesServicesRelations.php | 2 +- .../{Controllers => }/ScopeByIdGet.php | 2 +- .../{Controllers => }/ScopesList.php | 2 +- .../ServicesByOfficeList.php | 2 +- .../{Controllers => }/ServicesList.php | 2 +- .../Zmscitizenapi/AppointmentCancelTest.php | 2 +- .../Zmscitizenapi/AppointmentConfirmTest.php | 2 +- .../Zmscitizenapi/AppointmentGetTest.php | 2 +- .../AppointmentPreconfirmTest.php | 2 +- .../Zmscitizenapi/AppointmentReserveTest.php | 2 +- .../Zmscitizenapi/AppointmentUpdateTest.php | 2 +- .../AvailableAppointmentsListTest.php | 2 +- .../Zmscitizenapi/AvailableDaysListTest.php | 2 +- .../tests/Zmscitizenapi/CaptchaGetTest.php | 2 +- .../OfficesByServiceListTest.php | 2 +- .../tests/Zmscitizenapi/OfficesListTest.php | 2 +- .../OfficesServicesRelationsTest.php | 2 +- .../tests/Zmscitizenapi/ScopeByIdGetTest.php | 2 +- .../tests/Zmscitizenapi/ScopesListTest.php | 2 +- .../ServicesByOfficeListTest.php | 2 +- .../tests/Zmscitizenapi/ServicesListTest.php | 2 +- 33 files changed, 48 insertions(+), 48 deletions(-) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/AppointmentCancel.php (90%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/AppointmentConfirm.php (89%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/AppointmentGet.php (95%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/AppointmentPreconfirm.php (90%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/AppointmentReserve.php (99%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/AppointmentUpdate.php (89%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/AvailableAppointmentsList.php (95%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/AvailableDaysList.php (94%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/CaptchaGet.php (93%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/OfficesByServiceList.php (95%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/OfficesList.php (93%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/OfficesServicesRelations.php (95%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/ScopeByIdGet.php (95%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/ScopesList.php (93%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/ServicesByOfficeList.php (95%) rename zmscitizenapi/src/Zmscitizenapi/{Controllers => }/ServicesList.php (93%) diff --git a/zmscitizenapi/routing.php b/zmscitizenapi/routing.php index d95628c82..20d94efed 100644 --- a/zmscitizenapi/routing.php +++ b/zmscitizenapi/routing.php @@ -24,7 +24,7 @@ */ \App::$slim->get( '/services/', - '\BO\Zmscitizenapi\Controllers\ServicesList' + 'ServicesList' ) ->setName("ServicesList"); @@ -48,7 +48,7 @@ */ \App::$slim->get( '/scopes/', - '\BO\Zmscitizenapi\Controllers\ScopesList' + 'ScopesList' ) ->setName("ScopesList"); @@ -72,7 +72,7 @@ */ \App::$slim->get( '/offices/', - '\BO\Zmscitizenapi\Controllers\OfficesList' + 'OfficesList' ) ->setName("OfficesList"); @@ -96,7 +96,7 @@ */ \App::$slim->get( '/offices-and-services/', - '\BO\Zmscitizenapi\Controllers\OfficesServicesRelations' + 'OfficesServicesRelations' ) ->setName("OfficesServicesRelations"); @@ -128,7 +128,7 @@ */ \App::$slim->get( '/scope-by-id/', - '\BO\Zmscitizenapi\Controllers\ScopeByIdGet' + 'ScopeByIdGet' ) ->setName("ScopeByIdGet"); @@ -158,7 +158,7 @@ */ \App::$slim->get( '/services-by-office/', - '\BO\Zmscitizenapi\Controllers\ServicesByOfficeList' + 'ServicesByOfficeList' ) ->setName("ServicesByOfficeList"); @@ -188,7 +188,7 @@ */ \App::$slim->get( '/offices-by-service/', - '\BO\Zmscitizenapi\Controllers\OfficesByServiceList' + 'OfficesByServiceList' ) ->setName("OfficesByServiceList"); @@ -223,7 +223,7 @@ */ \App::$slim->get( '/available-days/', - '\BO\Zmscitizenapi\Controllers\AvailableDaysList' + 'AvailableDaysList' ) ->setName("AvailableDaysList"); @@ -263,7 +263,7 @@ */ \App::$slim->get( '/available-appointments/', - '\BO\Zmscitizenapi\Controllers\AvailableAppointmentsList' + 'AvailableAppointmentsList' ) ->setName("AvailableAppointmentsList"); @@ -318,7 +318,7 @@ */ \App::$slim->get( '/appointment/', - '\BO\Zmscitizenapi\Controllers\AppointmentGet' + 'AppointmentGet' ) ->setName("AppointmentGet"); @@ -342,7 +342,7 @@ */ \App::$slim->get( '/captcha-details/', - '\BO\Zmscitizenapi\Controllers\CaptchaGet' + 'CaptchaGet' ) ->setName("CaptchaGet"); @@ -393,7 +393,7 @@ */ \App::$slim->post( '/reserve-appointment/', - '\BO\Zmscitizenapi\Controllers\AppointmentReserve' + 'AppointmentReserve' ) ->setName("AppointmentReserve"); @@ -444,7 +444,7 @@ */ \App::$slim->post( '/update-appointment/', - '\BO\Zmscitizenapi\Controllers\AppointmentUpdate' + 'AppointmentUpdate' ) ->setName("AppointmentUpdate"); @@ -495,7 +495,7 @@ */ \App::$slim->post( '/confirm-appointment/', - '\BO\Zmscitizenapi\Controllers\AppointmentConfirm' + 'AppointmentConfirm' ) ->setName("AppointmentConfirm"); @@ -546,7 +546,7 @@ */ \App::$slim->post( '/preconfirm-appointment/', - '\BO\Zmscitizenapi\Controllers\AppointmentPreconfirm' + 'AppointmentPreconfirm' ) ->setName("AppointmentPreconfirm"); @@ -597,6 +597,6 @@ */ \App::$slim->post( '/cancel-appointment/', - '\BO\Zmscitizenapi\Controllers\AppointmentCancel' + 'AppointmentCancel' ) ->setName("AppointmentCancel"); diff --git a/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentCancel.php b/zmscitizenapi/src/Zmscitizenapi/AppointmentCancel.php similarity index 90% rename from zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentCancel.php rename to zmscitizenapi/src/Zmscitizenapi/AppointmentCancel.php index 482c67655..bd7e6c06f 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Controllers/AppointmentCancel.php +++ b/zmscitizenapi/src/Zmscitizenapi/AppointmentCancel.php @@ -1,6 +1,6 @@ renderJson(method: 'POST'); diff --git a/zmscitizenapi/tests/Zmscitizenapi/AppointmentConfirmTest.php b/zmscitizenapi/tests/Zmscitizenapi/AppointmentConfirmTest.php index 1a9b3f917..04d3d9e25 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AppointmentConfirmTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AppointmentConfirmTest.php @@ -4,7 +4,7 @@ class AppointmentConfirmTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\AppointmentConfirm"; + protected $classname = "AppointmentConfirm"; public function testRendering() { $responseData = $this->renderJson(method: 'POST'); diff --git a/zmscitizenapi/tests/Zmscitizenapi/AppointmentGetTest.php b/zmscitizenapi/tests/Zmscitizenapi/AppointmentGetTest.php index 3710bcc3a..1b5c757d4 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AppointmentGetTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AppointmentGetTest.php @@ -6,7 +6,7 @@ class AppointmentGetTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\AppointmentGet"; + protected $classname = "AppointmentGet"; public function testRendering() { diff --git a/zmscitizenapi/tests/Zmscitizenapi/AppointmentPreconfirmTest.php b/zmscitizenapi/tests/Zmscitizenapi/AppointmentPreconfirmTest.php index 4d65b967d..3208be31f 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AppointmentPreconfirmTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AppointmentPreconfirmTest.php @@ -5,7 +5,7 @@ class AppointmentPreconfirmTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\AppointmentPreconfirm"; + protected $classname = "AppointmentPreconfirm"; public function testRendering() { $responseData = $this->renderJson(method: 'POST'); diff --git a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php index c81afcd6e..17c8f45de 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php @@ -6,7 +6,7 @@ class AppointmentReserveTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\AppointmentReserve"; + protected $classname = "AppointmentReserve"; public function testRendering() { diff --git a/zmscitizenapi/tests/Zmscitizenapi/AppointmentUpdateTest.php b/zmscitizenapi/tests/Zmscitizenapi/AppointmentUpdateTest.php index 2dd462f85..48279fd9f 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AppointmentUpdateTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AppointmentUpdateTest.php @@ -5,7 +5,7 @@ class AppointmentUpdateTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\AppointmentUpdate"; + protected $classname = "AppointmentUpdate"; public function testRendering() { $responseData = $this->renderJson(method: 'POST'); diff --git a/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php b/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php index 8c8bf2c07..a807edc11 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php @@ -4,7 +4,7 @@ class AvailableAppointmentsListTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\AvailableAppointmentsList"; + protected $classname = "AvailableAppointmentsList"; public function testRendering() { diff --git a/zmscitizenapi/tests/Zmscitizenapi/AvailableDaysListTest.php b/zmscitizenapi/tests/Zmscitizenapi/AvailableDaysListTest.php index bd3113305..2e5b316d7 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AvailableDaysListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AvailableDaysListTest.php @@ -4,7 +4,7 @@ class AvailableDaysListTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\AvailableDaysList"; + protected $classname = "AvailableDaysList"; public function testRendering() { diff --git a/zmscitizenapi/tests/Zmscitizenapi/CaptchaGetTest.php b/zmscitizenapi/tests/Zmscitizenapi/CaptchaGetTest.php index 010151f73..f592448a3 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/CaptchaGetTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/CaptchaGetTest.php @@ -7,7 +7,7 @@ class CaptchaGetTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\CaptchaGet"; + protected $classname = "CaptchaGet"; public function setUp(): void { diff --git a/zmscitizenapi/tests/Zmscitizenapi/OfficesByServiceListTest.php b/zmscitizenapi/tests/Zmscitizenapi/OfficesByServiceListTest.php index 182e4b545..d911186b1 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/OfficesByServiceListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/OfficesByServiceListTest.php @@ -5,7 +5,7 @@ class OfficesByServiceListTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\OfficesByServiceList"; + protected $classname = "OfficesByServiceList"; public function testRendering() { diff --git a/zmscitizenapi/tests/Zmscitizenapi/OfficesListTest.php b/zmscitizenapi/tests/Zmscitizenapi/OfficesListTest.php index 06c9ee1de..deba791d7 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/OfficesListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/OfficesListTest.php @@ -5,7 +5,7 @@ class OfficesListTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\OfficesList"; + protected $classname = "OfficesList"; public function testRendering() { $this->setApiCalls([ diff --git a/zmscitizenapi/tests/Zmscitizenapi/OfficesServicesRelationsTest.php b/zmscitizenapi/tests/Zmscitizenapi/OfficesServicesRelationsTest.php index b312125cf..b6790002b 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/OfficesServicesRelationsTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/OfficesServicesRelationsTest.php @@ -5,7 +5,7 @@ class OfficesServicesRelationsTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\OfficesServicesRelations"; + protected $classname = "OfficesServicesRelations"; public function testRendering() { diff --git a/zmscitizenapi/tests/Zmscitizenapi/ScopeByIdGetTest.php b/zmscitizenapi/tests/Zmscitizenapi/ScopeByIdGetTest.php index 48e0e4f09..e9ede5fab 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/ScopeByIdGetTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/ScopeByIdGetTest.php @@ -7,7 +7,7 @@ class ScopeByIdGetTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\ScopeByIdGet"; + protected $classname = "ScopeByIdGet"; public function testRendering() { diff --git a/zmscitizenapi/tests/Zmscitizenapi/ScopesListTest.php b/zmscitizenapi/tests/Zmscitizenapi/ScopesListTest.php index f8126ff45..9a308d8a2 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/ScopesListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/ScopesListTest.php @@ -5,7 +5,7 @@ class ScopesListTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\ScopesList"; + protected $classname = "ScopesList"; public function testRendering() { $this->setApiCalls([ diff --git a/zmscitizenapi/tests/Zmscitizenapi/ServicesByOfficeListTest.php b/zmscitizenapi/tests/Zmscitizenapi/ServicesByOfficeListTest.php index cce6908b5..e577a28cf 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/ServicesByOfficeListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/ServicesByOfficeListTest.php @@ -5,7 +5,7 @@ class ServicesByOfficeListTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\ServicesByOfficeList"; + protected $classname = "ServicesByOfficeList"; public function testRendering() { diff --git a/zmscitizenapi/tests/Zmscitizenapi/ServicesListTest.php b/zmscitizenapi/tests/Zmscitizenapi/ServicesListTest.php index aa72571bb..97ce73cbc 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/ServicesListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/ServicesListTest.php @@ -5,7 +5,7 @@ class ServicesListTest extends Base { - protected $classname = "\BO\Zmscitizenapi\Controllers\ServicesList"; + protected $classname = "ServicesList"; public function testRendering() { $this->setApiCalls([ From 73a9d45f1d545dfad5d25941c1c587ac3be9e901 Mon Sep 17 00:00:00 2001 From: Thomas Fink Date: Fri, 27 Sep 2024 10:04:19 +0200 Subject: [PATCH 09/10] feat(ZMS-2517): Zmscitizenapi Refactor Part 2 of 3 create ZmsApiFacadeService ZmsApiClientService ValidationService MapperService UtilityHelper and delete fragmented services --- zmscitizenapi/routing.php | 32 +- .../src/Zmscitizenapi/AppointmentGet.php | 13 +- .../src/Zmscitizenapi/AppointmentReserve.php | 49 +- .../AvailableAppointmentsList.php | 11 +- .../src/Zmscitizenapi/AvailableDaysList.php | 10 +- .../src/Zmscitizenapi/CaptchaGet.php | 8 +- .../Zmscitizenapi/Helper/UtilityHelper.php | 54 +- .../Zmscitizenapi/OfficesByServiceList.php | 10 +- .../src/Zmscitizenapi/OfficesList.php | 11 +- .../OfficesServicesRelations.php | 14 +- .../src/Zmscitizenapi/ScopeByIdGet.php | 11 +- .../src/Zmscitizenapi/ScopesList.php | 11 +- .../Services/AppointmentService.php | 122 ---- .../Services/AvailableAppointmentsService.php | 198 ------ .../Services/AvailableDaysService.php | 99 --- .../Zmscitizenapi/Services/CaptchaService.php | 10 +- .../Zmscitizenapi/Services/MapperService.php | 94 +++ .../Zmscitizenapi/Services/OfficesService.php | 118 --- .../OfficesServicesRelationsService.php | 183 ----- .../Zmscitizenapi/Services/ScopesService.php | 143 ---- .../Services/ServicesService.php | 91 --- .../Services/ValidationService.php | 128 ++++ ...essService.php => ZmsApiClientService.php} | 156 ++-- .../Services/ZmsApiFacadeService.php | 671 ++++++++++++++++++ .../Zmscitizenapi/ServicesByOfficeList.php | 10 +- .../src/Zmscitizenapi/ServicesList.php | 11 +- 26 files changed, 1097 insertions(+), 1171 deletions(-) delete mode 100644 zmscitizenapi/src/Zmscitizenapi/Services/AppointmentService.php delete mode 100644 zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php delete mode 100644 zmscitizenapi/src/Zmscitizenapi/Services/AvailableDaysService.php create mode 100644 zmscitizenapi/src/Zmscitizenapi/Services/MapperService.php delete mode 100644 zmscitizenapi/src/Zmscitizenapi/Services/OfficesService.php delete mode 100644 zmscitizenapi/src/Zmscitizenapi/Services/OfficesServicesRelationsService.php delete mode 100644 zmscitizenapi/src/Zmscitizenapi/Services/ScopesService.php delete mode 100644 zmscitizenapi/src/Zmscitizenapi/Services/ServicesService.php create mode 100644 zmscitizenapi/src/Zmscitizenapi/Services/ValidationService.php rename zmscitizenapi/src/Zmscitizenapi/Services/{ProcessService.php => ZmsApiClientService.php} (51%) create mode 100644 zmscitizenapi/src/Zmscitizenapi/Services/ZmsApiFacadeService.php diff --git a/zmscitizenapi/routing.php b/zmscitizenapi/routing.php index 20d94efed..5060cb8e6 100644 --- a/zmscitizenapi/routing.php +++ b/zmscitizenapi/routing.php @@ -24,7 +24,7 @@ */ \App::$slim->get( '/services/', - 'ServicesList' + '\BO\Zmscitizenapi\ServicesList' ) ->setName("ServicesList"); @@ -48,7 +48,7 @@ */ \App::$slim->get( '/scopes/', - 'ScopesList' + '\BO\Zmscitizenapi\ScopesList' ) ->setName("ScopesList"); @@ -72,7 +72,7 @@ */ \App::$slim->get( '/offices/', - 'OfficesList' + '\BO\Zmscitizenapi\OfficesList' ) ->setName("OfficesList"); @@ -96,7 +96,7 @@ */ \App::$slim->get( '/offices-and-services/', - 'OfficesServicesRelations' + '\BO\Zmscitizenapi\OfficesServicesRelations' ) ->setName("OfficesServicesRelations"); @@ -128,7 +128,7 @@ */ \App::$slim->get( '/scope-by-id/', - 'ScopeByIdGet' + '\BO\Zmscitizenapi\ScopeByIdGet' ) ->setName("ScopeByIdGet"); @@ -158,7 +158,7 @@ */ \App::$slim->get( '/services-by-office/', - 'ServicesByOfficeList' + '\BO\Zmscitizenapi\ServicesByOfficeList' ) ->setName("ServicesByOfficeList"); @@ -188,7 +188,7 @@ */ \App::$slim->get( '/offices-by-service/', - 'OfficesByServiceList' + '\BO\Zmscitizenapi\OfficesByServiceList' ) ->setName("OfficesByServiceList"); @@ -223,7 +223,7 @@ */ \App::$slim->get( '/available-days/', - 'AvailableDaysList' + '\BO\Zmscitizenapi\AvailableDaysList' ) ->setName("AvailableDaysList"); @@ -263,7 +263,7 @@ */ \App::$slim->get( '/available-appointments/', - 'AvailableAppointmentsList' + '\BO\Zmscitizenapi\AvailableAppointmentsList' ) ->setName("AvailableAppointmentsList"); @@ -318,7 +318,7 @@ */ \App::$slim->get( '/appointment/', - 'AppointmentGet' + '\BO\Zmscitizenapi\AppointmentGet' ) ->setName("AppointmentGet"); @@ -342,7 +342,7 @@ */ \App::$slim->get( '/captcha-details/', - 'CaptchaGet' + '\BO\Zmscitizenapi\CaptchaGet' ) ->setName("CaptchaGet"); @@ -393,7 +393,7 @@ */ \App::$slim->post( '/reserve-appointment/', - 'AppointmentReserve' + '\BO\Zmscitizenapi\AppointmentReserve' ) ->setName("AppointmentReserve"); @@ -444,7 +444,7 @@ */ \App::$slim->post( '/update-appointment/', - 'AppointmentUpdate' + '\BO\Zmscitizenapi\AppointmentUpdate' ) ->setName("AppointmentUpdate"); @@ -495,7 +495,7 @@ */ \App::$slim->post( '/confirm-appointment/', - 'AppointmentConfirm' + '\BO\Zmscitizenapi\AppointmentConfirm' ) ->setName("AppointmentConfirm"); @@ -546,7 +546,7 @@ */ \App::$slim->post( '/preconfirm-appointment/', - 'AppointmentPreconfirm' + '\BO\Zmscitizenapi\AppointmentPreconfirm' ) ->setName("AppointmentPreconfirm"); @@ -597,6 +597,6 @@ */ \App::$slim->post( '/cancel-appointment/', - 'AppointmentCancel' + '\BO\Zmscitizenapi\AppointmentCancel' ) ->setName("AppointmentCancel"); diff --git a/zmscitizenapi/src/Zmscitizenapi/AppointmentGet.php b/zmscitizenapi/src/Zmscitizenapi/AppointmentGet.php index 9786bd097..556f4d0c6 100644 --- a/zmscitizenapi/src/Zmscitizenapi/AppointmentGet.php +++ b/zmscitizenapi/src/Zmscitizenapi/AppointmentGet.php @@ -5,26 +5,17 @@ use BO\Zmscitizenapi\BaseController; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use BO\Zmscitizenapi\Services\AppointmentService; -use BO\Zmscitizenapi\Services\ProcessService; +use BO\Zmscitizenapi\Services\ZmsApiFacadeService; class AppointmentGet extends BaseController { - protected $appointmentService; - - public function __construct() - { - $processService = new ProcessService(\App::$http); - $this->appointmentService = new AppointmentService($processService); - } - public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { $queryParams = $request->getQueryParams(); $processId = $queryParams['processId'] ?? null; $authKey = $queryParams['authKey'] ?? null; - $result = $this->appointmentService->getAppointmentById($processId, $authKey); + $result = ZmsApiFacadeService::getProcessById($processId, $authKey); return $this->createJsonResponse($response, $result['data'] ?? $result, $result['status']); } diff --git a/zmscitizenapi/src/Zmscitizenapi/AppointmentReserve.php b/zmscitizenapi/src/Zmscitizenapi/AppointmentReserve.php index f976d2230..42c985c06 100644 --- a/zmscitizenapi/src/Zmscitizenapi/AppointmentReserve.php +++ b/zmscitizenapi/src/Zmscitizenapi/AppointmentReserve.php @@ -4,37 +4,18 @@ use BO\Zmscitizenapi\Application; use BO\Zmscitizenapi\BaseController; -use BO\Zmscitizenapi\Services\CaptchaService; -use BO\Zmscitizenapi\Services\ScopesService; -use BO\Zmscitizenapi\Services\OfficesServicesRelationsService; -use BO\Zmscitizenapi\Services\AvailableAppointmentsService; -use BO\Zmscitizenapi\Services\AppointmentService; -use BO\Zmscitizenapi\Services\ProcessService; use BO\Zmscitizenapi\Helper\UtilityHelper; +use BO\Zmscitizenapi\Services\CaptchaService; +use BO\Zmscitizenapi\Services\MapperService; +use BO\Zmscitizenapi\Services\ValidationService; +use BO\Zmscitizenapi\Services\ZmsApiFacadeService; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; class AppointmentReserve extends BaseController { - protected $captchaService; - protected $scopesService; - protected $officesServicesRelationsService; - protected $availableAppointmentsService; - protected $appointmentService; - protected $utilityHelper; - protected $processService; - - public function __construct() - { - $this->captchaService = new CaptchaService(); - $this->scopesService = new ScopesService(); - $this->officesServicesRelationsService = new OfficesServicesRelationsService(); - $this->availableAppointmentsService = new AvailableAppointmentsService(); - $this->processService = new ProcessService(\App::$http); - $this->appointmentService = new AppointmentService($this->processService); - $this->utilityHelper = new UtilityHelper(); - } + public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { @@ -115,11 +96,11 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo } try { - $providerScope = $this->scopesService->getScopeByOfficeId($officeId); + $providerScope = ZmsApiFacadeService::getScopeByOfficeId($officeId); $captchaRequired = Application::$CAPTCHA_ENABLED === "1" && $providerScope['captchaActivatedRequired'] === "1"; if ($captchaRequired) { - $captchaVerificationResult = $this->captchaService->verifyCaptcha($captchaSolution); + $captchaVerificationResult = CaptchaService::verifyCaptcha($captchaSolution); if (!$captchaVerificationResult['success']) { return $this->createJsonResponse($response, [ 'errorCode' => 'captchaVerificationFailed', @@ -129,13 +110,13 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo } } - $serviceValidationResult = $this->officesServicesRelationsService->validateServiceLocationCombination($officeId, $serviceIds); + $serviceValidationResult = ValidationService::validateServiceLocationCombination($officeId, $serviceIds); if ($serviceValidationResult['status'] !== 200) { return $this->createJsonResponse($response, $serviceValidationResult, 400); } try { - $internalDate = $this->utilityHelper->getInternalDateFromTimestamp($timestamp); + $internalDate = UtilityHelper::getInternalDateFromTimestamp($timestamp); } catch (\Exception $e) { return $this->createJsonResponse($response, [ 'errorCode' => 'invalidTimestamp', @@ -144,11 +125,11 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo ], 400); } - $freeAppointments = $this->availableAppointmentsService->getFreeAppointments([ + $freeAppointments = ZmsApiFacadeService::getFreeAppointments([ 'officeId' => $officeId, 'serviceIds' => $serviceIds, 'serviceCounts' => $serviceCounts, - 'date' => $this->utilityHelper->getInternalDateFromTimestamp($timestamp) + 'date' => UtilityHelper::getInternalDateFromTimestamp($timestamp) ]); $selectedProcess = array_filter($freeAppointments, function ($process) use ($timestamp) { @@ -173,18 +154,18 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo ] ]; - $reservedProcess = $this->processService->reserveTimeslot($selectedProcess, $serviceIds, $serviceCounts); + $reservedProcess = ZmsApiFacadeService::reserveTimeslot($selectedProcess, $serviceIds, $serviceCounts); if ($reservedProcess && $reservedProcess->scope && $reservedProcess->scope->id) { $scopeIds = [$reservedProcess->scope->id]; - $scopesData = $this->scopesService->getScopeByIds($scopeIds); + $scopesData = ZmsApiFacadeService::getScopeByIds($scopeIds); if ($scopesData['status'] === 200 && isset($scopesData['scopes']['scopes']) && !empty($scopesData['scopes']['scopes'])) { - $reservedProcess->scope = $this->scopesService->mapScope($scopesData['scopes']['scopes'][0]); + $reservedProcess->scope = MapperService::mapScope($scopesData['scopes']['scopes'][0]); } } - $thinnedProcessData = $this->appointmentService->getThinnedProcessData($reservedProcess); + $thinnedProcessData = UtilityHelper::getThinnedProcessData($reservedProcess); $thinnedProcessData = array_merge($thinnedProcessData, ['officeId' => $officeId]); return $this->createJsonResponse($response, $thinnedProcessData, 200); diff --git a/zmscitizenapi/src/Zmscitizenapi/AvailableAppointmentsList.php b/zmscitizenapi/src/Zmscitizenapi/AvailableAppointmentsList.php index c17d6dea8..b93cc1d52 100644 --- a/zmscitizenapi/src/Zmscitizenapi/AvailableAppointmentsList.php +++ b/zmscitizenapi/src/Zmscitizenapi/AvailableAppointmentsList.php @@ -5,22 +5,15 @@ use BO\Zmscitizenapi\BaseController; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use BO\Zmscitizenapi\Services\AvailableAppointmentsService; +use BO\Zmscitizenapi\Services\ZmsApiFacadeService; class AvailableAppointmentsList extends BaseController { - protected $availableAppointmentsService; - - public function __construct() - { - $this->availableAppointmentsService = new AvailableAppointmentsService(); - } - public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { $queryParams = $request->getQueryParams(); - $result = $this->availableAppointmentsService->getAvailableAppointments($queryParams); + $result = ZmsApiFacadeService::getAvailableAppointments($queryParams); return $this->createJsonResponse($response, $result, $result['status']); } diff --git a/zmscitizenapi/src/Zmscitizenapi/AvailableDaysList.php b/zmscitizenapi/src/Zmscitizenapi/AvailableDaysList.php index af09f7dd4..b614eb978 100644 --- a/zmscitizenapi/src/Zmscitizenapi/AvailableDaysList.php +++ b/zmscitizenapi/src/Zmscitizenapi/AvailableDaysList.php @@ -5,22 +5,16 @@ use BO\Zmscitizenapi\BaseController; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use BO\Zmscitizenapi\Services\AvailableDaysService; +use BO\Zmscitizenapi\Services\ZmsApiFacadeService; class AvailableDaysList extends BaseController { - protected $availableDaysService; - - public function __construct() - { - $this->availableDaysService = new AvailableDaysService(); - } public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { $queryParams = $request->getQueryParams(); - $result = $this->availableDaysService->getAvailableDays($queryParams); + $result = ZmsApiFacadeService::getBookableFreeDays($queryParams); return $this->createJsonResponse($response, $result, $result['status']); } diff --git a/zmscitizenapi/src/Zmscitizenapi/CaptchaGet.php b/zmscitizenapi/src/Zmscitizenapi/CaptchaGet.php index bc9a55428..0b26610d1 100644 --- a/zmscitizenapi/src/Zmscitizenapi/CaptchaGet.php +++ b/zmscitizenapi/src/Zmscitizenapi/CaptchaGet.php @@ -10,16 +10,10 @@ class CaptchaGet extends BaseController { - protected $captchaService; - - public function __construct() - { - $this->captchaService = new CaptchaService(); - } public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { - $captchaDetails = $this->captchaService->getCaptchaDetails(); + $captchaDetails = CaptchaService::getCaptchaDetails(); return Render::withJson($response, $captchaDetails); } diff --git a/zmscitizenapi/src/Zmscitizenapi/Helper/UtilityHelper.php b/zmscitizenapi/src/Zmscitizenapi/Helper/UtilityHelper.php index 37f4f8590..e3b772ee1 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Helper/UtilityHelper.php +++ b/zmscitizenapi/src/Zmscitizenapi/Helper/UtilityHelper.php @@ -4,7 +4,7 @@ class UtilityHelper { - public function getInternalDateFromISO($dateString) + public static function getInternalDateFromISO($dateString) { $date = new \DateTime($dateString); return [ @@ -14,7 +14,7 @@ public function getInternalDateFromISO($dateString) ]; } - public function getInternalDateFromTimestamp(int $timestamp) + public static function getInternalDateFromTimestamp(int $timestamp) { $date = (new \DateTime())->setTimestamp($timestamp); return [ @@ -24,8 +24,56 @@ public function getInternalDateFromTimestamp(int $timestamp) ]; } - public function uniqueElementsFilter($value, $index, $self) + public static function uniqueElementsFilter($value, $index, $self) { return array_search($value, $self) === $index; } + + public static function getThinnedProcessData($myProcess) + { + if (!$myProcess || !isset($myProcess->id)) { + return []; + } + + $subRequestCounts = []; + $mainServiceId = null; + $mainServiceCount = 0; + + if (isset($myProcess->requests)) { + $requests = is_array($myProcess->requests) ? $myProcess->requests : iterator_to_array($myProcess->requests); + if (count($requests) > 0) { + $mainServiceId = $requests[0]->id; + foreach ($requests as $request) { + if ($request->id === $mainServiceId) { + $mainServiceCount++; + } else { + if (!isset($subRequestCounts[$request->id])) { + $subRequestCounts[$request->id] = [ + 'id' => $request->id, + 'count' => 0, + ]; + } + $subRequestCounts[$request->id]['count']++; + } + } + } + } + + return [ + 'processId' => $myProcess->id, + 'timestamp' => isset($myProcess->appointments[0]) ? $myProcess->appointments[0]->date : null, + 'authKey' => $myProcess->authKey ?? null, + 'familyName' => isset($myProcess->clients[0]) ? $myProcess->clients[0]->familyName : null, + 'customTextfield' => $myProcess->customTextfield ?? null, + 'email' => isset($myProcess->clients[0]) ? $myProcess->clients[0]->email : null, + 'telephone' => isset($myProcess->clients[0]) ? $myProcess->clients[0]->telephone : null, + 'officeName' => $myProcess->scope->contact->name ?? null, + 'officeId' => $myProcess->scope->provider->id ?? null, + 'scope' => $myProcess->scope ?? null, + 'subRequestCounts' => array_values($subRequestCounts), + 'serviceId' => $mainServiceId, + 'serviceCount' => $mainServiceCount, + ]; + } + } diff --git a/zmscitizenapi/src/Zmscitizenapi/OfficesByServiceList.php b/zmscitizenapi/src/Zmscitizenapi/OfficesByServiceList.php index 39c945a9f..d305b81ce 100644 --- a/zmscitizenapi/src/Zmscitizenapi/OfficesByServiceList.php +++ b/zmscitizenapi/src/Zmscitizenapi/OfficesByServiceList.php @@ -6,22 +6,16 @@ use BO\Slim\Render; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use BO\Zmscitizenapi\Services\OfficesService; +use BO\Zmscitizenapi\Services\ZmsApiFacadeService; class OfficesByServiceList extends BaseController { - protected $officesService; - - public function __construct() - { - $this->officesService = new OfficesService(); - } public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { $serviceIds = explode(',', $request->getQueryParams()['serviceId'] ?? ''); - $result = $this->officesService->getOfficesByServiceIds($serviceIds); + $result = ZmsApiFacadeService::getOfficesByServiceIds($serviceIds); if (isset($result['error'])) { return $this->createJsonResponse($response, $result, $result['status']); diff --git a/zmscitizenapi/src/Zmscitizenapi/OfficesList.php b/zmscitizenapi/src/Zmscitizenapi/OfficesList.php index ccdae2549..f89b403ff 100644 --- a/zmscitizenapi/src/Zmscitizenapi/OfficesList.php +++ b/zmscitizenapi/src/Zmscitizenapi/OfficesList.php @@ -6,20 +6,13 @@ use BO\Slim\Render; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use BO\Zmscitizenapi\Services\OfficesService; +use BO\Zmscitizenapi\Services\ZmsApiFacadeService; class OfficesList extends BaseController { - protected $officesService; - - public function __construct() - { - $this->officesService = new OfficesService(); // No container - } - public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { - $offices = $this->officesService->getOffices(); + $offices = ZmsApiFacadeService::getOffices(); return Render::withJson($response, ["offices" => $offices]); } } diff --git a/zmscitizenapi/src/Zmscitizenapi/OfficesServicesRelations.php b/zmscitizenapi/src/Zmscitizenapi/OfficesServicesRelations.php index 39ab7ef82..d6569b044 100644 --- a/zmscitizenapi/src/Zmscitizenapi/OfficesServicesRelations.php +++ b/zmscitizenapi/src/Zmscitizenapi/OfficesServicesRelations.php @@ -6,24 +6,14 @@ use BO\Slim\Render; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use BO\Zmscitizenapi\Services\OfficesServicesRelationsService; +use BO\Zmscitizenapi\Services\ZmsApiFacadeService; class OfficesServicesRelations extends BaseController { - protected $officesServicesRelationsService; - - public function __construct() - { - $this->officesServicesRelationsService = new OfficesServicesRelationsService(); // No container - } public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { - $sources = \App::$http->readGetResult('/source/' . \App::$source_name . '/', [ - 'resolveReferences' => 2, - ])->getEntity(); - - $data = $this->officesServicesRelationsService->getOfficesServicesRelations($sources); + $data = ZmsApiFacadeService::getServicesAndOffices(); return Render::withJson($response, $data); } diff --git a/zmscitizenapi/src/Zmscitizenapi/ScopeByIdGet.php b/zmscitizenapi/src/Zmscitizenapi/ScopeByIdGet.php index 3ab32a53c..6ec2146af 100644 --- a/zmscitizenapi/src/Zmscitizenapi/ScopeByIdGet.php +++ b/zmscitizenapi/src/Zmscitizenapi/ScopeByIdGet.php @@ -3,24 +3,17 @@ namespace BO\Zmscitizenapi; use BO\Zmscitizenapi\BaseController; -use BO\Zmscitizenapi\Services\ScopesService; +use BO\Zmscitizenapi\Services\ZmsApiFacadeService; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; class ScopeByIdGet extends BaseController { - protected $scopesService; - - public function __construct() - { - $this->scopesService = new ScopesService(); - } - public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { $scopeIds = explode(',', $request->getQueryParams()['scopeId'] ?? ''); - $result = $this->scopesService->getScopeByIds($scopeIds); + $result = ZmsApiFacadeService::getScopeByIds($scopeIds); if (isset($result['error'])) { return $this->createJsonResponse($response, $result, $result['status']); diff --git a/zmscitizenapi/src/Zmscitizenapi/ScopesList.php b/zmscitizenapi/src/Zmscitizenapi/ScopesList.php index c6432d7ba..ada550852 100644 --- a/zmscitizenapi/src/Zmscitizenapi/ScopesList.php +++ b/zmscitizenapi/src/Zmscitizenapi/ScopesList.php @@ -6,20 +6,13 @@ use BO\Slim\Render; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use BO\Zmscitizenapi\Services\ScopesService; +use BO\Zmscitizenapi\Services\ZmsApiFacadeService; class ScopesList extends BaseController { - protected $scopesService; - - public function __construct() - { - $this->scopesService = new ScopesService(); - } - public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { - $scopes = $this->scopesService->getScopes(); + $scopes = ZmsApiFacadeService::getScopes(); return Render::withJson($response, ["scopes" => $scopes]); } } diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/AppointmentService.php b/zmscitizenapi/src/Zmscitizenapi/Services/AppointmentService.php deleted file mode 100644 index 9f8e52256..000000000 --- a/zmscitizenapi/src/Zmscitizenapi/Services/AppointmentService.php +++ /dev/null @@ -1,122 +0,0 @@ -processService = $processService; - } - - public function getAppointmentById($processId, $authKey) - { - $errors = $this->validateInputs($processId, $authKey); - if (!empty($errors)) { - return ['errors' => $errors, 'status' => 400]; - } - - try { - $process = $this->processService->getProcessById($processId, $authKey); - - if (!$process) { - return [ - 'errorMessage' => 'Termin wurde nicht gefunden', - 'status' => 404, - ]; - } - - $responseData = $this->getThinnedProcessData($process); - return ['data' => $responseData, 'status' => 200]; - - } catch (\Exception $e) { - if (strpos($e->getMessage(), 'kein Termin gefunden') !== false) { - return [ - 'errorMessage' => 'Termin wurde nicht gefunden', - 'status' => 404, - ]; - } else { - return [ - 'error' => 'Unexpected error: ' . $e->getMessage(), - 'status' => 500, - ]; - } - } - } - - private function validateInputs($processId, $authKey) - { - $errors = []; - - if (!$processId || !is_numeric($processId) || intval($processId) <= 0) { - $errors[] = [ - 'type' => 'field', - 'msg' => 'processId should be a 32-bit integer', - 'path' => 'processId', - 'location' => 'query' - ]; - } - - if (!$authKey || !is_string($authKey)) { - $errors[] = [ - 'type' => 'field', - 'msg' => 'authKey should be a string', - 'path' => 'authKey', - 'location' => 'query' - ]; - } - - return $errors; - } - - public function getThinnedProcessData($myProcess) - { - if (!$myProcess || !isset($myProcess->id)) { - return []; - } - - $subRequestCounts = []; - $mainServiceId = null; - $mainServiceCount = 0; - - if (isset($myProcess->requests)) { - $requests = is_array($myProcess->requests) ? $myProcess->requests : iterator_to_array($myProcess->requests); - if (count($requests) > 0) { - $mainServiceId = $requests[0]->id; - foreach ($requests as $request) { - if ($request->id === $mainServiceId) { - $mainServiceCount++; - } else { - if (!isset($subRequestCounts[$request->id])) { - $subRequestCounts[$request->id] = [ - 'id' => $request->id, - 'count' => 0, - ]; - } - $subRequestCounts[$request->id]['count']++; - } - } - } - } - - return [ - 'processId' => $myProcess->id, - 'timestamp' => isset($myProcess->appointments[0]) ? $myProcess->appointments[0]->date : null, - 'authKey' => $myProcess->authKey ?? null, - 'familyName' => isset($myProcess->clients[0]) ? $myProcess->clients[0]->familyName : null, - 'customTextfield' => $myProcess->customTextfield ?? null, - 'email' => isset($myProcess->clients[0]) ? $myProcess->clients[0]->email : null, - 'telephone' => isset($myProcess->clients[0]) ? $myProcess->clients[0]->telephone : null, - 'officeName' => $myProcess->scope->contact->name ?? null, - 'officeId' => $myProcess->scope->provider->id ?? null, - 'scope' => $myProcess->scope ?? null, - 'subRequestCounts' => array_values($subRequestCounts), - 'serviceId' => $mainServiceId, - 'serviceCount' => $mainServiceCount, - ]; - } -} diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php b/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php deleted file mode 100644 index dd2227673..000000000 --- a/zmscitizenapi/src/Zmscitizenapi/Services/AvailableAppointmentsService.php +++ /dev/null @@ -1,198 +0,0 @@ -validateQueryParams($date, $officeId, $serviceIds, $serviceCounts); - - if (!empty($errors)) { - return ['errors' => $errors, 'status' => 400]; - } - - try { - $utilityHelper = new \BO\Zmscitizenapi\Helper\UtilityHelper(); - - $calendar = new CalendarEntity(); - $calendar->firstDay = $utilityHelper->getInternalDateFromISO($date); - $calendar->lastDay = $utilityHelper->getInternalDateFromISO($date); - $calendar->providers = [['id' => $officeId, 'source' => 'dldb']]; - - $calendar->requests = []; - foreach ($serviceIds as $index => $serviceId) { - $slotCount = isset($serviceCounts[$index]) ? intval($serviceCounts[$index]) : 1; - for ($i = 0; $i < $slotCount; $i++) { - $calendar->requests[] = [ - 'id' => $serviceId, - 'source' => 'dldb', - 'slotCount' => 1, - ]; - } - } - - $freeSlots = \App::$http->readPostResult('/process/status/free/', $calendar); - if (!$freeSlots || !method_exists($freeSlots, 'getCollection')) { - throw new \Exception('Invalid response from API'); - } - - return $this->processFreeSlots($freeSlots->getCollection()); - - } catch (\Exception $e) { - error_log('Error in AvailableAppointmentsService: ' . $e->getMessage()); - return [ - 'appointmentTimestamps' => [], - 'errorCode' => 'internalError', - 'errorMessage' => 'An error occurred while fetching available appointments', - 'status' => 500, - ]; - } - } - - public function getFreeAppointments(array $params) - { - $office = [ - 'id' => $params['officeId'], - 'source' => 'dldb' - ]; - - $requests = []; - - // Loop through service IDs and service counts - foreach ($params['serviceIds'] as $index => $serviceId) { - $service = [ - 'id' => $serviceId, - 'source' => 'dldb', - 'slotCount' => $params['serviceCounts'][$index] - ]; - $requests = array_merge($requests, array_fill(0, $service['slotCount'], $service)); - } - - try { - $processService = new ProcessService(\App::$http); - - $freeSlots = $processService->getFreeTimeslots( - [$office], - $requests, - $params['date'], - $params['date'] - ); - - return $freeSlots['data']; - - } catch (\Exception $e) { - error_log('Error in AvailableAppointmentsService: ' . $e->getMessage()); - return [ - 'appointmentTimestamps' => [], - 'errorCode' => 'internalError', - 'errorMessage' => 'An error occurred while fetching available appointments', - 'status' => 500, - ]; - } - } - - private function validateQueryParams($date, $officeId, $serviceIds, $serviceCounts) - { - $errors = []; - - if (!$date) { - $errors[] = [ - 'type' => 'field', - 'msg' => 'date is required and must be a valid date', - 'path' => 'date', - 'location' => 'body' - ]; - } - - if (!$officeId || !is_numeric($officeId)) { - $errors[] = [ - 'type' => 'field', - 'msg' => 'officeId should be a 32-bit integer', - 'path' => 'officeId', - 'location' => 'body' - ]; - } - - if (empty($serviceIds[0]) || !preg_match('/^\d+(,\d+)*$/', implode(',', $serviceIds))) { - $errors[] = [ - 'type' => 'field', - 'msg' => 'serviceId should be a comma-separated string of integers', - 'path' => 'serviceId', - 'location' => 'body' - ]; - } - - if (empty($serviceCounts[0]) || !preg_match('/^\d+(,\d+)*$/', implode(',', $serviceCounts))) { - $errors[] = [ - 'type' => 'field', - 'msg' => 'serviceCount should be a comma-separated string of integers', - 'path' => 'serviceCount', - 'location' => 'body' - ]; - } - - return $errors; - } - - - private function processFreeSlots($freeSlots) - { - if (empty($freeSlots) || !is_iterable($freeSlots)) { - return [ - 'appointmentTimestamps' => [], - 'errorCode' => 'appointmentNotAvailable', - 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', - 'status' => 404, - ]; - } - - $currentTimestamp = time(); - $appointmentTimestamps = []; - - foreach ($freeSlots as $slot) { - if (!isset($slot->appointments) || !is_iterable($slot->appointments)) { - continue; - } - - foreach ($slot->appointments as $appointment) { - - if (isset($appointment->date)) { - $timestamp = (int)$appointment->date; - - if (!in_array($timestamp, $appointmentTimestamps) && $timestamp > $currentTimestamp) { - $appointmentTimestamps[] = $timestamp; - } - } - } - } - - if (empty($appointmentTimestamps)) { - return [ - 'appointmentTimestamps' => [], - 'errorCode' => 'appointmentNotAvailable', - 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', - 'status' => 404, - ]; - } - - sort($appointmentTimestamps); - - return [ - 'appointmentTimestamps' => $appointmentTimestamps, - 'lastModified' => round(microtime(true) * 1000), - 'status' => 200, - ]; - } - - - - -} diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/AvailableDaysService.php b/zmscitizenapi/src/Zmscitizenapi/Services/AvailableDaysService.php deleted file mode 100644 index 2cb3b2a28..000000000 --- a/zmscitizenapi/src/Zmscitizenapi/Services/AvailableDaysService.php +++ /dev/null @@ -1,99 +0,0 @@ -validateQueryParams($officeId, $serviceId, $startDate, $endDate, $serviceCounts); - - if (!empty($errors)) { - return ['errors' => $errors, 'status' => 400]; - } - - try { - $utilityHelper = new \BO\Zmscitizenapi\Helper\UtilityHelper(); - - $firstDay = $utilityHelper->getInternalDateFromISO($startDate); - $lastDay = $utilityHelper->getInternalDateFromISO($endDate); - - $calendar = new CalendarEntity(); - $calendar->firstDay = $firstDay; - $calendar->lastDay = $lastDay; - $calendar->providers = [['id' => $officeId, 'source' => 'dldb']]; - $calendar->requests = [ - [ - 'id' => $serviceId, - 'source' => 'dldb', - 'slotCount' => $serviceCounts, - ] - ]; - - $apiResponse = \App::$http->readPostResult('/calendar/', $calendar); - $calendarEntity = $apiResponse->getEntity(); - $daysCollection = $calendarEntity->days; - $formattedDays = []; - - foreach ($daysCollection as $day) { - $formattedDays[] = sprintf('%04d-%02d-%02d', $day->year, $day->month, $day->day); - } - - if (empty($formattedDays)) { - return [ - 'availableDays' => [], - 'errorCode' => 'noAppointmentForThisScope', - 'errorMessage' => 'No available days found for the given criteria', - 'status' => 404, - ]; - } - - return [ - 'availableDays' => $formattedDays, - 'lastModified' => round(microtime(true) * 1000), - 'status' => 200, - ]; - - } catch (\Exception $e) { - error_log('Error in AvailableDaysService: ' . $e->getMessage()); - return [ - 'availableDays' => [], - 'errorCode' => 'internalError', - 'errorMessage' => 'An diesem Standort gibt es aktuell leider keine freien Termine', - 'lastModified' => round(microtime(true) * 1000), - 'status' => 500, - ]; - } - } - - private function validateQueryParams($officeId, $serviceId, $startDate, $endDate, $serviceCounts) - { - $errors = []; - if (!$startDate) { - $errors[] = ['type' => 'field', 'msg' => 'startDate is required and must be a valid date', 'path' => 'startDate', 'location' => 'query']; - } - if (!$endDate) { - $errors[] = ['type' => 'field', 'msg' => 'endDate is required and must be a valid date', 'path' => 'endDate', 'location' => 'query']; - } - if (!$officeId || !is_numeric($officeId)) { - $errors[] = ['type' => 'field', 'msg' => 'officeId should be a 32-bit integer', 'path' => 'officeId', 'location' => 'query']; - } - if (!$serviceId || !is_numeric($serviceId)) { - $errors[] = ['type' => 'field', 'msg' => 'serviceId should be a 32-bit integer', 'path' => 'serviceId', 'location' => 'query']; - } - if (empty($serviceCounts[0]) || !preg_match('/^\d+(,\d+)*$/', implode(',', $serviceCounts))) { - $errors[] = ['type' => 'field', 'msg' => 'serviceCount should be a comma-separated string of integers', 'path' => 'serviceCount', 'location' => 'query']; - } - - return $errors; - } - -} diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/CaptchaService.php b/zmscitizenapi/src/Zmscitizenapi/Services/CaptchaService.php index fc4086d0b..9cc933cc7 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Services/CaptchaService.php +++ b/zmscitizenapi/src/Zmscitizenapi/Services/CaptchaService.php @@ -8,7 +8,8 @@ class CaptchaService { - public function getCaptchaDetails() + + public static function getCaptchaDetails() { return [ 'siteKey' => Application::$FRIENDLYCAPTCHA_SITEKEY, @@ -18,10 +19,10 @@ public function getCaptchaDetails() ]; } - public function verifyCaptcha($solution) + public static function verifyCaptcha($solution) { try { - $response = $this->httpClient->post(Application::$FRIENDLYCAPTCHA_ENDPOINT, [ + $response = \App::$http->post(Application::$FRIENDLYCAPTCHA_ENDPOINT, [ 'form_params' => [ 'secret' => Application::$FRIENDLYCAPTCHA_SECRET, 'solution' => $solution @@ -33,8 +34,9 @@ public function verifyCaptcha($solution) return $responseBody; } catch (RequestException $e) { $errorMessage = $e->hasResponse() ? $e->getResponse()->getBody()->getContents() : $e->getMessage(); - error_log('Error verifying captcha: ' . $errorMessage); + //error_log('Error verifying captcha: ' . $errorMessage); throw new Exception('Captcha verification failed'); } } } + diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/MapperService.php b/zmscitizenapi/src/Zmscitizenapi/Services/MapperService.php new file mode 100644 index 000000000..e0738beed --- /dev/null +++ b/zmscitizenapi/src/Zmscitizenapi/Services/MapperService.php @@ -0,0 +1,94 @@ + $scope['id'] ?? null, + 'provider' => [ + 'id' => $scope['provider']['id'] ?? null, + 'source' => $scope['provider']['source'] ?? null, + ], + 'shortName' => $scope['shortName'] ?? null, + 'telephoneActivated' => $scope['telephoneActivated'] ?? null, + 'telephoneRequired' => $scope['telephoneRequired'] ?? null, + 'customTextfieldActivated' => $scope['customTextfieldActivated'] ?? null, + 'customTextfieldRequired' => $scope['customTextfieldRequired'] ?? null, + 'customTextfieldLabel' => $scope['customTextfieldLabel'] ?? null, + 'captchaActivatedRequired' => $scope['captchaActivatedRequired'] ?? null, + 'displayInfo' => $scope['displayInfo'] ?? null, + ]; + } + + public static function mapOfficesWithScope($providerList) + { + $offices = []; + foreach ($providerList as $provider) { + $officeData = [ + "id" => $provider->id, + "name" => $provider->displayName ?? $provider->name, + ]; + $scope = ZmsApiFacadeService::getScopeForProvider($provider->id); + if ($scope) { + $officeData['scope'] = $scope; + } + + $offices[] = $officeData; + } + return $offices; + } + + public static function mapServicesWithCombinations($requestList, $relationList) + { + $servicesProviderIds = []; + foreach ($relationList as $relation) { + if (!isset($servicesProviderIds[$relation->request->id])) { + $servicesProviderIds[$relation->request->id] = []; + } + $servicesProviderIds[$relation->request->id][] = $relation->provider->id; + } + + $services = []; + foreach ($requestList as $service) { + $serviceCombinations = []; + $mappedService = [ + "id" => $service->getId(), + "name" => $service->getName(), + "maxQuantity" => $service->getAdditionalData()['maxQuantity'] ?? 1, + ]; + + if (isset($service->getAdditionalData()['combinable'])) { + foreach ($service->getAdditionalData()['combinable'] as $combinationServiceId) { + $commonProviders = array_intersect( + $servicesProviderIds[$service->getId()] ?? [], + $servicesProviderIds[$combinationServiceId] ?? [] + ); + $serviceCombinations[$combinationServiceId] = !empty($commonProviders) ? array_values($commonProviders) : []; + } + $mappedService['combinable'] = $serviceCombinations; + } + + $services[] = $mappedService; + } + + return $services; + } + + public static function mapRelations($relationList) + { + $relations = []; + foreach ($relationList as $relation) { + $relations[] = [ + "officeId" => $relation->provider->id, + "serviceId" => $relation->request->id, + "slots" => intval($relation->slots) + ]; + } + return $relations; + } + +} \ No newline at end of file diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/OfficesService.php b/zmscitizenapi/src/Zmscitizenapi/Services/OfficesService.php deleted file mode 100644 index d796547b1..000000000 --- a/zmscitizenapi/src/Zmscitizenapi/Services/OfficesService.php +++ /dev/null @@ -1,118 +0,0 @@ -readGetResult('/source/' . \App::$source_name . '/', [ - 'resolveReferences' => 2, - ])->getEntity(); - - $scopeList = $sources->getScopeList() ?? []; - $providerProjectionList = []; - - foreach ($sources->getProviderList() as $provider) { - $matchingScope = null; - foreach ($scopeList as $scope) { - if ($scope->provider->id == $provider->id) { - $matchingScope = $scope; - break; - } - } - - $providerData = [ - "id" => $provider->id, - "name" => $provider->displayName ?? $provider->name, - ]; - - if ($matchingScope) { - $providerData["scope"] = [ - "id" => $matchingScope->id, - "provider" => $matchingScope->provider, - "shortName" => $matchingScope->shortName, - "telephoneActivated" => $matchingScope->getTelephoneActivated(), - "telephoneRequired" => $matchingScope->getTelephoneRequired(), - "customTextfieldActivated" => $matchingScope->getCustomTextfieldActivated(), - "customTextfieldRequired" => $matchingScope->getCustomTextfieldRequired(), - "customTextfieldLabel" => $matchingScope->getCustomTextfieldLabel(), - "captchaActivatedRequired" => $matchingScope->getCaptchaActivatedRequired(), - "displayInfo" => $matchingScope->getDisplayInfo() - ]; - } - - $providerProjectionList[] = $providerData; - } - - return $providerProjectionList; - } - - public function getOfficesByServiceIds(array $serviceIds) - { - $serviceIds = array_unique($serviceIds); - - if (empty($serviceIds) || $serviceIds == ['']) { - return [ - 'offices' => [], - 'error' => 'Invalid serviceId(s)', - 'status' => 400 - ]; - } - - $sources = \App::$http->readGetResult('/source/' . \App::$source_name . '/', [ - 'resolveReferences' => 2, - ])->getEntity(); - - $providerList = $sources->getProviderList(); - $requestRelationList = $sources->getRequestRelationList(); - - $offices = []; - $notFoundIds = []; - $addedOfficeIds = []; - - foreach ($serviceIds as $serviceId) { - $found = false; - foreach ($requestRelationList as $relation) { - if ($relation->request->id == $serviceId) { - if (!in_array($relation->provider->id, $addedOfficeIds)) { - foreach ($providerList as $provider) { - if ($provider->id == $relation->provider->id) { - $offices[] = [ - "id" => $provider->id, - "name" => $provider->name, - ]; - $addedOfficeIds[] = $provider->id; - $found = true; - break; - } - } - } else { - $found = true; - } - } - } - if (!$found) { - $notFoundIds[] = $serviceId; - } - } - - if (empty($offices)) { - return [ - 'offices' => [], - 'error' => 'Office(s) not found for the provided serviceId(s)', - 'status' => 404 - ]; - } - - $responseContent = ['offices' => $offices]; - if (!empty($notFoundIds)) { - $responseContent['warning'] = 'The following serviceId(s) were not found: ' . implode(', ', $notFoundIds); - } - - return [ - 'offices' => $responseContent, - 'status' => 200 - ]; - } -} diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/OfficesServicesRelationsService.php b/zmscitizenapi/src/Zmscitizenapi/Services/OfficesServicesRelationsService.php deleted file mode 100644 index e1d076292..000000000 --- a/zmscitizenapi/src/Zmscitizenapi/Services/OfficesServicesRelationsService.php +++ /dev/null @@ -1,183 +0,0 @@ -getProviderList() ?? []; - $requestList = $sources->getRequestList() ?? []; - $relationList = $sources->getRequestRelationList() ?? []; - - $offices = $this->mapOfficesWithScope($sources, $providerList); - $services = $this->mapServicesWithCombinations($requestList, $relationList); - $relations = $this->mapRelations($relationList); - - return [ - 'offices' => $offices, - 'services' => $services, - 'relations' => $relations, - ]; - } - - private function mapOfficesWithScope($sources, $providerList) - { - $offices = []; - foreach ($providerList as $provider) { - $officeData = [ - "id" => $provider->id, - "name" => $provider->displayName ?? $provider->name, - ]; - $scope = $this->getScopeForProvider($sources, $provider->id); - if ($scope) { - $officeData['scope'] = $scope; - } - - $offices[] = $officeData; - } - return $offices; - } - - private function mapServicesWithCombinations($requestList, $relationList) - { - $servicesProviderIds = []; - foreach ($relationList as $relation) { - if (!isset($servicesProviderIds[$relation->request->id])) { - $servicesProviderIds[$relation->request->id] = []; - } - $servicesProviderIds[$relation->request->id][] = $relation->provider->id; - } - - $services = []; - foreach ($requestList as $service) { - $serviceCombinations = []; - $mappedService = [ - "id" => $service->getId(), - "name" => $service->getName(), - "maxQuantity" => $service->getAdditionalData()['maxQuantity'] ?? 1, - ]; - - if (isset($service->getAdditionalData()['combinable'])) { - foreach ($service->getAdditionalData()['combinable'] as $combinationServiceId) { - $commonProviders = array_intersect( - $servicesProviderIds[$service->getId()] ?? [], - $servicesProviderIds[$combinationServiceId] ?? [] - ); - $serviceCombinations[$combinationServiceId] = !empty($commonProviders) ? array_values($commonProviders) : []; - } - $mappedService['combinable'] = $serviceCombinations; - } - - $services[] = $mappedService; - } - - return $services; - } - - private function mapRelations($relationList) - { - $relations = []; - foreach ($relationList as $relation) { - $relations[] = [ - "officeId" => $relation->provider->id, - "serviceId" => $relation->request->id, - "slots" => intval($relation->slots) - ]; - } - return $relations; - } - - private function getScopeForProvider($sources, $providerId) - { - $scopeList = $sources->getScopeList(); - foreach ($scopeList as $scope) { - if ($scope->provider->id === $providerId) { - return [ - "id" => $scope->id, - "provider" => $scope->provider, - "shortName" => $scope->shortName, - "telephoneActivated" => $scope->getTelephoneActivated(), - "telephoneRequired" => $scope->getTelephoneRequired(), - "customTextfieldActivated" => $scope->getCustomTextfieldActivated(), - "customTextfieldRequired" => $scope->getCustomTextfieldRequired(), - "customTextfieldLabel" => $scope->getCustomTextfieldLabel(), - "captchaActivatedRequired" => $scope->getCaptchaActivatedRequired(), - "displayInfo" => $scope->getDisplayInfo() - ]; - } - } - return null; - } - - - public function validateServiceLocationCombination($officeId, array $serviceIds) - { - - - $availableServices = $this->getServicesProvidedAtOffice($officeId); - $availableServiceIds = array_map(function ($service) { - return $service['id']; - }, $availableServices); - - $invalidServiceIds = array_filter($serviceIds, function ($serviceId) use ($availableServiceIds) { - return !in_array($serviceId, $availableServiceIds); - }); - - if (!empty($invalidServiceIds)) { - return [ - 'status' => 400, - 'errorCode' => 'invalidLocationAndServiceCombination', - 'errorMessage' => 'The provided service(s) do not exist at the given location.', - 'invalidServiceIds' => $invalidServiceIds, - 'locationId' => $officeId, - 'lastModified' => time() * 1000, - ]; - } - - return [ - 'status' => 200, - 'message' => 'Valid service-location combination.', - ]; - } - - public function getServicesProvidedAtOffice($officeId) - { - // Fetch the request relation list (assuming it's of type RequestRelationList) - $sources = \App::$http->readGetResult('/source/' . \App::$source_name . '/', [ - 'resolveReferences' => 2, - ])->getEntity(); - - $requestRelationList = $sources->getRequestRelationList(); - - // Manually iterate over the RequestRelationList to convert it to an array - $requestRelationArray = []; - foreach ($requestRelationList as $relation) { - $requestRelationArray[] = $relation; - } - - // Now apply array_filter to the array we built - $serviceIds = array_filter($requestRelationArray, function ($relation) use ($officeId) { - return $relation->provider->id === $officeId; - }); - - $serviceIds = array_map(function ($relation) { - return $relation->request->id; - }, $serviceIds); - - // Manually iterate over the RequestList to convert it to an array - $requestList = $sources->getRequestList(); - $requestArray = []; - foreach ($requestList as $request) { - $requestArray[] = $request; - } - - // Return the filtered request array - return array_filter($requestArray, function ($request) use ($serviceIds) { - return in_array($request->id, $serviceIds); - }); - } - - - -} diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/ScopesService.php b/zmscitizenapi/src/Zmscitizenapi/Services/ScopesService.php deleted file mode 100644 index 49846a680..000000000 --- a/zmscitizenapi/src/Zmscitizenapi/Services/ScopesService.php +++ /dev/null @@ -1,143 +0,0 @@ -readGetResult('/source/' . \App::$source_name . '/', [ - 'resolveReferences' => 2, - ])->getEntity(); - - $scopeList = $sources->getScopeList() ?? []; - $scopesProjectionList = []; - - foreach ($scopeList as $scope) { - $scopesProjectionList[] = [ - "id" => $scope->id, - "provider" => $scope->provider, - "shortName" => $scope->shortName, - "telephoneActivated" => $scope->getTelephoneActivated(), - "telephoneRequired" => $scope->getTelephoneRequired(), - "customTextfieldActivated" => $scope->getCustomTextfieldActivated(), - "customTextfieldRequired" => $scope->getCustomTextfieldRequired(), - "customTextfieldLabel" => $scope->getCustomTextfieldLabel(), - "captchaActivatedRequired" => $scope->getCaptchaActivatedRequired(), - "displayInfo" => $scope->getDisplayInfo() - ]; - } - - return $scopesProjectionList; - } - - public function getScopeByIds(array $scopeIds) - { - $scopeIds = array_unique($scopeIds); - - if (empty($scopeIds) || $scopeIds == ['']) { - return [ - 'scopes' => [], - 'error' => 'Invalid scopeId(s)', - 'status' => 400 - ]; - } - - $sources = \App::$http->readGetResult('/source/' . \App::$source_name . '/', [ - 'resolveReferences' => 2, - ])->getEntity(); - - $scopeList = $sources->getScopeList(); - $scopes = []; - $notFoundIds = []; - - foreach ($scopeIds as $scopeId) { - $found = false; - foreach ($scopeList as $scopeItem) { - if ($scopeItem->id == $scopeId) { - $scopes[] = [ - "id" => $scopeItem->id, - "provider" => [ - "id" => $scopeItem->provider->id, - "source" => $scopeItem->provider->source, - ], - "shortName" => $scopeItem->shortName, - "telephoneActivated" => $scopeItem->getTelephoneActivated(), - "telephoneRequired" => $scopeItem->getTelephoneRequired(), - "customTextfieldActivated" => $scopeItem->getCustomTextfieldActivated(), - "customTextfieldRequired" => $scopeItem->getCustomTextfieldRequired(), - "customTextfieldLabel" => $scopeItem->getCustomTextfieldLabel(), - "captchaActivatedRequired" => $scopeItem->getCaptchaActivatedRequired(), - "displayInfo" => $scopeItem->getDisplayInfo() - ]; - $found = true; - break; - } - } - - if (!$found) { - $notFoundIds[] = $scopeId; - } - } - - if (empty($scopes)) { - return [ - 'scopes' => [], - 'error' => 'Scope(s) not found', - 'status' => 404 - ]; - } - - $responseContent = ['scopes' => $scopes]; - if (!empty($notFoundIds)) { - $responseContent['warning'] = 'The following scopeId(s) were not found: ' . implode(', ', $notFoundIds); - } - - return [ - 'scopes' => $responseContent, - 'status' => 200 - ]; - } - - public function getScopeByOfficeId($officeId) - { - try { - $scopes = $this->getScopes(); - - foreach ($scopes as $scope) { - if (isset($scope['provider']) && $scope['provider']->id == $officeId) { - return $scope; - } - } - - return [ - 'error' => 'Scope not found for the provided office ID', - 'status' => 404 - ]; - } catch (\Exception $e) { - return [ - 'error' => 'Error fetching scope by office ID: ' . $e->getMessage(), - 'status' => 500 - ]; - } - } - - public function mapScope($scope) - { - return [ - 'id' => $scope['id'] ?? null, - 'provider' => [ - 'id' => $scope['provider']['id'] ?? null, - 'source' => $scope['provider']['source'] ?? null, - ], - 'shortName' => $scope['shortName'] ?? null, - 'telephoneActivated' => $scope['telephoneActivated'] ?? null, - 'telephoneRequired' => $scope['telephoneRequired'] ?? null, - 'customTextfieldActivated' => $scope['customTextfieldActivated'] ?? null, - 'customTextfieldRequired' => $scope['customTextfieldRequired'] ?? null, - 'customTextfieldLabel' => $scope['customTextfieldLabel'] ?? null, - 'captchaActivatedRequired' => $scope['captchaActivatedRequired'] ?? null, - 'displayInfo' => $scope['displayInfo'] ?? null, - ]; - } -} diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/ServicesService.php b/zmscitizenapi/src/Zmscitizenapi/Services/ServicesService.php deleted file mode 100644 index 9a90705c8..000000000 --- a/zmscitizenapi/src/Zmscitizenapi/Services/ServicesService.php +++ /dev/null @@ -1,91 +0,0 @@ -readGetResult('/source/' . \App::$source_name . '/', [ - 'resolveReferences' => 2, - ])->getEntity(); - - $requestList = $sources->getRequestList() ?? []; - $servicesProjectionList = []; - - foreach ($requestList as $request) { - $additionalData = $request->getAdditionalData(); - $servicesProjectionList[] = [ - "id" => $request->getId(), - "name" => $request->getName(), - "maxQuantity" => $additionalData['maxQuantity'] ?? 1, - ]; - } - - return $servicesProjectionList; - } - - public function getServicesByOfficeIds(array $officeIds) - { - $officeIds = array_unique($officeIds); - - if (empty($officeIds) || $officeIds == ['']) { - return [ - 'services' => [], - 'error' => 'Invalid officeId(s)', - 'status' => 400, - ]; - } - - $sources = \App::$http->readGetResult('/source/' . \App::$source_name . '/', [ - 'resolveReferences' => 2, - ])->getEntity(); - - $requestList = $sources->getRequestList(); - $requestRelationList = $sources->getRequestRelationList(); - - $services = []; - $notFoundIds = []; - $addedServices = []; - - foreach ($officeIds as $officeId) { - $found = false; - foreach ($requestRelationList as $relation) { - if ($relation->provider->id == $officeId) { - foreach ($requestList as $request) { - if ($request->id == $relation->request->id && !in_array($request->id, $addedServices)) { - $services[] = [ - "id" => $request->id, - "name" => $request->name, - "maxQuantity" => $request->getAdditionalData()['maxQuantity'] ?? 1, - ]; - $addedServices[] = $request->id; - $found = true; - } - } - } - } - if (!$found) { - $notFoundIds[] = $officeId; - } - } - - if (empty($services)) { - return [ - 'services' => [], - 'error' => 'Service(s) not found for the provided officeId(s)', - 'status' => 404, - ]; - } - - $responseContent = ['services' => $services]; - if (!empty($notFoundIds)) { - $responseContent['warning'] = 'The following officeId(s) were not found: ' . implode(', ', $notFoundIds); - } - - return [ - 'services' => $responseContent, - 'status' => 200, - ]; - } -} diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/ValidationService.php b/zmscitizenapi/src/Zmscitizenapi/Services/ValidationService.php new file mode 100644 index 000000000..64f204898 --- /dev/null +++ b/zmscitizenapi/src/Zmscitizenapi/Services/ValidationService.php @@ -0,0 +1,128 @@ + 400, + 'errorCode' => 'invalidLocationAndServiceCombination', + 'errorMessage' => 'The provided service(s) do not exist at the given location.', + 'invalidServiceIds' => $invalidServiceIds, + 'locationId' => $officeId, + 'lastModified' => time() * 1000, + ]; + } + + return [ + 'status' => 200, + 'message' => 'Valid service-location combination.', + ]; + } + + public static function validateBookableFreeDays($officeId, $serviceId, $startDate, $endDate, $serviceCounts) + { + $errors = []; + if (!$startDate) { + $errors[] = ['type' => 'field', 'msg' => 'startDate is required and must be a valid date', 'path' => 'startDate', 'location' => 'query']; + } + if (!$endDate) { + $errors[] = ['type' => 'field', 'msg' => 'endDate is required and must be a valid date', 'path' => 'endDate', 'location' => 'query']; + } + if (!$officeId || !is_numeric($officeId)) { + $errors[] = ['type' => 'field', 'msg' => 'officeId should be a 32-bit integer', 'path' => 'officeId', 'location' => 'query']; + } + if (!$serviceId || !is_numeric($serviceId)) { + $errors[] = ['type' => 'field', 'msg' => 'serviceId should be a 32-bit integer', 'path' => 'serviceId', 'location' => 'query']; + } + if (empty($serviceCounts[0]) || !preg_match('/^\d+(,\d+)*$/', implode(',', $serviceCounts))) { + $errors[] = ['type' => 'field', 'msg' => 'serviceCount should be a comma-separated string of integers', 'path' => 'serviceCount', 'location' => 'query']; + } + + return $errors; + } + + public static function validateGetAppointment($processId, $authKey) + { + $errors = []; + + if (!$processId || !is_numeric($processId) || intval($processId) <= 0) { + $errors[] = [ + 'type' => 'field', + 'msg' => 'processId should be a 32-bit integer', + 'path' => 'processId', + 'location' => 'query' + ]; + } + + if (!$authKey || !is_string($authKey)) { + $errors[] = [ + 'type' => 'field', + 'msg' => 'authKey should be a string', + 'path' => 'authKey', + 'location' => 'query' + ]; + } + + return $errors; + } + + public static function validateGetAvailableAppointments($date, $officeId, $serviceIds, $serviceCounts) + { + $errors = []; + + if (!$date) { + $errors[] = [ + 'type' => 'field', + 'msg' => 'date is required and must be a valid date', + 'path' => 'date', + 'location' => 'body' + ]; + } + + if (!$officeId || !is_numeric($officeId)) { + $errors[] = [ + 'type' => 'field', + 'msg' => 'officeId should be a 32-bit integer', + 'path' => 'officeId', + 'location' => 'body' + ]; + } + + if (empty($serviceIds[0]) || !preg_match('/^\d+(,\d+)*$/', implode(',', $serviceIds))) { + $errors[] = [ + 'type' => 'field', + 'msg' => 'serviceId should be a comma-separated string of integers', + 'path' => 'serviceId', + 'location' => 'body' + ]; + } + + if (empty($serviceCounts[0]) || !preg_match('/^\d+(,\d+)*$/', implode(',', $serviceCounts))) { + $errors[] = [ + 'type' => 'field', + 'msg' => 'serviceCount should be a comma-separated string of integers', + 'path' => 'serviceCount', + 'location' => 'body' + ]; + } + + return $errors; + } + +} \ No newline at end of file diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/ProcessService.php b/zmscitizenapi/src/Zmscitizenapi/Services/ZmsApiClientService.php similarity index 51% rename from zmscitizenapi/src/Zmscitizenapi/Services/ProcessService.php rename to zmscitizenapi/src/Zmscitizenapi/Services/ZmsApiClientService.php index 4a638cdd3..4f5d0519e 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Services/ProcessService.php +++ b/zmscitizenapi/src/Zmscitizenapi/Services/ZmsApiClientService.php @@ -5,26 +5,96 @@ use BO\Zmsentities\Calendar as CalendarEntity; use BO\Zmsentities\Process as ProcessEntity; -class ProcessService +class ZmsApiClientService { - protected $httpClient; - public function __construct($httpClient) + public static function getOffices() { - $this->httpClient = $httpClient; + $sources = \App::$http->readGetResult('/source/' . \App::$source_name . '/', [ + 'resolveReferences' => 2, + ])->getEntity(); + + $providerList = $sources->getProviderList() ?? []; + + return $providerList; + } - public function getProcessById($processId, $authKey) + public static function getScopes() { - $resolveReferences = 2; - $process = $this->httpClient->readGetResult("/process/{$processId}/{$authKey}/", [ - 'resolveReferences' => $resolveReferences + $sources = \App::$http->readGetResult('/source/' . \App::$source_name . '/', [ + 'resolveReferences' => 2, ])->getEntity(); - return $process; + $scopeList = $sources->getScopeList() ?? []; + + return $scopeList; + } - public function reserveTimeslot($appointmentProcess, $serviceIds, $serviceCounts) + public static function getServices() + { + $sources = \App::$http->readGetResult('/source/' . \App::$source_name . '/', [ + 'resolveReferences' => 2, + ])->getEntity(); + + $requestList = $sources->getRequestList() ?? []; + + return $requestList; + + } + + public static function getRequestRelationList(){ + + $sources = \App::$http->readGetResult('/source/' . \App::$source_name . '/', [ + 'resolveReferences' => 2, + ])->getEntity(); + + $requestRelationList = $sources->getRequestRelationList(); + + return $requestRelationList; + } + + /* Todo add cache methods + haveCachedSourcesExpired + getSources + + */ + + public static function getFreeDays($providers, $requests, $firstDay, $lastDay) + { + + $calendar = new CalendarEntity(); + $calendar->firstDay = $firstDay; + $calendar->lastDay = $lastDay; + $calendar->providers = $providers; + $calendar->requests = $requests; + + return \App::$http->readPostResult('/calendar/', $calendar)->getEntity(); + } + + public static function getFreeTimeslots($providers, $requests, $firstDay, $lastDay) + { + + $calendar = new CalendarEntity(); + $calendar->firstDay = $firstDay; + $calendar->lastDay = $lastDay; + $calendar->providers = $providers; + $calendar->requests = $requests; + + + $result = \App::$http->readPostResult('/process/status/free/', $calendar); + if (!$result || !method_exists($result, 'getCollection')) { + throw new \Exception('Invalid response from API'); + } + + $psr7Response = $result->getResponse(); + $responseBody = (string) $psr7Response->getBody(); + + return $result; + } + + public static function reserveTimeslot($appointmentProcess, $serviceIds, $serviceCounts) { $requests = []; @@ -56,97 +126,61 @@ public function reserveTimeslot($appointmentProcess, $serviceIds, $serviceCounts $processEntity->queue = $appointmentProcess['queue']; } - $result = $this->httpClient->readPostResult('/process/status/reserved/', $processEntity); + $result = \App::$http->readPostResult('/process/status/reserved/', $processEntity); return $result->getEntity(); } - public function submitClientData($process) { $url = "/process/{$process['id']}/{$process['authKey']}/"; - return $this->httpClient->readPostResult($url, $process)->getEntity(); + return \App::$http->readPostResult($url, $process)->getEntity(); } public function preconfirmProcess($process) { $url = '/process/status/preconfirmed/'; - return $this->httpClient->readPostResult($url, $process)->getEntity(); + return \App::$http->readPostResult($url, $process)->getEntity(); } public function confirmProcess($process) { $url = '/process/status/confirmed/'; - return $this->httpClient->readPostResult($url, $process)->getEntity(); + return \App::$http->readPostResult($url, $process)->getEntity(); } public function cancelAppointment($process) { $url = "/process/{$process['id']}/{$process['authKey']}/"; - return $this->httpClient->readDeleteResult($url, $process)->getEntity(); + return \App::$http->readDeleteResult($url, $process)->getEntity(); } public function sendConfirmationEmail($process) { $url = "/process/{$process['id']}/{$process['authKey']}/confirmation/mail/"; - return $this->httpClient->readPostResult($url, $process)->getEntity(); + return \App::$http->readPostResult($url, $process)->getEntity(); } public function sendPreconfirmationEmail($process) { $url = "/process/{$process['id']}/{$process['authKey']}/preconfirmation/mail/"; - return $this->httpClient->readPostResult($url, $process)->getEntity(); + return \App::$http->readPostResult($url, $process)->getEntity(); } public function sendCancelationEmail($process) { $url = "/process/{$process['id']}/{$process['authKey']}/delete/mail/"; - return $this->httpClient->readPostResult($url, $process)->getEntity(); + return \App::$http->readPostResult($url, $process)->getEntity(); } - public function getFreeDays($providers, $requests, $firstDay, $lastDay) + public static function getProcessById($processId, $authKey) { - $requestUrl = '/calendar/'; - $dataPayload = [ - 'firstDay' => $firstDay, - 'lastDay' => $lastDay, - 'providers' => $providers, - 'requests' => $requests, - ]; - - return $this->httpClient->readPostResult($requestUrl, $dataPayload)->getEntity(); - } - - public function getFreeTimeslots($providers, $requests, $firstDay, $lastDay) - { - $requestUrl = '/process/status/free/'; - $dataPayload = [ - 'firstDay' => $firstDay, - 'lastDay' => $lastDay, - 'providers' => $providers, - 'requests' => $requests, - ]; - - $calendar = new CalendarEntity(); - $calendar->firstDay = $firstDay; - $calendar->lastDay = $lastDay; - $calendar->providers = $providers; - $calendar->requests = $requests; - - - $result = \App::$http->readPostResult('/process/status/free/', $calendar); - if (!$result || !method_exists($result, 'getCollection')) { - throw new \Exception('Invalid response from API'); - } - - $psr7Response = $result->getResponse(); - $responseBody = (string) $psr7Response->getBody(); + $resolveReferences = 2; + $process = \App::$http->readGetResult("/process/{$processId}/{$authKey}/", [ + 'resolveReferences' => $resolveReferences + ])->getEntity(); - return json_decode($responseBody, true); + return $process; } - - - - -} +} \ No newline at end of file diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/ZmsApiFacadeService.php b/zmscitizenapi/src/Zmscitizenapi/Services/ZmsApiFacadeService.php new file mode 100644 index 000000000..37c9bd15e --- /dev/null +++ b/zmscitizenapi/src/Zmscitizenapi/Services/ZmsApiFacadeService.php @@ -0,0 +1,671 @@ +provider->id == $provider->id) { + $matchingScope = $scope; + break; + } + } + + $providerData = [ + "id" => $provider->id, + "name" => $provider->displayName ?? $provider->name, + ]; + + if ($matchingScope) { + $providerData["scope"] = [ + "id" => $matchingScope->id, + "provider" => $matchingScope->provider, + "shortName" => $matchingScope->shortName, + "telephoneActivated" => $matchingScope->getTelephoneActivated(), + "telephoneRequired" => $matchingScope->getTelephoneRequired(), + "customTextfieldActivated" => $matchingScope->getCustomTextfieldActivated(), + "customTextfieldRequired" => $matchingScope->getCustomTextfieldRequired(), + "customTextfieldLabel" => $matchingScope->getCustomTextfieldLabel(), + "captchaActivatedRequired" => $matchingScope->getCaptchaActivatedRequired(), + "displayInfo" => $matchingScope->getDisplayInfo() + ]; + } + + $providerProjectionList[] = $providerData; + } + + return $providerProjectionList; + } + + public static function getScopes() + { + $scopeList = ZmsApiClientService::getScopes() ?? []; + $scopesProjectionList = []; + + foreach ($scopeList as $scope) { + $scopesProjectionList[] = [ + "id" => $scope->id, + "provider" => $scope->provider, + "shortName" => $scope->shortName, + "telephoneActivated" => $scope->getTelephoneActivated(), + "telephoneRequired" => $scope->getTelephoneRequired(), + "customTextfieldActivated" => $scope->getCustomTextfieldActivated(), + "customTextfieldRequired" => $scope->getCustomTextfieldRequired(), + "customTextfieldLabel" => $scope->getCustomTextfieldLabel(), + "captchaActivatedRequired" => $scope->getCaptchaActivatedRequired(), + "displayInfo" => $scope->getDisplayInfo() + ]; + } + + return $scopesProjectionList; + } + + public static function getServices() + { + + $requestList = ZmsApiClientService::getServices() ?? []; + $servicesProjectionList = []; + + foreach ($requestList as $request) { + $additionalData = $request->getAdditionalData(); + $servicesProjectionList[] = [ + "id" => $request->getId(), + "name" => $request->getName(), + "maxQuantity" => $additionalData['maxQuantity'] ?? 1, + ]; + } + + return $servicesProjectionList; + } + + public static function getScopeForProvider($providerId) + { + $scopeList = ZmsApiClientService::getScopes() ?? []; + foreach ($scopeList as $scope) { + if ($scope->provider->id === $providerId) { + return [ + "id" => $scope->id, + "provider" => $scope->provider, + "shortName" => $scope->shortName, + "telephoneActivated" => $scope->getTelephoneActivated(), + "telephoneRequired" => $scope->getTelephoneRequired(), + "customTextfieldActivated" => $scope->getCustomTextfieldActivated(), + "customTextfieldRequired" => $scope->getCustomTextfieldRequired(), + "customTextfieldLabel" => $scope->getCustomTextfieldLabel(), + "captchaActivatedRequired" => $scope->getCaptchaActivatedRequired(), + "displayInfo" => $scope->getDisplayInfo() + ]; + } + } + return null; + } + + public static function getServicesAndOffices() + { + $providerList = ZmsApiClientService::getOffices() ?? []; + $requestList = ZmsApiClientService::getServices() ?? []; + $relationList = ZmsApiClientService::getRequestRelationList() ?? []; + + $offices = MapperService::mapOfficesWithScope($providerList); + $services = MapperService::mapServicesWithCombinations($requestList, $relationList); + $relations = MapperService::mapRelations($relationList); + + return [ + 'offices' => $offices, + 'services' => $services, + 'relations' => $relations, + ]; + } + + /* Todo add method + * getCombinableServicesByIds + * + * + * + */ + + public static function getScopeByOfficeId($officeId) + { + try { + $scopes = self::getScopes(); + + foreach ($scopes as $scope) { + if (isset($scope['provider']) && $scope['provider']->id == $officeId) { + return $scope; + } + } + + return [ + 'error' => 'Scope not found for the provided office ID', + 'status' => 404 + ]; + } catch (\Exception $e) { + return [ + 'error' => 'Error fetching scope by office ID: ' . $e->getMessage(), + 'status' => 500 + ]; + } + } + + /* Todo add method + * getOfficeByIds + * + * + * + */ + + public static function getOfficesByServiceIds(array $serviceIds) + { + $serviceIds = array_unique($serviceIds); + + if (empty($serviceIds) || $serviceIds == ['']) { + return [ + 'offices' => [], + 'error' => 'Invalid serviceId(s)', + 'status' => 400 + ]; + } + + $providerList = ZmsApiClientService::getOffices(); + $requestRelationList = ZmsApiClientService::getRequestRelationList(); + + $offices = []; + $notFoundIds = []; + $addedOfficeIds = []; + + foreach ($serviceIds as $serviceId) { + $found = false; + foreach ($requestRelationList as $relation) { + if ($relation->request->id == $serviceId) { + if (!in_array($relation->provider->id, $addedOfficeIds)) { + foreach ($providerList as $provider) { + if ($provider->id == $relation->provider->id) { + $offices[] = [ + "id" => $provider->id, + "name" => $provider->name, + ]; + $addedOfficeIds[] = $provider->id; + $found = true; + break; + } + } + } else { + $found = true; + } + } + } + if (!$found) { + $notFoundIds[] = $serviceId; + } + } + + if (empty($offices)) { + return [ + 'offices' => [], + 'error' => 'Office(s) not found for the provided serviceId(s)', + 'status' => 404 + ]; + } + + $responseContent = ['offices' => $offices]; + if (!empty($notFoundIds)) { + $responseContent['warning'] = 'The following serviceId(s) were not found: ' . implode(', ', $notFoundIds); + } + + return [ + 'offices' => $responseContent, + 'status' => 200 + ]; + } + + public static function getScopeByIds(array $scopeIds) + { + $scopeIds = array_unique($scopeIds); + + if (empty($scopeIds) || $scopeIds == ['']) { + return [ + 'scopes' => [], + 'error' => 'Invalid scopeId(s)', + 'status' => 400 + ]; + } + + $scopeList = ZmsApiClientService::getScopes() ?? []; + $scopes = []; + $notFoundIds = []; + + foreach ($scopeIds as $scopeId) { + $found = false; + foreach ($scopeList as $scopeItem) { + if ($scopeItem->id == $scopeId) { + $scopes[] = [ + "id" => $scopeItem->id, + "provider" => [ + "id" => $scopeItem->provider->id, + "source" => $scopeItem->provider->source, + ], + "shortName" => $scopeItem->shortName, + "telephoneActivated" => $scopeItem->getTelephoneActivated(), + "telephoneRequired" => $scopeItem->getTelephoneRequired(), + "customTextfieldActivated" => $scopeItem->getCustomTextfieldActivated(), + "customTextfieldRequired" => $scopeItem->getCustomTextfieldRequired(), + "customTextfieldLabel" => $scopeItem->getCustomTextfieldLabel(), + "captchaActivatedRequired" => $scopeItem->getCaptchaActivatedRequired(), + "displayInfo" => $scopeItem->getDisplayInfo() + ]; + $found = true; + break; + } + } + + if (!$found) { + $notFoundIds[] = $scopeId; + } + } + + if (empty($scopes)) { + return [ + 'scopes' => [], + 'error' => 'Scope(s) not found', + 'status' => 404 + ]; + } + + $responseContent = ['scopes' => $scopes]; + if (!empty($notFoundIds)) { + $responseContent['warning'] = 'The following scopeId(s) were not found: ' . implode(', ', $notFoundIds); + } + + return [ + 'scopes' => $responseContent, + 'status' => 200 + ]; + } + + public static function getServicesByOfficeIds(array $officeIds) + { + $officeIds = array_unique($officeIds); + + if (empty($officeIds) || $officeIds == ['']) { + return [ + 'services' => [], + 'error' => 'Invalid officeId(s)', + 'status' => 400, + ]; + } + + $requestList = ZmsApiClientService::getServices() ?? []; + $requestRelationList = ZmsApiClientService::getRequestRelationList(); + + $services = []; + $notFoundIds = []; + $addedServices = []; + + foreach ($officeIds as $officeId) { + $found = false; + foreach ($requestRelationList as $relation) { + if ($relation->provider->id == $officeId) { + foreach ($requestList as $request) { + if ($request->id == $relation->request->id && !in_array($request->id, $addedServices)) { + $services[] = [ + "id" => $request->id, + "name" => $request->name, + "maxQuantity" => $request->getAdditionalData()['maxQuantity'] ?? 1, + ]; + $addedServices[] = $request->id; + $found = true; + } + } + } + } + if (!$found) { + $notFoundIds[] = $officeId; + } + } + + if (empty($services)) { + return [ + 'services' => [], + 'error' => 'Service(s) not found for the provided officeId(s)', + 'status' => 404, + ]; + } + + $responseContent = ['services' => $services]; + if (!empty($notFoundIds)) { + $responseContent['warning'] = 'The following officeId(s) were not found: ' . implode(', ', $notFoundIds); + } + + return [ + 'services' => $responseContent, + 'status' => 200, + ]; + } + + /* Todo add method + * getOfficesThatProvideService + * + * + * + */ + + public static function getServicesProvidedAtOffice($officeId) + { + + $requestRelationList = ZmsApiClientService::getRequestRelationList(); + + $requestRelationArray = []; + foreach ($requestRelationList as $relation) { + $requestRelationArray[] = $relation; + } + + $serviceIds = array_filter($requestRelationArray, function ($relation) use ($officeId) { + return $relation->provider->id === $officeId; + }); + + $serviceIds = array_map(function ($relation) { + return $relation->request->id; + }, $serviceIds); + + $requestList = ZmsApiClientService::getServices() ?? []; + $requestArray = []; + foreach ($requestList as $request) { + $requestArray[] = $request; + } + + return array_filter($requestArray, function ($request) use ($serviceIds) { + return in_array($request->id, $serviceIds); + }); + } + + public static function getBookableFreeDays(array $queryParams) + { + $officeId = $queryParams['officeId'] ?? null; + $serviceId = $queryParams['serviceId'] ?? null; + $serviceCounts = isset($queryParams['serviceCount']) ? explode(',', $queryParams['serviceCount']) : []; + $startDate = $queryParams['startDate'] ?? null; + $endDate = $queryParams['endDate'] ?? null; + + $errors = ValidationService::validateBookableFreeDays($officeId, $serviceId, $startDate, $endDate, $serviceCounts); + + if (!empty($errors)) { + return ['errors' => $errors, 'status' => 400]; + } + + try { + $firstDay = UtilityHelper::getInternalDateFromISO($startDate); + $lastDay = UtilityHelper::getInternalDateFromISO($endDate); + + $freeDays = ZmsApiClientService::getFreeDays( + [['id' => $officeId, 'source' => 'dldb']], + [ + [ + 'id' => $serviceId, + 'source' => 'dldb', + 'slotCount' => $serviceCounts, + ] + ], + $firstDay, + $lastDay, + ); + + $daysCollection = $freeDays->days; + $formattedDays = []; + + foreach ($daysCollection as $day) { + $formattedDays[] = sprintf('%04d-%02d-%02d', $day->year, $day->month, $day->day); + } + + if (empty($formattedDays)) { + return [ + 'availableDays' => [], + 'errorCode' => 'noAppointmentForThisScope', + 'errorMessage' => 'No available days found for the given criteria', + 'status' => 404, + ]; + } + + return [ + 'availableDays' => $formattedDays, + 'lastModified' => round(microtime(true) * 1000), + 'status' => 200, + ]; + + } catch (\Exception $e) { + error_log('Error in AvailableDaysService: ' . $e->getMessage()); + return [ + 'availableDays' => [], + 'errorCode' => 'internalError', + 'errorMessage' => 'An diesem Standort gibt es aktuell leider keine freien Termine', + 'lastModified' => round(microtime(true) * 1000), + 'status' => 500, + ]; + } + } + + + public static function getFreeAppointments(array $params) + { + $office = [ + 'id' => $params['officeId'], + 'source' => 'dldb' + ]; + + $requests = []; + + foreach ($params['serviceIds'] as $index => $serviceId) { + $service = [ + 'id' => $serviceId, + 'source' => 'dldb', + 'slotCount' => $params['serviceCounts'][$index] + ]; + $requests = array_merge($requests, array_fill(0, $service['slotCount'], $service)); + } + + try { + + $freeSlots = ZmsApiClientService::getFreeTimeslots( + [$office], + $requests, + $params['date'], + $params['date'] + ); + + $psr7Response = $freeSlots->getResponse(); + $responseBody = (string) $psr7Response->getBody(); + + $responseBody = json_decode($responseBody, true); + + return $responseBody['data']; + + } catch (\Exception $e) { + error_log('Error in AvailableAppointmentsService: ' . $e->getMessage()); + return [ + 'appointmentTimestamps' => [], + 'errorCode' => 'internalError', + 'errorMessage' => 'An error occurred while fetching available appointments', + 'status' => 500, + ]; + } + } + + public static function getAvailableAppointments(array $queryParams) + { + $date = $queryParams['date'] ?? null; + $officeId = $queryParams['officeId'] ?? null; + $serviceIds = isset($queryParams['serviceId']) ? explode(',', $queryParams['serviceId']) : []; + $serviceCounts = isset($queryParams['serviceCount']) ? explode(',', $queryParams['serviceCount']) : []; + + $errors = ValidationService::validateGetAvailableAppointments($date, $officeId, $serviceIds, $serviceCounts); + + if (!empty($errors)) { + return ['errors' => $errors, 'status' => 400]; + } + + try { + $requests = []; + foreach ($serviceIds as $index => $serviceId) { + $slotCount = isset($serviceCounts[$index]) ? intval($serviceCounts[$index]) : 1; + for ($i = 0; $i < $slotCount; $i++) { + $requests[] = [ + 'id' => $serviceId, + 'source' => 'dldb', + 'slotCount' => 1, + ]; + } + } + + $freeSlots = ZmsApiClientService::getFreeTimeslots( + [['id' => $officeId, 'source' => 'dldb']], + $requests, + UtilityHelper::getInternalDateFromISO($date), + UtilityHelper::getInternalDateFromISO($date) + ); + + if (!$freeSlots || !method_exists($freeSlots, 'getCollection')) { + throw new \Exception('Invalid response from API'); + } + + return self::processFreeSlots($freeSlots->getCollection()); + + } catch (\Exception $e) { + error_log('Error in AvailableAppointmentsService: ' . $e->getMessage()); + return [ + 'appointmentTimestamps' => [], + 'errorCode' => 'internalError', + 'errorMessage' => 'An error occurred while fetching available appointments', + 'status' => 500, + ]; + } + } + + private static function processFreeSlots($freeSlots) + { + if (empty($freeSlots) || !is_iterable($freeSlots)) { + return [ + 'appointmentTimestamps' => [], + 'errorCode' => 'appointmentNotAvailable', + 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', + 'status' => 404, + ]; + } + + $currentTimestamp = time(); + $appointmentTimestamps = []; + + foreach ($freeSlots as $slot) { + if (!isset($slot->appointments) || !is_iterable($slot->appointments)) { + continue; + } + + foreach ($slot->appointments as $appointment) { + + if (isset($appointment->date)) { + $timestamp = (int) $appointment->date; + + if (!in_array($timestamp, $appointmentTimestamps) && $timestamp > $currentTimestamp) { + $appointmentTimestamps[] = $timestamp; + } + } + } + } + + if (empty($appointmentTimestamps)) { + return [ + 'appointmentTimestamps' => [], + 'errorCode' => 'appointmentNotAvailable', + 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', + 'status' => 404, + ]; + } + + sort($appointmentTimestamps); + + return [ + 'appointmentTimestamps' => $appointmentTimestamps, + 'lastModified' => round(microtime(true) * 1000), + 'status' => 200, + ]; + } + + public static function reserveTimeslot($appointmentProcess, $serviceIds, $serviceCounts) + { + return ZmsApiClientService::reserveTimeslot($appointmentProcess, $serviceIds, $serviceCounts); + } + + public static function getProcessById($processId, $authKey) + { + $errors = ValidationService::validateGetAppointment($processId, $authKey); + if (!empty($errors)) { + return ['errors' => $errors, 'status' => 400]; + } + + try { + $process = ZmsApiClientService::getProcessById($processId, $authKey); + + if (!$process) { + return [ + 'errorMessage' => 'Termin wurde nicht gefunden', + 'status' => 404, + ]; + } + + $responseData = UtilityHelper::getThinnedProcessData($process); + return ['data' => $responseData, 'status' => 200]; + + } catch (\Exception $e) { + if (strpos($e->getMessage(), 'kein Termin gefunden') !== false) { + return [ + 'errorMessage' => 'Termin wurde nicht gefunden', + 'status' => 404, + ]; + } else { + return [ + 'error' => 'Unexpected error: ' . $e->getMessage(), + 'status' => 500, + ]; + } + } + } + + + /* Todo add method + * updateClientData + * + * + * + */ + + /* Todo add method + * preconfirmAppointment + * + * + * + */ + + + /* Todo add method + * confirmAppointment + * + * + * + */ + + /* Todo add method + * cancelAppointment + * + * + * + */ + +} \ No newline at end of file diff --git a/zmscitizenapi/src/Zmscitizenapi/ServicesByOfficeList.php b/zmscitizenapi/src/Zmscitizenapi/ServicesByOfficeList.php index 3296cd1f0..838272852 100644 --- a/zmscitizenapi/src/Zmscitizenapi/ServicesByOfficeList.php +++ b/zmscitizenapi/src/Zmscitizenapi/ServicesByOfficeList.php @@ -5,22 +5,16 @@ use BO\Zmscitizenapi\BaseController; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use BO\Zmscitizenapi\Services\ServicesService; +use BO\Zmscitizenapi\Services\ZmsApiFacadeService; class ServicesByOfficeList extends BaseController { - protected $servicesService; - - public function __construct() - { - $this->servicesService = new ServicesService(); - } public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { $officeIds = explode(',', $request->getQueryParams()['officeId'] ?? ''); - $result = $this->servicesService->getServicesByOfficeIds($officeIds); + $result = ZmsApiFacadeService::getServicesByOfficeIds($officeIds); if (isset($result['error'])) { return $this->createJsonResponse($response, $result, $result['status']); diff --git a/zmscitizenapi/src/Zmscitizenapi/ServicesList.php b/zmscitizenapi/src/Zmscitizenapi/ServicesList.php index 792862c76..48ab91ef2 100644 --- a/zmscitizenapi/src/Zmscitizenapi/ServicesList.php +++ b/zmscitizenapi/src/Zmscitizenapi/ServicesList.php @@ -6,20 +6,13 @@ use BO\Slim\Render; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use BO\Zmscitizenapi\Services\ServicesService; +use BO\Zmscitizenapi\Services\ZmsApiFacadeService; class ServicesList extends BaseController { - protected $servicesService; - - public function __construct() - { - $this->servicesService = new ServicesService(); - } - public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { - $services = $this->servicesService->getServices(); + $services = ZmsApiFacadeService::getServices(); return Render::withJson($response, ["services" => $services]); } } From ea2ede21624c7963d56a707841441c85bfdcdb65 Mon Sep 17 00:00:00 2001 From: Thomas Fink Date: Fri, 27 Sep 2024 17:49:09 +0200 Subject: [PATCH 10/10] feat(ZMS-2517): Zmscitizenapi Refactor Part 3 of 3 clean up validations and unit tests --- .../src/Zmscitizenapi/AppointmentReserve.php | 100 +--- .../AvailableAppointmentsList.php | 2 +- .../src/Zmscitizenapi/CaptchaGet.php | 4 +- .../Zmscitizenapi/OfficesByServiceList.php | 3 +- .../src/Zmscitizenapi/OfficesList.php | 4 +- .../OfficesServicesRelations.php | 6 +- .../src/Zmscitizenapi/ScopeByIdGet.php | 4 +- .../src/Zmscitizenapi/ScopesList.php | 4 +- .../Zmscitizenapi/Services/CaptchaService.php | 5 +- .../Services/ExceptionService.php | 20 + .../Services/ValidationService.php | 265 ++++++++-- .../Services/ZmsApiFacadeService.php | 228 ++++----- .../Zmscitizenapi/ServicesByOfficeList.php | 2 +- .../src/Zmscitizenapi/ServicesList.php | 4 +- .../Zmscitizenapi/AppointmentGetTest.php | 270 +++++++--- .../Zmscitizenapi/AppointmentReserveTest.php | 308 ++++++++---- .../AvailableAppointmentsListTest.php | 249 +++++---- .../Zmscitizenapi/AvailableDaysListTest.php | 474 ++++++++++++------ .../tests/Zmscitizenapi/CaptchaGetTest.php | 8 +- .../OfficesByServiceListTest.php | 43 +- .../tests/Zmscitizenapi/OfficesListTest.php | 19 +- .../OfficesServicesRelationsTest.php | 13 +- .../tests/Zmscitizenapi/ScopeByIdGetTest.php | 42 +- .../tests/Zmscitizenapi/ScopesListTest.php | 15 +- .../ServicesByOfficeListTest.php | 42 +- .../tests/Zmscitizenapi/ServicesListTest.php | 13 +- 26 files changed, 1385 insertions(+), 762 deletions(-) create mode 100644 zmscitizenapi/src/Zmscitizenapi/Services/ExceptionService.php diff --git a/zmscitizenapi/src/Zmscitizenapi/AppointmentReserve.php b/zmscitizenapi/src/Zmscitizenapi/AppointmentReserve.php index 42c985c06..c766ac750 100644 --- a/zmscitizenapi/src/Zmscitizenapi/AppointmentReserve.php +++ b/zmscitizenapi/src/Zmscitizenapi/AppointmentReserve.php @@ -29,70 +29,11 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo $captchaSolution = $body['captchaSolution'] ?? null; $timestamp = $body['timestamp'] ?? null; - $errors = []; - - if (!$officeId) { - $errors[] = [ - 'type' => 'field', - 'msg' => 'Missing officeId.', - 'path' => 'officeId', - 'location' => 'body' - ]; - } elseif (!is_numeric($officeId)) { - $errors[] = [ - 'type' => 'field', - 'msg' => 'Invalid officeId format. It should be a numeric value.', - 'path' => 'officeId', - 'location' => 'body' - ]; - } - - if (empty($serviceIds)) { - $errors[] = [ - 'type' => 'field', - 'msg' => 'Missing serviceId.', - 'path' => 'serviceId', - 'location' => 'body' - ]; - } elseif (!is_array($serviceIds) || array_filter($serviceIds, fn($id) => !is_numeric($id))) { - $errors[] = [ - 'type' => 'field', - 'msg' => 'Invalid serviceId format. It should be an array of numeric values.', - 'path' => 'serviceId', - 'location' => 'body' - ]; - } - - if (!$timestamp) { - $errors[] = [ - 'type' => 'field', - 'msg' => 'Missing timestamp.', - 'path' => 'timestamp', - 'location' => 'body' - ]; - } elseif (!is_numeric($timestamp) || $timestamp < 0) { - $errors[] = [ - 'type' => 'field', - 'msg' => 'Invalid timestamp format. It should be a positive numeric value.', - 'path' => 'timestamp', - 'location' => 'body' - ]; - } - - if (!is_array($serviceCounts) || array_filter($serviceCounts, fn($count) => !is_numeric($count) || $count < 0)) { - $errors[] = [ - 'type' => 'field', - 'msg' => 'Invalid serviceCount format. It should be an array of non-negative numeric values.', - 'path' => 'serviceCount', - 'location' => 'body' - ]; - } - if (!empty($errors)) { - return $this->createJsonResponse($response, [ - 'errors' => $errors, - 'status' => 400 - ], 400); + $errors = ValidationService::validatePostAppointmentReserve($officeId, $serviceIds, $serviceCounts, $captchaSolution, $timestamp); + if (!empty($errors['errors'])) { + return $this->createJsonResponse($response, + $errors, 400); } try { @@ -104,8 +45,7 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo if (!$captchaVerificationResult['success']) { return $this->createJsonResponse($response, [ 'errorCode' => 'captchaVerificationFailed', - 'errorMessage' => 'Captcha verification failed', - 'lastModified' => round(microtime(true) * 1000) + 'errorMessage' => 'Captcha verification failed' ], 400); } } @@ -115,16 +55,6 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo return $this->createJsonResponse($response, $serviceValidationResult, 400); } - try { - $internalDate = UtilityHelper::getInternalDateFromTimestamp($timestamp); - } catch (\Exception $e) { - return $this->createJsonResponse($response, [ - 'errorCode' => 'invalidTimestamp', - 'errorMessage' => 'The provided timestamp is invalid.', - 'lastModified' => round(microtime(true) * 1000) - ], 400); - } - $freeAppointments = ZmsApiFacadeService::getFreeAppointments([ 'officeId' => $officeId, 'serviceIds' => $serviceIds, @@ -139,12 +69,10 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo return in_array($timestamp, array_column($process['appointments'], 'date')); }); - if (empty($selectedProcess)) { - return $this->createJsonResponse($response, [ - 'errorCode' => 'appointmentNotAvailable', - 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', - 'lastModified' => round(microtime(true) * 1000) - ], 404); + $errors = ValidationService::validateGetProcessNotFound($selectedProcess); + if (!empty($errors['errors'])) { + return $this->createJsonResponse($response, + $errors, 404); } $selectedProcess = array_values($selectedProcess)[0]; @@ -171,11 +99,11 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo return $this->createJsonResponse($response, $thinnedProcessData, 200); } catch (\Exception $e) { - error_log('Unexpected error: ' . $e->getMessage()); - return $this->createJsonResponse($response, [ - 'error' => 'Unexpected error', - 'message' => $e->getMessage() - ], 500); + return [ + 'errorCode' => 'unexpectedError', + 'errorMessage' => 'Unexpected error: ' . $e->getMessage(), + 'status' => 500, + ]; } } diff --git a/zmscitizenapi/src/Zmscitizenapi/AvailableAppointmentsList.php b/zmscitizenapi/src/Zmscitizenapi/AvailableAppointmentsList.php index b93cc1d52..105e823ea 100644 --- a/zmscitizenapi/src/Zmscitizenapi/AvailableAppointmentsList.php +++ b/zmscitizenapi/src/Zmscitizenapi/AvailableAppointmentsList.php @@ -15,7 +15,7 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo $result = ZmsApiFacadeService::getAvailableAppointments($queryParams); - return $this->createJsonResponse($response, $result, $result['status']); + return $this->createJsonResponse($response, $result, statusCode: $result['status']); } } diff --git a/zmscitizenapi/src/Zmscitizenapi/CaptchaGet.php b/zmscitizenapi/src/Zmscitizenapi/CaptchaGet.php index 0b26610d1..4dcbed6b9 100644 --- a/zmscitizenapi/src/Zmscitizenapi/CaptchaGet.php +++ b/zmscitizenapi/src/Zmscitizenapi/CaptchaGet.php @@ -3,18 +3,16 @@ namespace BO\Zmscitizenapi; use BO\Zmscitizenapi\BaseController; -use BO\Slim\Render; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use BO\Zmscitizenapi\Services\CaptchaService; class CaptchaGet extends BaseController { - public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { $captchaDetails = CaptchaService::getCaptchaDetails(); - return Render::withJson($response, $captchaDetails); + return $this->createJsonResponse($response, $captchaDetails, statusCode: $captchaDetails['status']); } } diff --git a/zmscitizenapi/src/Zmscitizenapi/OfficesByServiceList.php b/zmscitizenapi/src/Zmscitizenapi/OfficesByServiceList.php index d305b81ce..dc3c2e475 100644 --- a/zmscitizenapi/src/Zmscitizenapi/OfficesByServiceList.php +++ b/zmscitizenapi/src/Zmscitizenapi/OfficesByServiceList.php @@ -3,7 +3,6 @@ namespace BO\Zmscitizenapi; use BO\Zmscitizenapi\BaseController; -use BO\Slim\Render; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use BO\Zmscitizenapi\Services\ZmsApiFacadeService; @@ -17,7 +16,7 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo $result = ZmsApiFacadeService::getOfficesByServiceIds($serviceIds); - if (isset($result['error'])) { + if (isset($result['errors'])) { return $this->createJsonResponse($response, $result, $result['status']); } diff --git a/zmscitizenapi/src/Zmscitizenapi/OfficesList.php b/zmscitizenapi/src/Zmscitizenapi/OfficesList.php index f89b403ff..27bb1ed5b 100644 --- a/zmscitizenapi/src/Zmscitizenapi/OfficesList.php +++ b/zmscitizenapi/src/Zmscitizenapi/OfficesList.php @@ -3,7 +3,6 @@ namespace BO\Zmscitizenapi; use BO\Zmscitizenapi\BaseController; -use BO\Slim\Render; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use BO\Zmscitizenapi\Services\ZmsApiFacadeService; @@ -13,6 +12,7 @@ class OfficesList extends BaseController public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { $offices = ZmsApiFacadeService::getOffices(); - return Render::withJson($response, ["offices" => $offices]); + + return $this->createJsonResponse($response, $offices, statusCode: $offices['status']); } } diff --git a/zmscitizenapi/src/Zmscitizenapi/OfficesServicesRelations.php b/zmscitizenapi/src/Zmscitizenapi/OfficesServicesRelations.php index d6569b044..9e89ad4bb 100644 --- a/zmscitizenapi/src/Zmscitizenapi/OfficesServicesRelations.php +++ b/zmscitizenapi/src/Zmscitizenapi/OfficesServicesRelations.php @@ -3,18 +3,16 @@ namespace BO\Zmscitizenapi; use BO\Zmscitizenapi\BaseController; -use BO\Slim\Render; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use BO\Zmscitizenapi\Services\ZmsApiFacadeService; class OfficesServicesRelations extends BaseController { - public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { - $data = ZmsApiFacadeService::getServicesAndOffices(); + $officesAndServices = ZmsApiFacadeService::getServicesAndOffices(); - return Render::withJson($response, $data); + return $this->createJsonResponse($response, $officesAndServices, statusCode: $officesAndServices['status']); } } diff --git a/zmscitizenapi/src/Zmscitizenapi/ScopeByIdGet.php b/zmscitizenapi/src/Zmscitizenapi/ScopeByIdGet.php index 6ec2146af..ba57dd411 100644 --- a/zmscitizenapi/src/Zmscitizenapi/ScopeByIdGet.php +++ b/zmscitizenapi/src/Zmscitizenapi/ScopeByIdGet.php @@ -15,9 +15,9 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo $result = ZmsApiFacadeService::getScopeByIds($scopeIds); - if (isset($result['error'])) { + if (isset($result['errors'])) { return $this->createJsonResponse($response, $result, $result['status']); - } + } return $this->createJsonResponse($response, $result['scopes'], $result['status']); } diff --git a/zmscitizenapi/src/Zmscitizenapi/ScopesList.php b/zmscitizenapi/src/Zmscitizenapi/ScopesList.php index ada550852..e8a8d1319 100644 --- a/zmscitizenapi/src/Zmscitizenapi/ScopesList.php +++ b/zmscitizenapi/src/Zmscitizenapi/ScopesList.php @@ -3,7 +3,6 @@ namespace BO\Zmscitizenapi; use BO\Zmscitizenapi\BaseController; -use BO\Slim\Render; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use BO\Zmscitizenapi\Services\ZmsApiFacadeService; @@ -13,6 +12,7 @@ class ScopesList extends BaseController public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { $scopes = ZmsApiFacadeService::getScopes(); - return Render::withJson($response, ["scopes" => $scopes]); + + return $this->createJsonResponse($response, $scopes, statusCode: $scopes['status']); } } diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/CaptchaService.php b/zmscitizenapi/src/Zmscitizenapi/Services/CaptchaService.php index 9cc933cc7..6af881555 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Services/CaptchaService.php +++ b/zmscitizenapi/src/Zmscitizenapi/Services/CaptchaService.php @@ -15,7 +15,8 @@ public static function getCaptchaDetails() 'siteKey' => Application::$FRIENDLYCAPTCHA_SITEKEY, 'captchaEndpoint' => Application::$FRIENDLYCAPTCHA_ENDPOINT, 'puzzle' => Application::$FRIENDLYCAPTCHA_ENDPOINT_PUZZLE, - 'captchaEnabled' => Application::$CAPTCHA_ENABLED + 'captchaEnabled' => Application::$CAPTCHA_ENABLED, + 'status' => 200 ]; } @@ -35,7 +36,7 @@ public static function verifyCaptcha($solution) } catch (RequestException $e) { $errorMessage = $e->hasResponse() ? $e->getResponse()->getBody()->getContents() : $e->getMessage(); //error_log('Error verifying captcha: ' . $errorMessage); - throw new Exception('Captcha verification failed'); + throw new Exception('Captcha verification failed.'); } } } diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/ExceptionService.php b/zmscitizenapi/src/Zmscitizenapi/Services/ExceptionService.php new file mode 100644 index 000000000..dec1e7a9a --- /dev/null +++ b/zmscitizenapi/src/Zmscitizenapi/Services/ExceptionService.php @@ -0,0 +1,20 @@ + 'noAppointmentForThisOffice', + 'errorMessage' => 'An diesem Standort gibt es aktuell leider keine freien Termine.', + 'status' => 404, + ]; + + return ['errors' => $errors, 'status' => 404]; + + } + +} \ No newline at end of file diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/ValidationService.php b/zmscitizenapi/src/Zmscitizenapi/Services/ValidationService.php index 64f204898..91b6c01fc 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Services/ValidationService.php +++ b/zmscitizenapi/src/Zmscitizenapi/Services/ValidationService.php @@ -7,8 +7,6 @@ class ValidationService public static function validateServiceLocationCombination($officeId, array $serviceIds) { - - $availableServices = ZmsApiFacadeService::getServicesProvidedAtOffice($officeId); $availableServiceIds = array_map(function ($service) { return $service['id']; @@ -24,8 +22,7 @@ public static function validateServiceLocationCombination($officeId, array $serv 'errorCode' => 'invalidLocationAndServiceCombination', 'errorMessage' => 'The provided service(s) do not exist at the given location.', 'invalidServiceIds' => $invalidServiceIds, - 'locationId' => $officeId, - 'lastModified' => time() * 1000, + 'locationId' => $officeId ]; } @@ -35,94 +32,282 @@ public static function validateServiceLocationCombination($officeId, array $serv ]; } - public static function validateBookableFreeDays($officeId, $serviceId, $startDate, $endDate, $serviceCounts) + public static function validateGetBookableFreeDays($officeId, $serviceId, $startDate, $endDate, $serviceCounts) { $errors = []; if (!$startDate) { - $errors[] = ['type' => 'field', 'msg' => 'startDate is required and must be a valid date', 'path' => 'startDate', 'location' => 'query']; + $errors[] = ['status' => 400, 'errorMessage' => 'startDate is required and must be a valid date.']; } if (!$endDate) { - $errors[] = ['type' => 'field', 'msg' => 'endDate is required and must be a valid date', 'path' => 'endDate', 'location' => 'query']; + $errors[] = ['status' => 400, 'errorMessage' => 'endDate is required and must be a valid date.']; } if (!$officeId || !is_numeric($officeId)) { - $errors[] = ['type' => 'field', 'msg' => 'officeId should be a 32-bit integer', 'path' => 'officeId', 'location' => 'query']; + $errors[] = ['status' => 400, 'errorMessage' => 'officeId should be a 32-bit integer.']; } if (!$serviceId || !is_numeric($serviceId)) { - $errors[] = ['type' => 'field', 'msg' => 'serviceId should be a 32-bit integer', 'path' => 'serviceId', 'location' => 'query']; + $errors[] = ['status' => 400, 'errorMessage' => 'serviceId should be a 32-bit integer.']; } if (empty($serviceCounts[0]) || !preg_match('/^\d+(,\d+)*$/', implode(',', $serviceCounts))) { - $errors[] = ['type' => 'field', 'msg' => 'serviceCount should be a comma-separated string of integers', 'path' => 'serviceCount', 'location' => 'query']; + $errors[] = ['status' => 400, 'errorMessage' => 'serviceCount should be a comma-separated string of integers.']; } - return $errors; + return ['errors' => $errors, 'status' => 400]; } - public static function validateGetAppointment($processId, $authKey) + public static function validateGetProcessById($processId, $authKey) { $errors = []; - if (!$processId || !is_numeric($processId) || intval($processId) <= 0) { $errors[] = [ - 'type' => 'field', - 'msg' => 'processId should be a 32-bit integer', - 'path' => 'processId', - 'location' => 'query' + 'status' => 400, + 'errorMessage' => 'processId should be a 32-bit integer.', ]; } if (!$authKey || !is_string($authKey)) { $errors[] = [ - 'type' => 'field', - 'msg' => 'authKey should be a string', - 'path' => 'authKey', - 'location' => 'query' + 'status' => 400, + 'errorMessage' => 'authKey should be a string.', ]; } - return $errors; + return ['errors' => $errors, 'status' => 400]; } public static function validateGetAvailableAppointments($date, $officeId, $serviceIds, $serviceCounts) { $errors = []; - if (!$date) { $errors[] = [ - 'type' => 'field', - 'msg' => 'date is required and must be a valid date', - 'path' => 'date', - 'location' => 'body' + 'status' => 400, + 'errorMessage' => 'date is required and must be a valid date.', ]; } if (!$officeId || !is_numeric($officeId)) { $errors[] = [ - 'type' => 'field', - 'msg' => 'officeId should be a 32-bit integer', - 'path' => 'officeId', - 'location' => 'body' + 'status' => 400, + 'errorMessage' => 'officeId should be a 32-bit integer.', ]; } if (empty($serviceIds[0]) || !preg_match('/^\d+(,\d+)*$/', implode(',', $serviceIds))) { $errors[] = [ - 'type' => 'field', - 'msg' => 'serviceId should be a comma-separated string of integers', - 'path' => 'serviceId', - 'location' => 'body' + 'status' => 400, + 'errorMessage' => 'serviceId should be a comma-separated string of integers.', ]; } if (empty($serviceCounts[0]) || !preg_match('/^\d+(,\d+)*$/', implode(',', $serviceCounts))) { $errors[] = [ - 'type' => 'field', - 'msg' => 'serviceCount should be a comma-separated string of integers', - 'path' => 'serviceCount', - 'location' => 'body' + 'status' => 400, + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', ]; } - return $errors; + return ['errors' => $errors, 'status' => 400]; + } + public static function validatePostAppointmentReserve($officeId, $serviceIds, $serviceCounts, $captchaSolution, $timestamp) + { + $errors = []; + if (!$officeId) { + $errors[] = [ + 'status' => 400, + 'errorMessage' => 'Missing officeId.', + ]; + } elseif (!is_numeric($officeId)) { + $errors[] = [ + 'status' => 400, + 'errorMessage' => 'Invalid officeId format. It should be a numeric value.', + ]; + } + + if (empty($serviceIds)) { + $errors[] = [ + 'status' => 400, + 'errorMessage' => 'Missing serviceId.', + ]; + } elseif (!is_array($serviceIds) || array_filter($serviceIds, fn($id) => !is_numeric($id))) { + $errors[] = [ + 'status' => 400, + 'errorMessage' => 'Invalid serviceId format. It should be an array of numeric values.', + ]; + } + + if (!$timestamp) { + $errors[] = [ + 'status' => 400, + 'errorMessage' => 'Missing timestamp.', + ]; + } elseif (!is_numeric($timestamp) || $timestamp < 0) { + $errors[] = [ + 'status' => 400, + 'errorMessage' => 'Invalid timestamp format. It should be a positive numeric value.', + ]; + } + + if (!is_array($serviceCounts) || array_filter($serviceCounts, fn($count) => !is_numeric($count) || $count < 0)) { + $errors[] = [ + 'status' => 400, + 'errorMessage' => 'Invalid serviceCount format. It should be an array of non-negative numeric values.', + ]; + } + + return ['errors' => $errors, 'status' => 400]; + } + + public static function validateGetOfficesByServiceIds($serviceIds) + { + $errors = []; + if (empty($serviceIds) || $serviceIds == ['']) { + $errors[] = [ + 'offices' => [], + 'errorMessage' => 'Invalid serviceId(s).', + 'status' => 400 + ]; + } + + return ['errors' => $errors, 'status' => 400]; + } + + public static function validateGetScopeByIds($scopeIds) + { + $errors = []; + if (empty($scopeIds) || $scopeIds == ['']) { + $errors[] = [ + 'scopes' => [], + 'errorMessage' => 'Invalid scopeId(s).', + 'status' => 400 + ]; + } + + return ['errors' => $errors, 'status' => 400]; + } + + public static function validateGetServicesByOfficeIds($officeIds){ + + $errors = []; + if (empty($officeIds) || $officeIds == ['']) { + $errors[] = [ + 'services' => [], + 'errorMessage' => 'Invalid officeId(s)', + 'status' => 400, + ]; + } + + return ['errors' => $errors, 'status' => 400]; + } + + public static function validateGetProcessFreeSlots($freeSlots) + { + $errors = []; + if (empty($freeSlots) || !is_iterable($freeSlots)) { + $errors[] = [ + 'appointmentTimestamps' => [], + 'errorCode' => 'appointmentNotAvailable', + 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', + 'status' => 404, + ]; + } + + return ['errors' => $errors, 'status' => 404]; + } + + public static function validateGetProcessByIdTimestamps($appointmentTimestamps) + { + $errors = []; + if (empty($appointmentTimestamps)) { + $errors[] = [ + 'appointmentTimestamps' => [], + 'errorCode' => 'appointmentNotAvailable', + 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', + 'status' => 404, + ]; + } + + return ['errors' => $errors, 'status' => 404]; + } + + public static function validateGetProcessNotFound($process) + { + $errors = []; + if (!$process) { + $errors[] = [ + 'errorCode' => 'appointmentNotAvailable', + 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', + 'status' => 404, + ]; + } + + return ['errors' => $errors, 'status' => 404]; + } + + public static function validateScopesNotFound($scopes) + { + $errors = []; + if (empty($scopes)) { + $errors[] = [ + 'errorCode' => 'scopesNotFound', + 'errorMessage' => 'Scope(s) not found.', + 'status' => 404, + ]; + } + + return ['errors' => $errors, 'status' => 404]; + } + + public static function validateServicesNotFound($services) + { + $errors = []; + if (empty($services)) { + $errors[] = [ + 'errorCode' => 'servicesNotFound', + 'errorMessage' => 'Service(s) not found for the provided officeId(s).', + 'status' => 404, + ]; + } + + return ['errors' => $errors, 'status' => 404]; + } + + public static function validateOfficesNotFound($offices) + { + $errors = []; + if (empty($offices)) { + $errors[] = [ + 'errorCode' => 'officesNotFound', + 'errorMessage' => 'Office(s) not found for the provided serviceId(s).', + 'status' => 404, + ]; + } + + return ['errors' => $errors, 'status' => 404]; + } + + public static function validateAppointmentDaysNotFound($formattedDays) + { + $errors = []; + if (empty($formattedDays)) { + $errors[] = [ + 'errorCode' => 'noAppointmentForThisDay', + 'errorMessage' => 'No available days found for the given criteria.', + 'status' => 404, + ]; + } + + return ['errors' => $errors, 'status' => 404]; + } + + public static function validateNoAppointmentsAtLocation(){ + + $errors[] = [ + 'errorCode' => 'noAppointmentForThisScope', + 'errorMessage' => 'An diesem Standort gibt es aktuell leider keine freien Termine.', + 'status' => 404, + ]; + + return ['errors' => $errors, 'status' => 404]; + } } \ No newline at end of file diff --git a/zmscitizenapi/src/Zmscitizenapi/Services/ZmsApiFacadeService.php b/zmscitizenapi/src/Zmscitizenapi/Services/ZmsApiFacadeService.php index 37c9bd15e..4f23c0597 100644 --- a/zmscitizenapi/src/Zmscitizenapi/Services/ZmsApiFacadeService.php +++ b/zmscitizenapi/src/Zmscitizenapi/Services/ZmsApiFacadeService.php @@ -11,7 +11,7 @@ public static function getOffices() { $scopeList = ZmsApiClientService::getScopes() ?? []; $providerProjectionList = []; - + foreach (ZmsApiClientService::getOffices() as $provider) { $matchingScope = null; foreach ($scopeList as $scope) { @@ -20,12 +20,12 @@ public static function getOffices() break; } } - + $providerData = [ "id" => $provider->id, "name" => $provider->displayName ?? $provider->name, ]; - + if ($matchingScope) { $providerData["scope"] = [ "id" => $matchingScope->id, @@ -40,12 +40,16 @@ public static function getOffices() "displayInfo" => $matchingScope->getDisplayInfo() ]; } - + $providerProjectionList[] = $providerData; } - - return $providerProjectionList; + + return [ + "offices" => $providerProjectionList, + "status" => 200 + ]; } + public static function getScopes() { @@ -67,7 +71,10 @@ public static function getScopes() ]; } - return $scopesProjectionList; + return [ + "scopes" => $scopesProjectionList, + "status" => 200 + ]; } public static function getServices() @@ -85,7 +92,10 @@ public static function getServices() ]; } - return $servicesProjectionList; + return [ + "services" => $servicesProjectionList, + "status" => 200 + ]; } public static function getScopeForProvider($providerId) @@ -121,9 +131,10 @@ public static function getServicesAndOffices() $relations = MapperService::mapRelations($relationList); return [ - 'offices' => $offices, - 'services' => $services, - 'relations' => $relations, + "offices" => $offices, + "services" => $services, + "relations" => $relations, + "status" => 200 ]; } @@ -168,12 +179,9 @@ public static function getOfficesByServiceIds(array $serviceIds) { $serviceIds = array_unique($serviceIds); - if (empty($serviceIds) || $serviceIds == ['']) { - return [ - 'offices' => [], - 'error' => 'Invalid serviceId(s)', - 'status' => 400 - ]; + $errors = ValidationService::validateGetOfficesByServiceIds($serviceIds); + if (!empty($errors['errors'])) { + return $errors; } $providerList = ZmsApiClientService::getOffices(); @@ -209,12 +217,9 @@ public static function getOfficesByServiceIds(array $serviceIds) } } - if (empty($offices)) { - return [ - 'offices' => [], - 'error' => 'Office(s) not found for the provided serviceId(s)', - 'status' => 404 - ]; + $errors = ValidationService::validateOfficesNotFound($offices); + if (!empty($errors['errors'])) { + return $errors; } $responseContent = ['offices' => $offices]; @@ -232,12 +237,9 @@ public static function getScopeByIds(array $scopeIds) { $scopeIds = array_unique($scopeIds); - if (empty($scopeIds) || $scopeIds == ['']) { - return [ - 'scopes' => [], - 'error' => 'Invalid scopeId(s)', - 'status' => 400 - ]; + $errors = ValidationService::validateGetScopeByIds($scopeIds); + if (!empty($errors['errors'])) { + return $errors; } $scopeList = ZmsApiClientService::getScopes() ?? []; @@ -273,12 +275,9 @@ public static function getScopeByIds(array $scopeIds) } } - if (empty($scopes)) { - return [ - 'scopes' => [], - 'error' => 'Scope(s) not found', - 'status' => 404 - ]; + $errors = ValidationService::validateScopesNotFound($scopes); + if (!empty($errors['errors'])) { + return $errors; } $responseContent = ['scopes' => $scopes]; @@ -296,12 +295,9 @@ public static function getServicesByOfficeIds(array $officeIds) { $officeIds = array_unique($officeIds); - if (empty($officeIds) || $officeIds == ['']) { - return [ - 'services' => [], - 'error' => 'Invalid officeId(s)', - 'status' => 400, - ]; + $errors = ValidationService::validateGetServicesByOfficeIds($officeIds); + if (!empty($errors['errors'])) { + return $errors; } $requestList = ZmsApiClientService::getServices() ?? []; @@ -333,12 +329,9 @@ public static function getServicesByOfficeIds(array $officeIds) } } - if (empty($services)) { - return [ - 'services' => [], - 'error' => 'Service(s) not found for the provided officeId(s)', - 'status' => 404, - ]; + $errors = ValidationService::validateServicesNotFound($services); + if (!empty($errors['errors'])) { + return $errors; } $responseContent = ['services' => $services]; @@ -396,10 +389,9 @@ public static function getBookableFreeDays(array $queryParams) $startDate = $queryParams['startDate'] ?? null; $endDate = $queryParams['endDate'] ?? null; - $errors = ValidationService::validateBookableFreeDays($officeId, $serviceId, $startDate, $endDate, $serviceCounts); - - if (!empty($errors)) { - return ['errors' => $errors, 'status' => 400]; + $errors = ValidationService::validateGetBookableFreeDays($officeId, $serviceId, $startDate, $endDate, $serviceCounts); + if (!empty($errors['errors'])) { + return $errors; } try { @@ -414,10 +406,10 @@ public static function getBookableFreeDays(array $queryParams) 'source' => 'dldb', 'slotCount' => $serviceCounts, ] - ], + ], $firstDay, $lastDay, - ); + ); $daysCollection = $freeDays->days; $formattedDays = []; @@ -426,34 +418,21 @@ public static function getBookableFreeDays(array $queryParams) $formattedDays[] = sprintf('%04d-%02d-%02d', $day->year, $day->month, $day->day); } - if (empty($formattedDays)) { - return [ - 'availableDays' => [], - 'errorCode' => 'noAppointmentForThisScope', - 'errorMessage' => 'No available days found for the given criteria', - 'status' => 404, - ]; + $errors = ValidationService::validateAppointmentDaysNotFound($formattedDays); + if (!empty($errors['errors'])) { + return $errors; } return [ 'availableDays' => $formattedDays, - 'lastModified' => round(microtime(true) * 1000), 'status' => 200, ]; } catch (\Exception $e) { - error_log('Error in AvailableDaysService: ' . $e->getMessage()); - return [ - 'availableDays' => [], - 'errorCode' => 'internalError', - 'errorMessage' => 'An diesem Standort gibt es aktuell leider keine freien Termine', - 'lastModified' => round(microtime(true) * 1000), - 'status' => 500, - ]; + //error_log('Error in AvailableDaysService: ' . $e->getMessage()); + return ExceptionService::exceptionNoAppointmentsAtLocation(); } } - - public static function getFreeAppointments(array $params) { $office = [ @@ -482,14 +461,14 @@ public static function getFreeAppointments(array $params) ); $psr7Response = $freeSlots->getResponse(); - $responseBody = (string) $psr7Response->getBody(); - + $responseBody = (string) $psr7Response->getBody(); + $responseBody = json_decode($responseBody, true); return $responseBody['data']; } catch (\Exception $e) { - error_log('Error in AvailableAppointmentsService: ' . $e->getMessage()); + //error_log('Error in AvailableAppointmentsService: ' . $e->getMessage()); return [ 'appointmentTimestamps' => [], 'errorCode' => 'internalError', @@ -507,9 +486,8 @@ public static function getAvailableAppointments(array $queryParams) $serviceCounts = isset($queryParams['serviceCount']) ? explode(',', $queryParams['serviceCount']) : []; $errors = ValidationService::validateGetAvailableAppointments($date, $officeId, $serviceIds, $serviceCounts); - - if (!empty($errors)) { - return ['errors' => $errors, 'status' => 400]; + if (!empty($errors['errors'])) { + return $errors; } try { @@ -530,7 +508,7 @@ public static function getAvailableAppointments(array $queryParams) $requests, UtilityHelper::getInternalDateFromISO($date), UtilityHelper::getInternalDateFromISO($date) - ); + ); if (!$freeSlots || !method_exists($freeSlots, 'getCollection')) { throw new \Exception('Invalid response from API'); @@ -539,7 +517,6 @@ public static function getAvailableAppointments(array $queryParams) return self::processFreeSlots($freeSlots->getCollection()); } catch (\Exception $e) { - error_log('Error in AvailableAppointmentsService: ' . $e->getMessage()); return [ 'appointmentTimestamps' => [], 'errorCode' => 'internalError', @@ -551,13 +528,10 @@ public static function getAvailableAppointments(array $queryParams) private static function processFreeSlots($freeSlots) { - if (empty($freeSlots) || !is_iterable($freeSlots)) { - return [ - 'appointmentTimestamps' => [], - 'errorCode' => 'appointmentNotAvailable', - 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', - 'status' => 404, - ]; + + $errors = ValidationService::validateGetProcessFreeSlots($freeSlots); + if (!empty($errors['errors'])) { + return $errors; } $currentTimestamp = time(); @@ -580,63 +554,59 @@ private static function processFreeSlots($freeSlots) } } - if (empty($appointmentTimestamps)) { - return [ - 'appointmentTimestamps' => [], - 'errorCode' => 'appointmentNotAvailable', - 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', - 'status' => 404, - ]; + $errors = ValidationService::validateGetProcessByIdTimestamps($appointmentTimestamps); + if (!empty($errors['errors'])) { + return $errors; } sort($appointmentTimestamps); return [ 'appointmentTimestamps' => $appointmentTimestamps, - 'lastModified' => round(microtime(true) * 1000), 'status' => 200, ]; } public static function reserveTimeslot($appointmentProcess, $serviceIds, $serviceCounts) { - return ZmsApiClientService::reserveTimeslot($appointmentProcess, $serviceIds, $serviceCounts); + return ZmsApiClientService::reserveTimeslot($appointmentProcess, $serviceIds, $serviceCounts); } - public static function getProcessById($processId, $authKey) - { - $errors = ValidationService::validateGetAppointment($processId, $authKey); - if (!empty($errors)) { - return ['errors' => $errors, 'status' => 400]; - } - - try { - $process = ZmsApiClientService::getProcessById($processId, $authKey); - - if (!$process) { - return [ - 'errorMessage' => 'Termin wurde nicht gefunden', - 'status' => 404, - ]; - } - - $responseData = UtilityHelper::getThinnedProcessData($process); - return ['data' => $responseData, 'status' => 200]; - - } catch (\Exception $e) { - if (strpos($e->getMessage(), 'kein Termin gefunden') !== false) { - return [ - 'errorMessage' => 'Termin wurde nicht gefunden', - 'status' => 404, - ]; - } else { - return [ - 'error' => 'Unexpected error: ' . $e->getMessage(), - 'status' => 500, - ]; - } - } - } + public static function getProcessById($processId, $authKey) + { + $errors = ValidationService::validateGetProcessById($processId, $authKey); + if (!empty($errors['errors'])) { + return $errors; + } + + try { + $process = ZmsApiClientService::getProcessById($processId, $authKey); + + + $errors = ValidationService::validateGetProcessNotFound($process); + if (!empty($errors['errors'])) { + return $errors; + } + + $responseData = UtilityHelper::getThinnedProcessData($process); + return ['data' => $responseData, 'status' => 200]; + + } catch (\Exception $e) { + if (strpos($e->getMessage(), 'kein Termin gefunden') !== false) { + return [ + 'errorCode' => 'appointmentNotFound', + 'errorMessage' => 'Termin wurde nicht gefunden.', + 'status' => 404, + ]; + } else { + return [ + 'errorCode' => 'unexpectedError', + 'errorMessage' => 'Unexpected error: ' . $e->getMessage(), + 'status' => 500, + ]; + } + } + } /* Todo add method diff --git a/zmscitizenapi/src/Zmscitizenapi/ServicesByOfficeList.php b/zmscitizenapi/src/Zmscitizenapi/ServicesByOfficeList.php index 838272852..1c1812758 100644 --- a/zmscitizenapi/src/Zmscitizenapi/ServicesByOfficeList.php +++ b/zmscitizenapi/src/Zmscitizenapi/ServicesByOfficeList.php @@ -16,7 +16,7 @@ public function readResponse(RequestInterface $request, ResponseInterface $respo $result = ZmsApiFacadeService::getServicesByOfficeIds($officeIds); - if (isset($result['error'])) { + if (isset($result['errors'])) { return $this->createJsonResponse($response, $result, $result['status']); } diff --git a/zmscitizenapi/src/Zmscitizenapi/ServicesList.php b/zmscitizenapi/src/Zmscitizenapi/ServicesList.php index 48ab91ef2..a57adc64f 100644 --- a/zmscitizenapi/src/Zmscitizenapi/ServicesList.php +++ b/zmscitizenapi/src/Zmscitizenapi/ServicesList.php @@ -3,7 +3,6 @@ namespace BO\Zmscitizenapi; use BO\Zmscitizenapi\BaseController; -use BO\Slim\Render; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use BO\Zmscitizenapi\Services\ZmsApiFacadeService; @@ -13,6 +12,7 @@ class ServicesList extends BaseController public function readResponse(RequestInterface $request, ResponseInterface $response, array $args) { $services = ZmsApiFacadeService::getServices(); - return Render::withJson($response, ["services" => $services]); + + return $this->createJsonResponse($response, $services, statusCode: $services['status']); } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/AppointmentGetTest.php b/zmscitizenapi/tests/Zmscitizenapi/AppointmentGetTest.php index 1b5c757d4..858ddc948 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AppointmentGetTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AppointmentGetTest.php @@ -30,45 +30,132 @@ public function testRendering() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'processId' => '101002', + 'timestamp' => 1724907600, + 'authKey' => 'fb43', + 'familyName' => 'Doe', + 'customTextfield' => '', + 'email' => 'johndoe@example.com', + 'telephone' => '0123456789', + 'officeName' => 'Bürgerbüro Orleansplatz DEV (KVR-II/231 DEV)', + 'officeId' => '102522', + 'scope' => [ + '$schema' => 'https://schema.berlin.de/queuemanagement/scope.json', + 'id' => '64', + 'source' => 'dldb', + 'contact' => [ + 'name' => 'Bürgerbüro Orleansplatz DEV (KVR-II/231 DEV)', + 'street' => 'Orleansstraße 50', + 'email' => '', + 'country' => 'Germany' + ], + 'provider' => [ + 'contact' => [ + 'city' => 'Muenchen', + 'country' => 'Germany', + 'name' => 'Bürgerbüro Orleansplatz DEV (KVR-II/231 DEV)', + 'postalCode' => '81667', + 'region' => 'Muenchen', + 'street' => 'Orleansstraße', + 'streetNumber' => '50' + ], + 'id' => '102522', + 'link' => 'https://service.berlin.de/standort/102522/', + 'name' => 'Bürgerbüro Orleansplatz DEV (KVR-II/231 DEV)', + 'displayName' => 'Bürgerbüro Orleansplatz DEV', + 'source' => 'dldb' + ], + 'hint' => '', + 'lastChange' => 1724192287, + 'preferences' => [ + 'appointment' => [ + 'deallocationDuration' => '15', + 'endInDaysDefault' => '60', + 'multipleSlotsEnabled' => '0', + 'reservationDuration' => '15', + 'activationDuration' => '15', + 'startInDaysDefault' => '2', + 'notificationConfirmationEnabled' => '0', + 'notificationHeadsUpEnabled' => '0' + ], + 'client' => [ + 'alternateAppointmentUrl' => '', + 'amendmentActivated' => '0', + 'amendmentLabel' => '', + 'emailFrom' => 'terminvereinbarung@muenchen.de', + 'emailRequired' => '0', + 'telephoneActivated' => '1', + 'telephoneRequired' => '1', + 'appointmentsPerMail' => '1', + 'customTextfieldActivated' => '1', + 'customTextfieldRequired' => '1', + 'customTextfieldLabel' => 'Nachname des Kindes', + 'captchaActivatedRequired' => '0', + 'adminMailOnAppointment' => 0, + 'adminMailOnDeleted' => 0, + 'adminMailOnUpdated' => 0, + 'adminMailOnMailSent' => 0 + ], + 'notifications' => [ + 'confirmationContent' => '', + 'headsUpContent' => '', + 'headsUpTime' => '10' + ], + 'pickup' => [ + 'alternateName' => 'Ausgabe', + 'isDefault' => '0' + ], + 'queue' => [ + 'callCountMax' => '1', + 'callDisplayText' => 'Herzlich Willkommen', + 'firstNumber' => '1', + 'lastNumber' => '999', + 'maxNumberContingent' => '999', + 'processingTimeAverage' => '12', + 'publishWaitingTimeEnabled' => '0', + 'statisticsEnabled' => '0' + ], + 'survey' => [ + 'emailContent' => '', + 'enabled' => '0', + 'label' => '' + ], + 'ticketprinter' => [ + 'buttonName' => 'Bürgerbüro Orleansplatz (KVR-II/231)', + 'confirmationEnabled' => '0', + 'deactivatedText' => 'dasdsa', + 'notificationsAmendmentEnabled' => '0', + 'notificationsEnabled' => '0', + 'notificationsDelay' => '0' + ], + 'workstation' => [ + 'emergencyEnabled' => '0', + 'emergencyRefreshInterval' => '5' + ] + ], + 'shortName' => 'DEVV', + 'status' => [ + 'emergency' => [ + 'activated' => '0' + ], + 'queue' => [ + 'ghostWorkstationCount' => '-1', + 'givenNumberCount' => '4', + 'lastGivenNumber' => '4', + 'lastGivenNumberTimestamp' => 1715292000 + ], + 'ticketprinter' => [ + 'deactivated' => '0' + ] + ] + ], + 'subRequestCounts' => [], + 'serviceId' => '1063424', + 'serviceCount' => 1 + ]; $this->assertEquals(200, $response->getStatusCode()); - - $this->assertArrayHasKey('processId', $responseBody); - $this->assertEquals('101002', $responseBody['processId']); - - $this->assertArrayHasKey('timestamp', $responseBody); - $this->assertEquals(1724907600, $responseBody['timestamp']); - - $this->assertArrayHasKey('authKey', $responseBody); - $this->assertEquals('fb43', $responseBody['authKey']); - - $this->assertArrayHasKey('familyName', $responseBody); - $this->assertEquals('Doe', $responseBody['familyName']); - - $this->assertArrayHasKey('email', $responseBody); - $this->assertEquals('johndoe@example.com', $responseBody['email']); - - $this->assertArrayHasKey('telephone', $responseBody); - $this->assertEquals('0123456789', $responseBody['telephone']); - - $this->assertArrayHasKey('officeName', $responseBody); - $this->assertEquals('Bürgerbüro Orleansplatz DEV (KVR-II/231 DEV)', $responseBody['officeName']); - - $this->assertArrayHasKey('officeId', $responseBody); - $this->assertEquals('102522', $responseBody['officeId']); - - $this->assertArrayHasKey('scope', $responseBody); - $this->assertArrayHasKey('id', $responseBody['scope']); - $this->assertEquals('64', $responseBody['scope']['id']); - - $this->assertArrayHasKey('serviceId', $responseBody); - $this->assertEquals('1063424', $responseBody['serviceId']); - - $this->assertArrayHasKey('serviceCount', $responseBody); - $this->assertEquals(1, $responseBody['serviceCount']); - - $this->assertArrayHasKey('subRequestCounts', $responseBody); - $this->assertEmpty($responseBody['subRequestCounts']); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testMissingProcessId() @@ -79,10 +166,17 @@ public function testMissingProcessId() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'processId should be a 32-bit integer.' + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertEquals('processId should be a 32-bit integer', $responseBody['errors'][0]['msg']); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testMissingAuthKey() @@ -93,10 +187,17 @@ public function testMissingAuthKey() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'authKey should be a string.' + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertEquals('authKey should be a string', $responseBody['errors'][0]['msg']); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testInvalidProcessId() @@ -108,10 +209,17 @@ public function testInvalidProcessId() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'processId should be a 32-bit integer.' + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertEquals('processId should be a 32-bit integer', $responseBody['errors'][0]['msg']); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testInvalidAuthKey() @@ -123,10 +231,17 @@ public function testInvalidAuthKey() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'authKey should be a string.' + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertEquals('authKey should be a string', $responseBody['errors'][0]['msg']); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testBothParametersMissing() @@ -135,32 +250,22 @@ public function testBothParametersMissing() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $errors = $responseBody['errors']; - - $this->assertCount(2, $errors); - - $this->assertContains( - [ - 'type' => 'field', - 'msg' => 'processId should be a 32-bit integer', - 'path' => 'processId', - 'location' => 'query' + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'processId should be a 32-bit integer.', + ], + [ + 'status' => 400, + 'errorMessage' => 'authKey should be a string.', + ] ], - $errors - ); + 'status' => 400 + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); - $this->assertContains( - [ - 'type' => 'field', - 'msg' => 'authKey should be a string', - 'path' => 'authKey', - 'location' => 'query' - ], - $errors - ); } public function testAppointmentNotFound() @@ -177,18 +282,21 @@ public function testAppointmentNotFound() ] ] ); - + $parameters = [ 'processId' => '101002', 'authKey' => 'fb43', ]; - + $response = $this->render([], $parameters, []); - $responseBody = json_decode((string)$response->getBody(), true); - + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errorCode' => 'appointmentNotFound', + 'errorMessage' => 'Termin wurde nicht gefunden.', + 'status' => 404, + ]; $this->assertEquals(404, $response->getStatusCode()); - - $this->assertArrayHasKey('errorMessage', $responseBody); - $this->assertEquals('Termin wurde nicht gefunden', $responseBody['errorMessage']); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); } + } diff --git a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php index 17c8f45de..45dfe6e0c 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AppointmentReserveTest.php @@ -43,19 +43,37 @@ public function testRendering() $response = $this->render([], $parameters, [], 'POST'); $responseBody = json_decode((string) $response->getBody(), true); - $this->assertEquals(200, $response->getStatusCode(), 'Expected a 200 OK response.'); - $this->assertArrayHasKey('processId', $responseBody, 'Expected processId in response.'); - $this->assertArrayHasKey('email', $responseBody, 'Expected email in response.'); - $this->assertEquals('test@muenchen.de', $responseBody['email'], 'Expected test@muenchen.de email.'); - $this->assertArrayHasKey('authKey', $responseBody, 'Expected authKey in response.'); - $this->assertEquals('b93e', $responseBody['authKey'], 'Expected correct authKey.'); - $this->assertArrayHasKey('timestamp', $responseBody, 'Expected timestamp in response.'); - $this->assertEquals('32526616522', $responseBody['timestamp'], 'Expected correct timestamp.'); - $this->assertArrayHasKey('scope', $responseBody, 'Expected scope in response.'); - $this->assertEquals('58', $responseBody['scope']['id'], 'Expected correct scope id.'); - $this->assertEquals('dldb', $responseBody['scope']['provider']['source'], 'Expected correct provider source.'); - $this->assertArrayHasKey('serviceCount', $responseBody, 'Expected serviceCount in response.'); - $this->assertEquals(0, $responseBody['serviceCount'], 'Expected serviceCount to be 0.'); + $expectedResponse = [ + 'processId' => '101142', + 'timestamp' => 32526616522, + 'authKey' => 'b93e', + 'familyName' => '', + 'customTextfield' => '', + 'email' => 'test@muenchen.de', + 'telephone' => '', + 'officeName' => null, + 'officeId' => '10546', + 'scope' => [ + 'id' => '58', + 'provider' => [ + 'id' => '10546', + 'source' => 'dldb' + ], + 'shortName' => 'Gewerbemeldungen', + 'telephoneActivated' => '0', + 'telephoneRequired' => '1', + 'customTextfieldActivated' => '0', + 'customTextfieldRequired' => '1', + 'customTextfieldLabel' => '', + 'captchaActivatedRequired' => '0', + 'displayInfo' => null + ], + 'subRequestCounts' => [], + 'serviceId' => null, + 'serviceCount' => 0 + ]; + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testAppointmentNotAvailable() @@ -77,7 +95,7 @@ public function testAppointmentNotAvailable() ] ] ); - + $parameters = [ 'officeId' => '10546', 'serviceId' => ['1063423'], @@ -85,14 +103,21 @@ public function testAppointmentNotAvailable() 'timestamp' => "32526616300", 'captchaSolution' => null ]; - + $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string) $response->getBody(), true); - - $this->assertEquals(404, $response->getStatusCode(), 'Expected a 404 Not Found response.'); - $this->assertArrayHasKey('errorCode', $responseBody, 'Expected errorCode in response.'); - $this->assertEquals('appointmentNotAvailable', $responseBody['errorCode'], 'Expected errorCode to be appointmentNotAvailable.'); - $this->assertArrayHasKey('errorMessage', $responseBody, 'Expected errorMessage in response.'); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errors' => [ + [ + 'errorCode' => 'appointmentNotAvailable', + 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', + 'status' => 404, + ] + ], + 'status' => 404 + ]; + $this->assertEquals(404, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testMissingOfficeId() @@ -107,12 +132,18 @@ public function testMissingOfficeId() ]; $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string) $response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); - $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); - $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); - $this->assertEquals('Missing officeId.', $responseBody['errors'][0]['msg'], 'Expected error message for missing officeId.'); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'Missing officeId.', + ] + ], + 'status' => 400 + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testMissingServiceId() @@ -127,12 +158,18 @@ public function testMissingServiceId() ]; $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string) $response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); - $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); - $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); - $this->assertEquals('Missing serviceId.', $responseBody['errors'][0]['msg'], 'Expected error message for missing serviceId.'); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'Missing serviceId.', + ] + ], + 'status' => 400 + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testMissingTimestamp() @@ -147,12 +184,18 @@ public function testMissingTimestamp() ]; $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string) $response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); - $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); - $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); - $this->assertEquals('Missing timestamp.', $responseBody['errors'][0]['msg'], 'Expected error message for missing timestamp.'); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'Missing timestamp.', + ] + ], + 'status' => 400 + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testMissingOfficeIdAndServiceId() @@ -166,13 +209,22 @@ public function testMissingOfficeIdAndServiceId() ]; $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string) $response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); - $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); - $this->assertCount(2, $responseBody['errors'], 'Expected two errors in response.'); - $this->assertEquals('Missing officeId.', $responseBody['errors'][0]['msg'], 'Expected error message for missing officeId.'); - $this->assertEquals('Missing serviceId.', $responseBody['errors'][1]['msg'], 'Expected error message for missing serviceId.'); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'Missing officeId.', + ], + [ + 'status' => 400, + 'errorMessage' => 'Missing serviceId.', + ] + ], + 'status' => 400 + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testMissingOfficeIdAndTimestamp() @@ -186,13 +238,22 @@ public function testMissingOfficeIdAndTimestamp() ]; $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string) $response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); - $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); - $this->assertCount(2, $responseBody['errors'], 'Expected two errors in response.'); - $this->assertEquals('Missing officeId.', $responseBody['errors'][0]['msg'], 'Expected error message for missing officeId.'); - $this->assertEquals('Missing timestamp.', $responseBody['errors'][1]['msg'], 'Expected error message for missing timestamp.'); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'Missing officeId.', + ], + [ + 'status' => 400, + 'errorMessage' => 'Missing timestamp.', + ] + ], + 'status' => 400 + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testMissingServiceIdAndTimestamp() @@ -206,13 +267,22 @@ public function testMissingServiceIdAndTimestamp() ]; $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string) $response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); - $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); - $this->assertCount(2, $responseBody['errors'], 'Expected two errors in response.'); - $this->assertEquals('Missing serviceId.', $responseBody['errors'][0]['msg'], 'Expected error message for missing serviceId.'); - $this->assertEquals('Missing timestamp.', $responseBody['errors'][1]['msg'], 'Expected error message for missing timestamp.'); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'Missing serviceId.', + ], + [ + 'status' => 400, + 'errorMessage' => 'Missing timestamp.', + ] + ], + 'status' => 400 + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testMissingAllFields() @@ -222,14 +292,26 @@ public function testMissingAllFields() $parameters = []; $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string) $response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); - $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); - $this->assertCount(3, $responseBody['errors'], 'Expected three errors in response.'); - $this->assertEquals('Missing officeId.', $responseBody['errors'][0]['msg'], 'Expected error message for missing officeId.'); - $this->assertEquals('Missing serviceId.', $responseBody['errors'][1]['msg'], 'Expected error message for missing serviceId.'); - $this->assertEquals('Missing timestamp.', $responseBody['errors'][2]['msg'], 'Expected error message for missing timestamp.'); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'Missing officeId.', + ], + [ + 'status' => 400, + 'errorMessage' => 'Missing serviceId.', + ], + [ + 'status' => 400, + 'errorMessage' => 'Missing timestamp.', + ] + ], + 'status' => 400 + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testInvalidOfficeIdFormat() @@ -245,12 +327,18 @@ public function testInvalidOfficeIdFormat() ]; $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string) $response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); - $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); - $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); - $this->assertEquals('Invalid officeId format. It should be a numeric value.', $responseBody['errors'][0]['msg'], 'Expected error message for invalid officeId format.'); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'Invalid officeId format. It should be a numeric value.', + ] + ], + 'status' => 400 + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testInvalidServiceIdFormat() @@ -266,12 +354,18 @@ public function testInvalidServiceIdFormat() ]; $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string) $response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); - $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); - $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); - $this->assertEquals('Invalid serviceId format. It should be an array of numeric values.', $responseBody['errors'][0]['msg'], 'Expected error message for invalid serviceId format.'); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'Invalid serviceId format. It should be an array of numeric values.', + ] + ], + 'status' => 400 + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testInvalidTimestampFormat() @@ -287,12 +381,18 @@ public function testInvalidTimestampFormat() ]; $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string) $response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); - $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); - $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); - $this->assertEquals('Invalid timestamp format. It should be a positive numeric value.', $responseBody['errors'][0]['msg'], 'Expected error message for invalid timestamp format.'); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'Invalid timestamp format. It should be a positive numeric value.', + ] + ], + 'status' => 400 + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testEmptyServiceIdArray() { @@ -307,12 +407,18 @@ public function testEmptyServiceIdArray() ]; $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string) $response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); - $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); - $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); - $this->assertEquals('Missing serviceId.', $responseBody['errors'][0]['msg'], 'Expected error message for empty serviceId array.'); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'Missing serviceId.', + ] + ], + 'status' => 400 + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testInvalidServiceCount() @@ -328,12 +434,18 @@ public function testInvalidServiceCount() ]; $response = $this->render([], $parameters, [], 'POST'); - $responseBody = json_decode((string) $response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode(), 'Expected a 400 Bad Request response.'); - $this->assertArrayHasKey('errors', $responseBody, 'Expected errors in response.'); - $this->assertCount(1, $responseBody['errors'], 'Expected one error in response.'); - $this->assertEquals('Invalid serviceCount format. It should be an array of non-negative numeric values.', $responseBody['errors'][0]['msg'], 'Expected error message for invalid serviceCount.'); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'errors' => [ + [ + 'status' => 400, + 'errorMessage' => 'Invalid serviceCount format. It should be an array of non-negative numeric values.', + ] + ], + 'status' => 400 + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php b/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php index a807edc11..8d320b570 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AvailableAppointmentsListTest.php @@ -27,18 +27,12 @@ public function testRendering() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - - $this->assertEquals(200, $response->getStatusCode(), 'Expected a 200 OK response.'); - - $this->assertArrayHasKey('appointmentTimestamps', $responseBody, 'Expected appointmentTimestamps in response.'); - $this->assertNotEmpty($responseBody['appointmentTimestamps'], 'Expected non-empty appointmentTimestamps.'); - $this->assertTrue(is_array($responseBody['appointmentTimestamps']), 'Expected appointmentTimestamps to be an array.'); - - $this->assertTrue(count($responseBody['appointmentTimestamps']) > 0, 'Expected more than 0 timestamps.'); - $this->assertTrue(is_numeric($responseBody['appointmentTimestamps'][0]), 'Expected numeric timestamps.'); - - $this->assertArrayHasKey('lastModified', $responseBody, 'Expected lastModified in response.'); - $this->assertTrue(is_numeric($responseBody['lastModified']), 'Expected lastModified to be a numeric timestamp.'); + $expectedResponse = [ + 'appointmentTimestamps' => [32526616522], + 'status' => 200, + ]; + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } @@ -62,18 +56,19 @@ public function testEmptyAppointments() ]; $response = $this->render([], $parameters, []); - $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'appointmentTimestamps' => [], + 'errorCode' => "appointmentNotAvailable", + 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', + 'status' => 404, + ] + ], + 'status' => 404 + ]; $this->assertEquals(404, $response->getStatusCode()); - - $this->assertArrayHasKey('errorCode', $responseBody); - $this->assertEquals('appointmentNotAvailable', $responseBody['errorCode']); - - $this->assertArrayHasKey('errorMessage', $responseBody); - $this->assertEquals('Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.', $responseBody['errorMessage']); - - $this->assertArrayHasKey('appointmentTimestamps', $responseBody); - $this->assertEmpty($responseBody['appointmentTimestamps']); + $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); } public function testDateMissing() @@ -86,13 +81,17 @@ public function testDateMissing() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'date is required and must be a valid date.', + 'status' => 400, + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertContains( - ['type' => 'field', 'msg' => 'date is required and must be a valid date', 'path' => 'date', 'location' => 'body'], - $responseBody['errors'] - ); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testOfficeIdMissing() @@ -105,13 +104,17 @@ public function testOfficeIdMissing() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'officeId should be a 32-bit integer.', + 'status' => 400, + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertContains( - ['type' => 'field', 'msg' => 'officeId should be a 32-bit integer', 'path' => 'officeId', 'location' => 'body'], - $responseBody['errors'] - ); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testServiceIdMissing() @@ -124,13 +127,17 @@ public function testServiceIdMissing() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'serviceId should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertContains( - ['type' => 'field', 'msg' => 'serviceId should be a comma-separated string of integers', 'path' => 'serviceId', 'location' => 'body'], - $responseBody['errors'] - ); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testServiceCountMissing() @@ -143,13 +150,17 @@ public function testServiceCountMissing() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertContains( - ['type' => 'field', 'msg' => 'serviceCount should be a comma-separated string of integers', 'path' => 'serviceCount', 'location' => 'body'], - $responseBody['errors'] - ); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testDateAndOfficeIdMissing() @@ -161,17 +172,21 @@ public function testDateAndOfficeIdMissing() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'date is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'officeId should be a 32-bit integer.', + 'status' => 400, + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertContains( - ['type' => 'field', 'msg' => 'date is required and must be a valid date', 'path' => 'date', 'location' => 'body'], - $responseBody['errors'] - ); - $this->assertContains( - ['type' => 'field', 'msg' => 'officeId should be a 32-bit integer', 'path' => 'officeId', 'location' => 'body'], - $responseBody['errors'] - ); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testDateAndServiceIdMissing() @@ -183,17 +198,21 @@ public function testDateAndServiceIdMissing() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'date is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceId should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertContains( - ['type' => 'field', 'msg' => 'date is required and must be a valid date', 'path' => 'date', 'location' => 'body'], - $responseBody['errors'] - ); - $this->assertContains( - ['type' => 'field', 'msg' => 'serviceId should be a comma-separated string of integers', 'path' => 'serviceId', 'location' => 'body'], - $responseBody['errors'] - ); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testDateAndServiceCountMissing() @@ -205,17 +224,21 @@ public function testDateAndServiceCountMissing() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'date is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertContains( - ['type' => 'field', 'msg' => 'date is required and must be a valid date', 'path' => 'date', 'location' => 'body'], - $responseBody['errors'] - ); - $this->assertContains( - ['type' => 'field', 'msg' => 'serviceCount should be a comma-separated string of integers', 'path' => 'serviceCount', 'location' => 'body'], - $responseBody['errors'] - ); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testOfficeIdAndServiceIdMissing() @@ -227,17 +250,21 @@ public function testOfficeIdAndServiceIdMissing() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'officeId should be a 32-bit integer.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceId should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertContains( - ['type' => 'field', 'msg' => 'officeId should be a 32-bit integer', 'path' => 'officeId', 'location' => 'body'], - $responseBody['errors'] - ); - $this->assertContains( - ['type' => 'field', 'msg' => 'serviceId should be a comma-separated string of integers', 'path' => 'serviceId', 'location' => 'body'], - $responseBody['errors'] - ); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testOfficeIdAndServiceCountMissing() @@ -249,17 +276,21 @@ public function testOfficeIdAndServiceCountMissing() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'officeId should be a 32-bit integer.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertContains( - ['type' => 'field', 'msg' => 'officeId should be a 32-bit integer', 'path' => 'officeId', 'location' => 'body'], - $responseBody['errors'] - ); - $this->assertContains( - ['type' => 'field', 'msg' => 'serviceCount should be a comma-separated string of integers', 'path' => 'serviceCount', 'location' => 'body'], - $responseBody['errors'] - ); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testServiceIdAndServiceCountMissing() @@ -271,16 +302,20 @@ public function testServiceIdAndServiceCountMissing() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'serviceId should be a comma-separated string of integers.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400 + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertContains( - ['type' => 'field', 'msg' => 'serviceId should be a comma-separated string of integers', 'path' => 'serviceId', 'location' => 'body'], - $responseBody['errors'] - ); - $this->assertContains( - ['type' => 'field', 'msg' => 'serviceCount should be a comma-separated string of integers', 'path' => 'serviceCount', 'location' => 'body'], - $responseBody['errors'] - ); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/AvailableDaysListTest.php b/zmscitizenapi/tests/Zmscitizenapi/AvailableDaysListTest.php index 2e5b316d7..9591e64d1 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/AvailableDaysListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/AvailableDaysListTest.php @@ -25,21 +25,18 @@ public function testRendering() 'serviceCount' => '1', ]; $response = $this->render([], $parameters, []); - - $this->assertStringContainsString( - '2024-08-21', - (string)$response->getBody() - ); - $this->assertStringContainsString( - '2024-08-22', - (string)$response->getBody() - ); - $this->assertStringContainsString( - '2024-08-23', - (string)$response->getBody() - ); - + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ + 'availableDays' => [ + "2024-08-21", "2024-08-22", "2024-08-23", "2024-08-26", "2024-08-27", "2024-08-28", "2024-08-29", "2024-08-30", + "2024-09-02", "2024-09-03", "2024-09-04", "2024-09-05", "2024-09-06", "2024-09-09", "2024-09-10", "2024-09-11", + "2024-09-12", "2024-09-13", "2024-09-16", "2024-09-17", "2024-09-18", "2024-09-19", "2024-09-20" + ], + 'status' => 200, + ]; $this->assertEquals(200, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); + } public function testNoAvailableDays() @@ -53,6 +50,7 @@ public function testNoAvailableDays() ] ] ); + $parameters = [ 'officeId' => '9999998', 'serviceId' => '1', @@ -60,16 +58,21 @@ public function testNoAvailableDays() 'startDate' => '2024-08-21', 'endDate' => '2024-08-23', ]; + $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorCode' => 'noAppointmentForThisDay', + 'errorMessage' => 'No available days found for the given criteria.', + 'status' => 404, + ] + ], + 'status' => 404, + ]; $this->assertEquals(404, $response->getStatusCode()); - $this->assertArrayHasKey('errorCode', $responseBody); - $this->assertEquals('noAppointmentForThisScope', $responseBody['errorCode']); - $this->assertArrayHasKey('errorMessage', $responseBody); - $this->assertEquals('No available days found for the given criteria', $responseBody['errorMessage']); - $this->assertArrayHasKey('availableDays', $responseBody); - $this->assertEmpty($responseBody['availableDays']); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testInvalidDateFormat() @@ -83,13 +86,19 @@ public function testInvalidDateFormat() ]; $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - - $this->assertEquals(500, $response->getStatusCode()); - $this->assertArrayHasKey('errorCode', $responseBody); - $this->assertArrayHasKey('errorMessage', $responseBody); - $this->assertEquals('An diesem Standort gibt es aktuell leider keine freien Termine', $responseBody['errorMessage']); - $this->assertArrayHasKey('availableDays', $responseBody); - $this->assertEmpty($responseBody['availableDays']); + $expectedResponse = [ + 'errors' => [ + [ + 'errorCode' => 'noAppointmentForThisOffice', + 'errorMessage' => 'An diesem Standort gibt es aktuell leider keine freien Termine.', + 'status' => 404, + ] + ], + 'status' => 404, + ]; + $this->assertEquals(404, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); + } public function testMissingStartDate() @@ -103,11 +112,17 @@ public function testMissingStartDate() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'startDate is required and must be a valid date.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(1, $responseBody['errors']); - $this->assertEquals('startDate is required and must be a valid date', $responseBody['errors'][0]['msg']); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody, true); } public function testMissingEndDate() @@ -121,12 +136,18 @@ public function testMissingEndDate() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - - $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(1, $responseBody['errors']); - $this->assertEquals('endDate is required and must be a valid date', $responseBody['errors'][0]['msg']); - } + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'endDate is required and must be a valid date.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testMissingOfficeId() { @@ -139,12 +160,18 @@ public function testMissingOfficeId() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'officeId should be a 32-bit integer.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(1, $responseBody['errors']); - $this->assertEquals('officeId should be a 32-bit integer', $responseBody['errors'][0]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testMissingServiceId() { @@ -157,12 +184,18 @@ public function testMissingServiceId() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'serviceId should be a 32-bit integer.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(1, $responseBody['errors']); - $this->assertEquals('serviceId should be a 32-bit integer', $responseBody['errors'][0]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testMissingServiceCount() { @@ -175,12 +208,18 @@ public function testMissingServiceCount() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(1, $responseBody['errors']); - $this->assertEquals('serviceCount should be a comma-separated string of integers', $responseBody['errors'][0]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testEmptyServiceCount() { @@ -194,12 +233,18 @@ public function testEmptyServiceCount() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(1, $responseBody['errors']); - $this->assertEquals('serviceCount should be a comma-separated string of integers', $responseBody['errors'][0]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testInvalidServiceCountFormat() { @@ -213,12 +258,18 @@ public function testInvalidServiceCountFormat() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(1, $responseBody['errors']); - $this->assertEquals('serviceCount should be a comma-separated string of integers', $responseBody['errors'][0]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testAllParametersMissing() { @@ -226,10 +277,33 @@ public function testAllParametersMissing() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'startDate is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'endDate is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'officeId should be a 32-bit integer.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceId should be a 32-bit integer.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(5, $responseBody['errors']); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); } public function testMissingStartDateAndEndDate() @@ -242,13 +316,22 @@ public function testMissingStartDateAndEndDate() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'startDate is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'endDate is required and must be a valid date.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(2, $responseBody['errors']); - $this->assertEquals('startDate is required and must be a valid date', $responseBody['errors'][0]['msg']); - $this->assertEquals('endDate is required and must be a valid date', $responseBody['errors'][1]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testMissingOfficeIdAndServiceId() { @@ -260,13 +343,22 @@ public function testMissingOfficeIdAndServiceId() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'officeId should be a 32-bit integer.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceId should be a 32-bit integer.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(2, $responseBody['errors']); - $this->assertEquals('officeId should be a 32-bit integer', $responseBody['errors'][0]['msg']); - $this->assertEquals('serviceId should be a 32-bit integer', $responseBody['errors'][1]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testMissingServiceIdAndServiceCount() { @@ -278,13 +370,22 @@ public function testMissingServiceIdAndServiceCount() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'serviceId should be a 32-bit integer.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(2, $responseBody['errors']); - $this->assertEquals('serviceId should be a 32-bit integer', $responseBody['errors'][0]['msg']); - $this->assertEquals('serviceCount should be a comma-separated string of integers', $responseBody['errors'][1]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testMissingStartDateAndOfficeId() { @@ -296,12 +397,21 @@ public function testMissingStartDateAndOfficeId() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'startDate is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'officeId should be a 32-bit integer.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(2, $responseBody['errors']); - $this->assertEquals('startDate is required and must be a valid date', $responseBody['errors'][0]['msg']); - $this->assertEquals('officeId should be a 32-bit integer', $responseBody['errors'][1]['msg']); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); } public function testMissingEndDateAndServiceCount() @@ -314,13 +424,22 @@ public function testMissingEndDateAndServiceCount() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'endDate is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(2, $responseBody['errors']); - $this->assertEquals('endDate is required and must be a valid date', $responseBody['errors'][0]['msg']); - $this->assertEquals('serviceCount should be a comma-separated string of integers', $responseBody['errors'][1]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testMissingOfficeIdAndServiceCount() { @@ -332,14 +451,22 @@ public function testMissingOfficeIdAndServiceCount() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'officeId should be a 32-bit integer.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(2, $responseBody['errors']); - $this->assertEquals('officeId should be a 32-bit integer', $responseBody['errors'][0]['msg']); - $this->assertEquals('serviceCount should be a comma-separated string of integers', $responseBody['errors'][1]['msg']); - } - + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testMissingStartDateEndDateAndOfficeId() { @@ -350,14 +477,26 @@ public function testMissingStartDateEndDateAndOfficeId() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'startDate is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'endDate is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'officeId should be a 32-bit integer.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(3, $responseBody['errors']); - $this->assertEquals('startDate is required and must be a valid date', $responseBody['errors'][0]['msg']); - $this->assertEquals('endDate is required and must be a valid date', $responseBody['errors'][1]['msg']); - $this->assertEquals('officeId should be a 32-bit integer', $responseBody['errors'][2]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testMissingStartDateEndDateAndServiceId() { @@ -368,14 +507,26 @@ public function testMissingStartDateEndDateAndServiceId() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'startDate is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'endDate is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceId should be a 32-bit integer.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(3, $responseBody['errors']); - $this->assertEquals('startDate is required and must be a valid date', $responseBody['errors'][0]['msg']); - $this->assertEquals('endDate is required and must be a valid date', $responseBody['errors'][1]['msg']); - $this->assertEquals('serviceId should be a 32-bit integer', $responseBody['errors'][2]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testMissingStartDateOfficeIdAndServiceCount() { @@ -386,14 +537,26 @@ public function testMissingStartDateOfficeIdAndServiceCount() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'startDate is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'officeId should be a 32-bit integer.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(3, $responseBody['errors']); - $this->assertEquals('startDate is required and must be a valid date', $responseBody['errors'][0]['msg']); - $this->assertEquals('officeId should be a 32-bit integer', $responseBody['errors'][1]['msg']); - $this->assertEquals('serviceCount should be a comma-separated string of integers', $responseBody['errors'][2]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testMissingEndDateOfficeIdAndServiceCount() { @@ -404,14 +567,26 @@ public function testMissingEndDateOfficeIdAndServiceCount() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'endDate is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'officeId should be a 32-bit integer.', + 'status' => 400, + ], + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(3, $responseBody['errors']); - $this->assertEquals('endDate is required and must be a valid date', $responseBody['errors'][0]['msg']); - $this->assertEquals('officeId should be a 32-bit integer', $responseBody['errors'][1]['msg']); - $this->assertEquals('serviceCount should be a comma-separated string of integers', $responseBody['errors'][2]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } public function testEmptyStartDateAndEndDate() { @@ -425,14 +600,23 @@ public function testEmptyStartDateAndEndDate() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'startDate is required and must be a valid date.', + 'status' => 400, + ], + [ + 'errorMessage' => 'endDate is required and must be a valid date.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(2, $responseBody['errors']); - $this->assertEquals('startDate is required and must be a valid date', $responseBody['errors'][0]['msg']); - $this->assertEquals('endDate is required and must be a valid date', $responseBody['errors'][1]['msg']); - } - + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } + public function testNonNumericServiceCount() { $parameters = [ @@ -445,11 +629,17 @@ public function testNonNumericServiceCount() $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - + $expectedResponse = [ + 'errors' => [ + [ + 'errorMessage' => 'serviceCount should be a comma-separated string of integers.', + 'status' => 400, + ] + ], + 'status' => 400, + ]; $this->assertEquals(400, $response->getStatusCode()); - $this->assertArrayHasKey('errors', $responseBody); - $this->assertCount(1, $responseBody['errors']); - $this->assertEquals('serviceCount should be a comma-separated string of integers', $responseBody['errors'][0]['msg']); - } + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); + } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/CaptchaGetTest.php b/zmscitizenapi/tests/Zmscitizenapi/CaptchaGetTest.php index f592448a3..824f93cec 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/CaptchaGetTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/CaptchaGetTest.php @@ -36,15 +36,15 @@ public function testCaptchaDetails() $parameters = []; $response = $this->render([], $parameters, []); $responseBody = json_decode((string)$response->getBody(), true); - - $expectedDetails = [ + $expectedResponse = [ 'siteKey' => 'FAKE_SITE_KEY', 'captchaEndpoint' => 'https://api.friendlycaptcha.com/api/v1/siteverify', 'puzzle' => 'https://api.friendlycaptcha.com/api/v1/puzzle', - 'captchaEnabled' => true + 'captchaEnabled' => true, + 'status' => 200 ]; $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals($expectedDetails, $responseBody); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/OfficesByServiceListTest.php b/zmscitizenapi/tests/Zmscitizenapi/OfficesByServiceListTest.php index d911186b1..c61c1c5a9 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/OfficesByServiceListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/OfficesByServiceListTest.php @@ -30,6 +30,7 @@ public function testRendering() ] ] ]; + $this->assertEquals(200, $response->getStatusCode()); $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); } @@ -60,6 +61,7 @@ public function testRenderingRequestRelation() ] ] ]; + $this->assertEquals(200, $response->getStatusCode()); $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); } @@ -90,6 +92,7 @@ public function testRenderingMulti() ] ] ]; + $this->assertEquals(200, $response->getStatusCode()); $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); } @@ -109,26 +112,39 @@ public function testServiceNotFound() $response = $this->render([], [ 'serviceId' => '99999999' ], []); - + $expectedResponse = [ - 'status' => 404, - 'offices' => [], - 'error' => 'Office(s) not found for the provided serviceId(s)' + 'errors' => [ + [ + 'errorCode' => 'officesNotFound', + 'errorMessage' => 'Office(s) not found for the provided serviceId(s).', + 'status' => 404, + ] + ], + 'status' => 404 ]; - $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); $this->assertEquals(404, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + } public function testNoServiceIdProvided() { $response = $this->render([], [], []); + $expectedResponse = [ - 'status' => 400, - 'offices' => [], - 'error' => 'Invalid serviceId(s)' + 'errors' => [ + [ + 'offices' => [], + 'errorMessage' => 'Invalid serviceId(s).', + 'status' => 400 + ] + ], + 'status' => 400 ]; - $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + } public function testPartialResultsWithWarning() @@ -155,8 +171,9 @@ public function testPartialResultsWithWarning() ], 'warning' => 'The following serviceId(s) were not found: 99999999' ]; - $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); $this->assertEquals(200, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + } public function testPartialResultsWithWarningRequestRelation() @@ -187,8 +204,9 @@ public function testPartialResultsWithWarningRequestRelation() ], 'warning' => 'The following serviceId(s) were not found: 99999999' ]; - $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); $this->assertEquals(200, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + } public function testDuplicateServiceIds() @@ -214,6 +232,7 @@ public function testDuplicateServiceIds() ] ] ]; + $this->assertEquals(200, $response->getStatusCode()); $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); } @@ -244,6 +263,8 @@ public function testDuplicateServiceIdsCombinable() ] ] ]; + $this->assertEquals(200, $response->getStatusCode()); $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/OfficesListTest.php b/zmscitizenapi/tests/Zmscitizenapi/OfficesListTest.php index deba791d7..d04746041 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/OfficesListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/OfficesListTest.php @@ -7,7 +7,8 @@ class OfficesListTest extends Base protected $classname = "OfficesList"; - public function testRendering() { + public function testRendering() + { $this->setApiCalls([ [ 'function' => 'readGetResult', @@ -15,11 +16,13 @@ public function testRendering() { 'parameters' => [ 'resolveReferences' => 2, ], - 'response' => $this->readFixture("GET_SourceGet_dldb.json"), + 'response' => $this->readFixture("GET_SourceGet_dldb.json") ] ]); - $responseData = $this->renderJson(); - $this->assertEqualsCanonicalizing([ + + $response = $this->render(); + $responseBody = json_decode((string)$response->getBody(), true); + $expectedResponse = [ "offices" => [ [ "id" => "9999998", @@ -61,7 +64,11 @@ public function testRendering() { "displayInfo" => null ] ] - ] - ], $responseData); + ], + "status" => 200 + ]; + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/OfficesServicesRelationsTest.php b/zmscitizenapi/tests/Zmscitizenapi/OfficesServicesRelationsTest.php index b6790002b..965dc9e33 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/OfficesServicesRelationsTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/OfficesServicesRelationsTest.php @@ -16,10 +16,12 @@ public function testRendering() 'parameters' => [ 'resolveReferences' => 2, ], - 'response' => $this->readFixture("GET_SourceGet_dldb.json"), + 'response' => $this->readFixture("GET_SourceGet_dldb.json") ] ]); - $responseData = $this->renderJson(); + + $response = $this->render(); + $responseBody = json_decode((string)$response->getBody(), true); $expectedResponse = [ "offices" => [ [ @@ -95,8 +97,11 @@ public function testRendering() "serviceId" => "2", "slots" => 1 ] - ] + ], + "status" => 200 ]; - $this->assertEqualsCanonicalizing($expectedResponse, $responseData); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/ScopeByIdGetTest.php b/zmscitizenapi/tests/Zmscitizenapi/ScopeByIdGetTest.php index e9ede5fab..4a3b95ca9 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/ScopeByIdGetTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/ScopeByIdGetTest.php @@ -43,6 +43,7 @@ public function testRendering() ] ] ]; + $this->assertEquals(200, $response->getStatusCode()); $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); } @@ -95,6 +96,7 @@ public function testRenderingMulti() ], ] ]; + $this->assertEquals(200, $response->getStatusCode()); $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); } @@ -114,26 +116,39 @@ public function testScopeNotFound() $response = $this->render([], [ 'scopeId' => '99' ], []); - + $expectedResponse = [ - 'status' => 404, - 'scopes' => [], - 'error' => 'Scope(s) not found' + 'errors' => [ + [ + 'errorCode' => "scopesNotFound", + 'errorMessage' => 'Scope(s) not found.', + 'status' => 404 + ] + ], + 'status' => 404 ]; - $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + $this->assertEquals(404, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + } public function testNoScopeIdProvided() { $response = $this->render([], [], []); $expectedResponse = [ - 'status' => 400, - 'scopes' => [], - 'error' => 'Invalid scopeId(s)' + 'errors' => [ + [ + 'services' => [], + 'errorMessage' => 'Invalid scopeId(s).', + 'status' => 400 + ] + ], + 'status' => 400 ]; - $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + } public function testPartialResultsWithWarning() @@ -170,9 +185,10 @@ public function testPartialResultsWithWarning() ] ], 'warning' => 'The following scopeId(s) were not found: 99' - ]; + ]; + $this->assertEquals(200, $response->getStatusCode()); $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); - $this->assertEquals(200, $response->getStatusCode()); + } public function testDuplicateScopeIds() @@ -211,9 +227,9 @@ public function testDuplicateScopeIds() ] ] ]; - - $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); $this->assertEquals(200, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/ScopesListTest.php b/zmscitizenapi/tests/Zmscitizenapi/ScopesListTest.php index 9a308d8a2..d1b019f42 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/ScopesListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/ScopesListTest.php @@ -7,7 +7,8 @@ class ScopesListTest extends Base protected $classname = "ScopesList"; - public function testRendering() { + public function testRendering() + { $this->setApiCalls([ [ 'function' => 'readGetResult', @@ -15,10 +16,12 @@ public function testRendering() { 'parameters' => [ 'resolveReferences' => 2, ], - 'response' => $this->readFixture("GET_SourceGet_dldb.json"), // Use the same fixture as before + 'response' => $this->readFixture("GET_SourceGet_dldb.json") ] ]); - $responseData = $this->renderJson(); + + $response = $this->render(); + $responseBody = json_decode((string)$response->getBody(), true); $expectedResponse = [ "scopes" => [ [ @@ -53,9 +56,11 @@ public function testRendering() { "captchaActivatedRequired" => "0", "displayInfo" => null ] - ] + ], + "status" => 200, ]; - $this->assertEqualsCanonicalizing($expectedResponse, $responseData); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/ServicesByOfficeListTest.php b/zmscitizenapi/tests/Zmscitizenapi/ServicesByOfficeListTest.php index e577a28cf..54305a9a8 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/ServicesByOfficeListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/ServicesByOfficeListTest.php @@ -31,6 +31,7 @@ public function testRendering() ] ] ]; + $this->assertEquals(200, $response->getStatusCode()); $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); } @@ -63,6 +64,7 @@ public function testRenderingMulti() ] ] ]; + $this->assertEquals(200, $response->getStatusCode()); $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); } @@ -83,26 +85,40 @@ public function testServiceNotFound() $response = $this->render([], [ 'officeId' => '99999999' ], []); - + $expectedResponse = [ - 'status' => 404, - 'services' => [], - 'error' => 'Service(s) not found for the provided officeId(s)' + 'errors' => [ + [ + 'errorCode' => 'servicesNotFound', + 'errorMessage' => 'Service(s) not found for the provided officeId(s).', + 'status' => 404 + ] + ], + 'status' => 404 ]; - $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + $this->assertEquals(404, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + } public function testNoOfficeIdProvided() { $response = $this->render([], [], []); $expectedResponse = [ - 'status' => 400, - 'services' => [], - 'error' => 'Invalid officeId(s)' + 'errors' => [ + [ + 'services' => [], + 'errorMessage' => 'Invalid officeId(s)', + 'status' => 400 + ] + ], + 'status' => 400 ]; - $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + } public function testPartialResultsWithWarning() @@ -129,9 +145,11 @@ public function testPartialResultsWithWarning() ] ], 'warning' => 'The following officeId(s) were not found: 99999999' - ]; - $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + ]; + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); + } public function testDuplicateOfficeIds() @@ -158,6 +176,8 @@ public function testDuplicateOfficeIds() ] ] ]; + + $this->assertEquals(200, $response->getStatusCode()); $this->assertEqualsCanonicalizing($expectedResponse, json_decode((string)$response->getBody(), true)); } } diff --git a/zmscitizenapi/tests/Zmscitizenapi/ServicesListTest.php b/zmscitizenapi/tests/Zmscitizenapi/ServicesListTest.php index 97ce73cbc..dc4911ea4 100644 --- a/zmscitizenapi/tests/Zmscitizenapi/ServicesListTest.php +++ b/zmscitizenapi/tests/Zmscitizenapi/ServicesListTest.php @@ -15,10 +15,12 @@ public function testRendering() { 'parameters' => [ 'resolveReferences' => 2, ], - 'response' => $this->readFixture("GET_SourceGet_dldb.json"), + 'response' => $this->readFixture("GET_SourceGet_dldb.json") ] ]); - $responseData = $this->renderJson(); + + $response = $this->render(); + $responseBody = json_decode((string)$response->getBody(), true); $expectedResponse = [ "services" => [ [ @@ -31,8 +33,11 @@ public function testRendering() { "name" => "Unittest Source Dienstleistung 2", "maxQuantity" => 1 ] - ] + ], + "status" => 200, ]; - $this->assertEqualsCanonicalizing($expectedResponse, $responseData); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEqualsCanonicalizing($expectedResponse, $responseBody); } }