Lines 98.33% 59 / 60
Functions and Methods 75.00% 3 / 4
Classes and Traits 0.00% 0 / 1
Name Lines Functions and Methods CRAP Classes and Traits
AvailableCalendarService 98.33% 59 / 60 75.00% 3 / 4 15 0.00% 0 / 1
 __construct 100.00% 2 / 2 100.00% 1 / 1 1
 getAvailableCalendar 95.65% 22 / 23 0.00% 0 / 1 4
 extractClientData 100.00% 22 / 22 100.00% 1 / 1 9
 validateClientData 100.00% 13 / 13 100.00% 1 / 1 1
1<?php
2
3declare(strict_types=1);
4
5namespace BO\Zmscitizenapi\Services\Availability;
6
7use BO\Zmscitizenapi\Models\AvailableCalendar;
8use BO\Zmscitizenapi\Services\Captcha\CaptchaRequirementTrait;
9use BO\Zmscitizenapi\Services\Captcha\TokenValidationService;
10use BO\Zmscitizenapi\Services\Core\AppointmentProcessLimitsValidationService;
11use BO\Zmscitizenapi\Services\Core\ValidationService;
12use BO\Zmscitizenapi\Services\Core\ZmsApiFacadeService;
13
14class AvailableCalendarService
15{
16    use CaptchaRequirementTrait;
17    use ServiceLocationValidationTrait;
18
19    private TokenValidationService $tokenValidator;
20    private ZmsApiFacadeService $zmsApiFacadeService;
21
22    public function __construct()
23    {
24        $this->tokenValidator = new TokenValidationService();
25        $this->zmsApiFacadeService = new ZmsApiFacadeService();
26    }
27
28    public function getAvailableCalendar(
29        array $queryParams,
30        bool $showUnpublished = false
31    ): AvailableCalendar|array {
32        $clientData = $this->extractClientData($queryParams);
33
34        $errors = $this->validateClientData($clientData);
35        if (!empty($errors['errors'])) {
36            return $errors;
37        }
38
39        $errors = $this->validateServiceLocations($clientData->officeIds, $clientData->serviceIds, $showUnpublished);
40        if ($errors !== null) {
41            return $errors;
42        }
43
44        $eligibleOffices = AppointmentProcessLimitsValidationService::filterOfficeIdsWithinRequestLimits(
45            $clientData->officeIds,
46            $clientData->serviceIds,
47            $clientData->serviceCounts
48        );
49        if (!empty($eligibleOffices['errors'])) {
50            return $eligibleOffices;
51        }
52
53        return ZmsApiFacadeService::getCalendarAvailability(
54            $eligibleOffices['officeIds'],
55            $clientData->serviceIds,
56            $clientData->serviceCounts,
57            $clientData->startDate,
58            $clientData->endDate,
59            $clientData->slotsStartDate,
60            $clientData->slotsEndDate
61        );
62    }
63
64    private function extractClientData(array $queryParams): object
65    {
66        $queryParams['officeIds'] = isset($queryParams['officeIds']) ? (string) $queryParams['officeIds'] : '';
67        $queryParams['serviceIds'] = isset($queryParams['serviceIds']) ? (string) $queryParams['serviceIds'] : '';
68        $serviceCountsRaw = $queryParams['serviceCounts'] ?? '';
69        $serviceCounts = !empty($serviceCountsRaw)
70            ? array_map('trim', explode(',', (string) $serviceCountsRaw))
71            : [];
72
73        $slotsStartDate = isset($queryParams['slotsStartDate']) && $queryParams['slotsStartDate'] !== ''
74            ? (string) $queryParams['slotsStartDate']
75            : null;
76        $slotsEndDate = isset($queryParams['slotsEndDate']) && $queryParams['slotsEndDate'] !== ''
77            ? (string) $queryParams['slotsEndDate']
78            : null;
79
80        return (object) [
81            'officeIds' => array_map('trim', explode(',', $queryParams['officeIds'])),
82            'serviceIds' => array_map('trim', explode(',', $queryParams['serviceIds'])),
83            'serviceCounts' => $serviceCounts,
84            'startDate' => $queryParams['startDate'] ?? null,
85            'endDate' => $queryParams['endDate'] ?? null,
86            'slotsStartDate' => $slotsStartDate,
87            'slotsEndDate' => $slotsEndDate,
88            'captchaToken' => isset($queryParams['captchaToken']) ? (string) $queryParams['captchaToken'] : null,
89        ];
90    }
91
92    private function validateClientData(object $data): array
93    {
94        $captchaRequired = $this->isCaptchaRequiredForOfficeIds($data->officeIds);
95
96        return ValidationService::validateGetBookableFreeDays(
97            $data->officeIds,
98            $data->serviceIds,
99            $data->startDate,
100            $data->endDate,
101            $data->serviceCounts,
102            $captchaRequired,
103            $data->captchaToken,
104            $this->tokenValidator,
105            $data->slotsStartDate,
106            $data->slotsEndDate
107        );
108    }
109}