Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.08% covered (success)
96.08%
49 / 51
85.71% covered (warning)
85.71%
6 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
AvailableAppointmentsListService
96.08% covered (success)
96.08%
49 / 51
85.71% covered (warning)
85.71%
6 / 7
17
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getAvailableAppointmentsList
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 extractClientData
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
6
 isCaptchaRequired
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 validateClientData
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 getAvailableAppointments
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 getAvailableAppointmentsListByOffice
75.00% covered (warning)
75.00%
6 / 8
0.00% covered (danger)
0.00%
0 / 1
3.14
1<?php
2
3declare(strict_types=1);
4
5namespace BO\Zmscitizenapi\Services\Availability;
6
7use BO\Zmscitizenapi\Models\AvailableAppointments;
8use BO\Zmscitizenapi\Models\AvailableAppointmentsByOffice;
9use BO\Zmscitizenapi\Services\Captcha\TokenValidationService;
10use BO\Zmscitizenapi\Services\Core\ValidationService;
11use BO\Zmscitizenapi\Services\Core\ZmsApiFacadeService;
12
13class AvailableAppointmentsListService
14{
15    use ServiceLocationValidationTrait;
16
17    private TokenValidationService $tokenValidator;
18    private ZmsApiFacadeService $zmsApiFacadeService;
19
20    public function __construct()
21    {
22        $this->tokenValidator = new TokenValidationService();
23        $this->zmsApiFacadeService = new ZmsApiFacadeService();
24    }
25
26    public function getAvailableAppointmentsList(array $queryParams): AvailableAppointments|array
27    {
28        $clientData = $this->extractClientData($queryParams);
29        $errors = $this->validateClientData($clientData);
30        if (!empty($errors['errors'])) {
31            return $errors;
32        }
33
34        $errors = $this->validateServiceLocations($clientData->officeIds, $clientData->serviceIds);
35        if ($errors !== null) {
36            return $errors;
37        }
38
39        return $this->getAvailableAppointments($clientData);
40    }
41
42    private function extractClientData(array $queryParams): object
43    {
44        return (object) [
45            'date' => isset($queryParams['date']) ? (string) $queryParams['date'] : null,
46            'officeIds' => isset($queryParams['officeId'])
47                ? array_map('trim', explode(',', (string) $queryParams['officeId']))
48                : [],
49            'serviceIds' => isset($queryParams['serviceId'])
50                ? array_map('trim', explode(',', (string) $queryParams['serviceId']))
51                : [],
52            'serviceCounts' => isset($queryParams['serviceCount'])
53                ? array_map('trim', explode(',', (string) $queryParams['serviceCount']))
54                : [],
55            'captchaToken' => isset($queryParams['captchaToken']) ? (string) $queryParams['captchaToken'] : null
56        ];
57    }
58
59    private function isCaptchaRequired(array $officeIds): bool
60    {
61        $officeId = (int)($officeIds[0] ?? 0);
62
63        try {
64            $scope = $this->zmsApiFacadeService->getScopeByOfficeId($officeId);
65            return $scope->captchaActivatedRequired ?? false;
66        } catch (\Throwable $e) {
67            return false;
68        }
69    }
70
71    private function validateClientData(object $data): array
72    {
73        $captchaRequired = $this->isCaptchaRequired($data->officeIds);
74        $captchaToken = $data->captchaToken;
75
76        return ValidationService::validateGetAvailableAppointments(
77            $data->date,
78            $data->officeIds,
79            $data->serviceIds,
80            $data->serviceCounts,
81            $captchaRequired,
82            $captchaToken,
83            $this->tokenValidator
84        );
85    }
86
87    private function getAvailableAppointments(object $data, ?bool $groupByOffice = false): array|AvailableAppointments|AvailableAppointmentsByOffice
88    {
89        return ZmsApiFacadeService::getAvailableAppointments(
90            $data->date,
91            $data->officeIds,
92            $data->serviceIds,
93            $data->serviceCounts,
94            $groupByOffice
95        );
96    }
97
98    public function getAvailableAppointmentsListByOffice($queryParams): AvailableAppointments|AvailableAppointmentsByOffice|array
99    {
100        $clientData = $this->extractClientData($queryParams);
101        $errors = $this->validateClientData($clientData);
102        if (!empty($errors['errors'])) {
103            return $errors;
104        }
105
106        $errors = $this->validateServiceLocations($clientData->officeIds, $clientData->serviceIds);
107        if ($errors !== null) {
108            return $errors;
109        }
110
111        return $this->getAvailableAppointments($clientData, true);
112    }
113}