Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.32% covered (success)
90.32%
28 / 31
71.43% covered (warning)
71.43%
5 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
AppointmentConfirmService
90.32% covered (success)
90.32%
28 / 31
71.43% covered (warning)
71.43%
5 / 7
20.36
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 processConfirm
86.67% covered (warning)
86.67%
13 / 15
0.00% covered (danger)
0.00%
0 / 1
7.12
 extractClientData
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
6
 validateClientData
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getReservedProcess
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 confirmProcess
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
3.07
 sendConfirmationEmail
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
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\Captcha\CaptchaService;
10use BO\Zmscitizenapi\Services\Core\ValidationService;
11use BO\Zmscitizenapi\Services\Core\ZmsApiFacadeService;
12use BO\Zmscitizenapi\Services\Core\MapperService;
13
14class AppointmentConfirmService
15{
16    private CaptchaService $captchaService;
17
18    public function __construct()
19    {
20        $this->captchaService = new CaptchaService();
21    }
22
23    public function processConfirm(array $body, ?AuthenticatedUser $authenticatedUser): ThinnedProcess|array
24    {
25        $clientData = $this->extractClientData($body);
26        $errors = $this->validateClientData($clientData);
27        if (!empty($errors['errors'])) {
28            return $errors;
29        }
30
31        $reservedProcess = $this->getReservedProcess($clientData->processId, $clientData->authKey, $authenticatedUser);
32        if (is_array($reservedProcess) && !empty($reservedProcess['errors'])) {
33            return $reservedProcess;
34        }
35
36        // Todo: check if the email template confirmed exists for the scope before submitting and sending
37        $result = $this->confirmProcess($reservedProcess);
38        if (is_array($result) && !empty($result['errors'])) {
39            return $result;
40        }
41
42        $token = $this->captchaService->generateToken();
43        $result->setCaptchaToken($token);
44
45        if ($result->status === 'confirmed') {
46            $this->sendConfirmationEmail($result);
47        }
48
49        return $result;
50    }
51
52
53    private function extractClientData(array $body): object
54    {
55        return (object) [
56            'processId' => isset($body['processId']) && is_numeric($body['processId'])
57                ? (int) $body['processId']
58                : null,
59            'authKey' => isset($body['authKey']) && is_string($body['authKey']) && trim($body['authKey']) !== ''
60                ? htmlspecialchars(trim($body['authKey']), ENT_QUOTES, 'UTF-8')
61                : null
62        ];
63    }
64
65    private function validateClientData(object $data): array
66    {
67        return ValidationService::validateGetProcessById($data->processId, $data->authKey);
68    }
69
70    private function getReservedProcess(int $processId, ?string $authKey, ?AuthenticatedUser $user): ThinnedProcess|array
71    {
72        return ZmsApiFacadeService::getThinnedProcessById($processId, $authKey, $user);
73    }
74
75    private function confirmProcess(ThinnedProcess $process): ThinnedProcess|array
76    {
77        $processEntity = MapperService::thinnedProcessToProcess($process);
78        $result = ZmsApiFacadeService::confirmAppointment($processEntity);
79        if (is_array($result) && !empty($result['errors'])) {
80            return $result;
81        }
82
83        return MapperService::processToThinnedProcess($result);
84    }
85
86    private function sendConfirmationEmail(ThinnedProcess $process): void
87    {
88        $processEntity = MapperService::thinnedProcessToProcess($process);
89        ZmsApiFacadeService::sendConfirmationEmail($processEntity);
90    }
91}