Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.57% covered (success)
96.57%
169 / 175
70.59% covered (warning)
70.59%
12 / 17
CRAP
0.00% covered (danger)
0.00%
0 / 1
ZmsApiClientService
96.57% covered (success)
96.57%
169 / 175
70.59% covered (warning)
70.59%
12 / 17
60
0.00% covered (danger)
0.00%
0 / 1
 fetchSourceData
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
5
 getOffices
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 getScopes
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 getServices
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 getRequestRelationList
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 getFreeDays
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
6
 getFreeTimeslots
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
3
 reserveTimeslot
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
1 / 1
6
 submitClientData
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 preconfirmProcess
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 confirmProcess
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 cancelAppointment
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 sendConfirmationEmail
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 sendPreconfirmationEmail
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 sendCancellationEmail
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 getProcessById
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
3
 getScopesByProviderId
77.78% covered (warning)
77.78%
7 / 9
0.00% covered (danger)
0.00%
0 / 1
4.18
1<?php
2
3declare(strict_types=1);
4
5namespace BO\Zmscitizenapi\Services\Core;
6
7use BO\Zmscitizenapi\Helper\ClientIpHelper;
8use BO\Zmscitizenapi\Services\Core\LoggerService;
9use BO\Zmscitizenapi\Services\Core\ExceptionService;
10use BO\Zmsentities\Calendar;
11use BO\Zmsentities\Process;
12use BO\Zmsentities\Source;
13use BO\Zmsentities\Collection\DayList;
14use BO\Zmsentities\Collection\ProcessList;
15use BO\Zmsentities\Collection\ProviderList;
16use BO\Zmsentities\Collection\RequestList;
17use BO\Zmsentities\Collection\RequestRelationList;
18use BO\Zmsentities\Collection\ScopeList;
19
20class ZmsApiClientService
21{
22    private static function fetchSourceData(): Source
23    {
24        $cacheKey = 'source_' . \App::$source_name;
25        if (\App::$cache && ($data = \App::$cache->get($cacheKey))) {
26            return $data;
27        }
28
29        $result = \App::$http->readGetResult('/source/' . \App::$source_name . '/', [
30            'resolveReferences' => 2,
31        ]);
32        $entity = $result?->getEntity();
33        if (!$entity instanceof Source) {
34            return new Source();
35        }
36
37        if (\App::$cache) {
38            \App::$cache->set($cacheKey, $entity, \App::$SOURCE_CACHE_TTL);
39            LoggerService::logInfo('Cache set', [
40                'key' => $cacheKey,
41                'ttl' => \App::$SOURCE_CACHE_TTL,
42                'entity_type' => get_class($entity)
43            ]);
44        }
45
46        return $entity;
47    }
48
49    public static function getOffices(): ProviderList
50    {
51        try {
52            $sources = self::fetchSourceData();
53            $list = $sources?->getProviderList();
54            if (!$list instanceof ProviderList) {
55                return new ProviderList();
56            }
57            return $list;
58        } catch (\Exception $e) {
59            ExceptionService::handleException($e);
60        }
61    }
62
63    public static function getScopes(): ScopeList
64    {
65        try {
66            $sources = self::fetchSourceData();
67            $list = $sources?->getScopeList();
68            if (!$list instanceof ScopeList) {
69                return new ScopeList();
70            }
71            return $list;
72        } catch (\Exception $e) {
73            ExceptionService::handleException($e);
74        }
75    }
76
77    public static function getServices(): RequestList
78    {
79        try {
80            $sources = self::fetchSourceData();
81            $list = $sources?->getRequestList();
82            if (!$list instanceof RequestList) {
83                return new RequestList();
84            }
85            return $list;
86        } catch (\Exception $e) {
87            ExceptionService::handleException($e);
88        }
89    }
90
91    public static function getRequestRelationList(): RequestRelationList
92    {
93        try {
94            $sources = self::fetchSourceData();
95            $list = $sources?->getRequestRelationList();
96            if (!$list instanceof RequestRelationList) {
97                return new RequestRelationList();
98            }
99            return $list;
100        } catch (\Exception $e) {
101            ExceptionService::handleException($e);
102        }
103    }
104
105    public static function getFreeDays(ProviderList $providers, RequestList $requests, array $firstDay, array $lastDay): Calendar
106    {
107        try {
108            $calendar = new Calendar();
109            $calendar->firstDay = $firstDay;
110            $calendar->lastDay = $lastDay;
111            $calendar->providers = $providers;
112            $calendar->requests = $requests;
113            $result = \App::$http->readPostResult('/calendar/', $calendar);
114            $entity = $result?->getEntity();
115
116            if (!$entity instanceof Calendar) {
117                return new Calendar();
118            }
119            $bookableDays = new DayList();
120            foreach ($entity->days as $day) {
121                if (isset($day['status']) && $day['status'] === 'bookable') {
122                    $bookableDays->addEntity($day);
123                }
124            }
125            $entity->days = $bookableDays;
126
127            return $entity;
128        } catch (\Exception $e) {
129            ExceptionService::handleException($e);
130        }
131    }
132
133    public static function getFreeTimeslots(ProviderList $providers, RequestList $requests, array $firstDay, array $lastDay): ProcessList
134    {
135        try {
136            $calendar = new Calendar();
137            $calendar->firstDay = $firstDay;
138            $calendar->lastDay = $lastDay;
139            $calendar->providers = $providers;
140            $calendar->requests = $requests;
141            $result = \App::$http->readPostResult('/process/status/free/', $calendar);
142            $collection = $result?->getCollection();
143            if (!$collection instanceof ProcessList) {
144                return new ProcessList();
145            }
146
147            return $collection;
148        } catch (\Exception $e) {
149            ExceptionService::handleException($e);
150        }
151    }
152
153    public static function reserveTimeslot(Process $appointmentProcess, array $serviceIds, array $serviceCounts): Process
154    {
155        try {
156            $requests = [];
157            foreach ($serviceIds as $index => $serviceId) {
158                $count = intval($serviceCounts[$index]);
159                for ($i = 0; $i < $count; $i++) {
160                    $requests[] = [
161                        'id' => $serviceId,
162                        'source' => \App::$source_name
163                    ];
164                }
165            }
166
167            $processEntity = new Process();
168            $processEntity->appointments = $appointmentProcess->appointments ?? [];
169            $processEntity->authKey = $appointmentProcess->authKey ?? null;
170            $processEntity->clients = $appointmentProcess->clients ?? [];
171            $processEntity->scope = $appointmentProcess->scope ?? null;
172            $processEntity->requests = $requests;
173            $processEntity->lastChange = $appointmentProcess->lastChange ?? time();
174            $processEntity->createIP = ClientIpHelper::getClientIp();
175            $processEntity->createTimestamp = time();
176            if (isset($appointmentProcess->queue)) {
177                $processEntity->queue = $appointmentProcess->queue;
178            }
179
180            $result = \App::$http->readPostResult('/process/status/reserved/', $processEntity);
181            $entity = $result?->getEntity();
182            if (!$entity instanceof Process) {
183                return new Process();
184            }
185            return $entity;
186        } catch (\Exception $e) {
187            ExceptionService::handleException($e);
188        }
189    }
190
191    public static function submitClientData(Process $process): Process
192    {
193        try {
194            $url = "/process/{$process->id}/{$process->authKey}/";
195            $result = \App::$http->readPostResult($url, $process);
196            $entity = $result?->getEntity();
197            if (!$entity instanceof Process) {
198                return new Process();
199            }
200            return $entity;
201        } catch (\Exception $e) {
202            ExceptionService::handleException($e);
203        }
204    }
205
206    public static function preconfirmProcess(Process $process): Process
207    {
208        try {
209            $url = '/process/status/preconfirmed/';
210            $result = \App::$http->readPostResult($url, $process);
211            $entity = $result?->getEntity();
212            if (!$entity instanceof Process) {
213                return new Process();
214            }
215            return $entity;
216        } catch (\Exception $e) {
217            ExceptionService::handleException($e);
218        }
219    }
220
221    public static function confirmProcess(Process $process): Process
222    {
223        try {
224            $url = '/process/status/confirmed/';
225            $result = \App::$http->readPostResult($url, $process);
226            $entity = $result?->getEntity();
227            if (!$entity instanceof Process) {
228                return new Process();
229            }
230            return $entity;
231        } catch (\Exception $e) {
232            ExceptionService::handleException($e);
233        }
234    }
235
236    public static function cancelAppointment(Process $process): Process
237    {
238        try {
239            $url = "/process/{$process->id}/{$process->authKey}/";
240            $result = \App::$http->readDeleteResult($url, []);
241            $entity = $result?->getEntity();
242            if (!$entity instanceof Process) {
243                return new Process();
244            }
245            return $entity;
246        } catch (\Exception $e) {
247            ExceptionService::handleException($e);
248        }
249    }
250
251    public static function sendConfirmationEmail(Process $process): Process
252    {
253        try {
254            $url = "/process/{$process->id}/{$process->authKey}/confirmation/mail/";
255            $result = \App::$http->readPostResult($url, $process);
256            $entity = $result?->getEntity();
257            if (!$entity instanceof Process) {
258                return new Process();
259            }
260            return $entity;
261        } catch (\Exception $e) {
262            ExceptionService::handleException($e);
263        }
264    }
265
266    public static function sendPreconfirmationEmail(Process $process): Process
267    {
268        try {
269            $url = "/process/{$process->id}/{$process->authKey}/preconfirmation/mail/";
270            $result = \App::$http->readPostResult($url, $process);
271            $entity = $result?->getEntity();
272            if (!$entity instanceof Process) {
273                return new Process();
274            }
275            return $entity;
276        } catch (\Exception $e) {
277            ExceptionService::handleException($e);
278        }
279    }
280
281    public static function sendCancellationEmail(Process $process): Process
282    {
283        try {
284            $url = "/process/{$process->id}/{$process->authKey}/delete/mail/";
285            $result = \App::$http->readPostResult($url, $process);
286            $entity = $result?->getEntity();
287            if (!$entity instanceof Process) {
288                return new Process();
289            }
290            return $entity;
291        } catch (\Exception $e) {
292            ExceptionService::handleException($e);
293        }
294    }
295
296    public static function getProcessById(int $processId, string $authKey): Process
297    {
298        try {
299            $resolveReferences = 2;
300            $result = \App::$http->readGetResult("/process/{$processId}/{$authKey}/", [
301                'resolveReferences' => $resolveReferences
302            ]);
303            $entity = $result?->getEntity();
304            if (!$entity instanceof Process) {
305                return new Process();
306            }
307            return $entity;
308        } catch (\Exception $e) {
309            ExceptionService::handleException($e);
310        }
311    }
312
313    public static function getScopesByProviderId(string $source, string|int $providerId): ScopeList
314    {
315        try {
316            $scopeList = self::getScopes();
317            if (!$scopeList instanceof ScopeList) {
318                return new ScopeList();
319            }
320            $result = $scopeList->withProviderID($source, (string) $providerId);
321            if (!$result instanceof ScopeList) {
322                return new ScopeList();
323            }
324            return $result;
325        } catch (\Exception $e) {
326            ExceptionService::handleException($e);
327        }
328    }
329}