Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
93.88% covered (success)
93.88%
46 / 49
66.67% covered (warning)
66.67%
4 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
AppointmentUpdateService
93.88% covered (success)
93.88%
46 / 49
66.67% covered (warning)
66.67%
4 / 6
32.24
0.00% covered (danger)
0.00%
0 / 1
 processUpdate
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 validateClientData
94.12% covered (success)
94.12%
16 / 17
0.00% covered (danger)
0.00%
0 / 1
7.01
 extractClientData
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
16
 getReservedProcess
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 updateProcessWithClientData
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 saveProcessUpdate
71.43% covered (warning)
71.43%
5 / 7
0.00% covered (danger)
0.00%
0 / 1
5.58
1<?php
2
3declare(strict_types=1);
4
5namespace BO\Zmscitizenapi\Services\Appointment;
6
7use BO\Zmscitizenapi\Models\AuthenticatedUser;
8use BO\Zmscitizenapi\Models\ThinnedProcess;
9use BO\Zmscitizenapi\Services\Core\ValidationService;
10use BO\Zmscitizenapi\Services\Core\ZmsApiFacadeService;
11use BO\Zmscitizenapi\Services\Core\MapperService;
12
13class AppointmentUpdateService
14{
15    public function processUpdate(array $body, ?AuthenticatedUser $authenticatedUser): ThinnedProcess|array
16    {
17        $clientData = $this->extractClientData($body);
18
19        $errors = $this->validateClientData($clientData, $authenticatedUser);
20        if (!empty($errors['errors'])) {
21            return $errors;
22        }
23
24        $reservedProcess = $this->getReservedProcess($clientData->processId, $clientData->authKey, $authenticatedUser);
25
26        $updatedProcess = $this->updateProcessWithClientData($reservedProcess, $clientData);
27        return $this->saveProcessUpdate($updatedProcess, $authenticatedUser);
28    }
29
30    private function validateClientData(object $data, ?AuthenticatedUser $authenticatedUser): array
31    {
32        $authErrors = ValidationService::validateGetProcessById($data->processId, $data->authKey);
33        if (is_array($authErrors) && !empty($authErrors['errors'])) {
34            return $authErrors;
35        }
36
37        $reservedProcess = $this->getReservedProcess($data->processId, $data->authKey, $authenticatedUser);
38        if (is_array($reservedProcess) && !empty($reservedProcess['errors'])) {
39            return $reservedProcess;
40        }
41
42        $fieldErrors = ValidationService::validateAppointmentUpdateFields(
43            $data->familyName,
44            $data->email,
45            $data->telephone,
46            $data->customTextfield,
47            $data->customTextfield2,
48            $reservedProcess->scope ?? null
49        );
50        if (is_array($fieldErrors) && !empty($fieldErrors['errors'])) {
51            return $fieldErrors;
52        }
53
54        return ['errors' => []];
55    }
56
57    private function extractClientData(array $body): object
58    {
59        return (object) [
60            'processId' => isset($body['processId']) && is_numeric($body['processId'])
61                ? (int) $body['processId']
62                : null,
63            'authKey' => isset($body['authKey']) && is_string($body['authKey']) && trim($body['authKey']) !== ''
64                ? htmlspecialchars(trim($body['authKey']), ENT_QUOTES, 'UTF-8')
65                : null,
66            'familyName' => isset($body['familyName']) && is_string($body['familyName']) ? (string) $body['familyName'] : null,
67            'email' => isset($body['email']) && is_string($body['email']) ? (string) $body['email'] : null,
68            'telephone' => isset($body['telephone']) && is_string($body['telephone']) ? (string) $body['telephone'] : null,
69            'customTextfield' => isset($body['customTextfield']) && is_string($body['customTextfield']) ? (string) $body['customTextfield'] : null,
70            'customTextfield2' => isset($body['customTextfield2']) && is_string($body['customTextfield2']) ? (string) $body['customTextfield2'] : null,
71        ];
72    }
73
74    private function getReservedProcess(int $processId, ?string $authKey, ?AuthenticatedUser $user): ThinnedProcess|array
75    {
76        return ZmsApiFacadeService::getThinnedProcessById($processId, $authKey, $user);
77    }
78
79    private function updateProcessWithClientData(ThinnedProcess $process, object $data): ThinnedProcess
80    {
81        $process->familyName = $data->familyName ?? $process->familyName ?? null;
82        $process->email = $data->email ?? $process->email ?? null;
83        $process->telephone = $data->telephone ?? $process->telephone ?? null;
84        $process->customTextfield = $data->customTextfield ?? $process->customTextfield ?? null;
85        $process->customTextfield2 = $data->customTextfield2 ?? $process->customTextfield2 ?? null;
86        return $process;
87    }
88
89    private function saveProcessUpdate(ThinnedProcess $process, ?AuthenticatedUser $authenticatedUser): ThinnedProcess|array
90    {
91        $processEntity = MapperService::thinnedProcessToProcess($process);
92        if (!is_null($authenticatedUser) && is_null($processEntity->getExternalUserId())) {
93            $processEntity->setExternalUserId($authenticatedUser->getExternalUserId());
94        }
95        $result = ZmsApiFacadeService::updateClientData($processEntity);
96        if (is_array($result) && !empty($result['errors'])) {
97            return $result;
98        }
99
100        return MapperService::processToThinnedProcess($result);
101    }
102}