Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
91.15% |
237 / 260 |
|
82.14% |
23 / 28 |
CRAP | |
0.00% |
0 / 1 |
Scope | |
91.15% |
237 / 260 |
|
82.14% |
23 / 28 |
80.00 | |
0.00% |
0 / 1 |
readEntity | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
4 | |||
readResolvedReferences | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
readByClusterId | |
100.00% |
23 / 23 |
|
100.00% |
1 / 1 |
5 | |||
readByProviderId | |
65.00% |
13 / 20 |
|
0.00% |
0 / 1 |
6.07 | |||
readByRequestId | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
readByDepartmentId | |
100.00% |
26 / 26 |
|
100.00% |
1 / 1 |
6 | |||
readListBySource | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
testSource | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
readCollection | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
readList | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
4 | |||
readIsOpened | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
readIsEnabled | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
3 | |||
readWaitingNumberUpdated | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
3 | |||
readIsGivenNumberInContingent | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
readQueueList | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
2 | |||
readWithWorkstationCount | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
2 | |||
readQueueListWithWaitingTime | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
2 | |||
readListWithScopeAdminEmail | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
4 | |||
writeEntity | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
updateEntity | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
1 | |||
replacePreferences | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
4 | |||
updateGhostWorkstationCount | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
updateEmergency | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
writeImageData | |
93.33% |
14 / 15 |
|
0.00% |
0 / 1 |
4.00 | |||
readImageData | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
2 | |||
deleteImage | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
deleteEntity | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
3 | |||
deletePreferences | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | |
3 | namespace BO\Zmsdb; |
4 | |
5 | use BO\Zmsentities\Scope as Entity; |
6 | use BO\Zmsentities\Collection\ScopeList as Collection; |
7 | |
8 | /** |
9 | * |
10 | * @SuppressWarnings(Public) |
11 | * @SuppressWarnings(Coupling) |
12 | * @SuppressWarnings(Complexity) |
13 | * @SuppressWarnings(TooManyMethods) |
14 | * |
15 | */ |
16 | class Scope extends Base |
17 | { |
18 | public static $cache = [ ]; |
19 | |
20 | public function readEntity($scopeId, $resolveReferences = 0, $disableCache = false) |
21 | { |
22 | $cacheKey = "$scopeId-$resolveReferences"; |
23 | if ($disableCache || ! array_key_exists($cacheKey, self::$cache)) { |
24 | $query = new Query\Scope(Query\Base::SELECT); |
25 | $query->addEntityMapping() |
26 | ->addResolvedReferences($resolveReferences) |
27 | ->addConditionScopeId($scopeId); |
28 | $scope = $this->fetchOne($query, new Entity()); |
29 | if (! $scope->hasId()) { |
30 | return null; |
31 | } |
32 | self::$cache[$cacheKey] = $this->readResolvedReferences($scope, $resolveReferences); |
33 | } |
34 | return self::$cache[$cacheKey]; |
35 | } |
36 | |
37 | public function readResolvedReferences( |
38 | \BO\Zmsentities\Schema\Entity $scope, |
39 | $resolveReferences |
40 | ) { |
41 | if (0 < $resolveReferences) { |
42 | $scope['dayoff'] = (new DayOff())->readByScopeId($scope->id); |
43 | } |
44 | return $scope; |
45 | } |
46 | |
47 | public function readByClusterId( |
48 | $clusterId, |
49 | $resolveReferences = 0 |
50 | ) { |
51 | $scopeList = new Collection(); |
52 | if ($resolveReferences > 0) { |
53 | $query = new Query\Scope(Query\Base::SELECT); |
54 | $query->addEntityMapping() |
55 | ->addResolvedReferences($resolveReferences - 1) |
56 | ->addConditionClusterId($clusterId); |
57 | $result = $this->fetchList($query, new Entity()); |
58 | } else { |
59 | $result = $this->getReader()->perform( |
60 | (new Query\Scope(Query\Base::SELECT))->getQuerySimpleClusterMatch(), |
61 | [$clusterId] |
62 | ); |
63 | } |
64 | if ($result) { |
65 | foreach ($result as $entity) { |
66 | if (0 == $resolveReferences) { |
67 | $entity = new Entity( |
68 | array( |
69 | 'id' => $entity['id'], |
70 | '$ref' => '/scope/' . $entity['id'] . '/' |
71 | ) |
72 | ); |
73 | $scopeList->addEntity($entity); |
74 | } else { |
75 | $scopeList->addEntity($this->readResolvedReferences($entity, $resolveReferences - 1)); |
76 | } |
77 | } |
78 | } |
79 | return $scopeList; |
80 | } |
81 | |
82 | public function readByProviderId($providerId, $resolveReferences = 0) |
83 | { |
84 | $scopeList = new Collection(); |
85 | $query = new Query\Scope(Query\Base::SELECT); |
86 | $query->addEntityMapping() |
87 | ->addResolvedReferences($resolveReferences) |
88 | ->addConditionProviderId($providerId); |
89 | $result = $this->fetchList($query, new Entity()); |
90 | if (count($result)) { |
91 | foreach ($result as $entity) { |
92 | if (0 == $resolveReferences) { |
93 | $entity = new Entity( |
94 | array( |
95 | 'id' => $entity->id, |
96 | '$ref' => '/scope/' . $entity->id . '/' |
97 | ) |
98 | ); |
99 | $scopeList->addEntity($entity); |
100 | } else { |
101 | if ($entity instanceof Entity) { |
102 | $entity = $this->readResolvedReferences($entity, $resolveReferences - 1); |
103 | $scopeList->addEntity($entity); |
104 | } |
105 | } |
106 | } |
107 | } |
108 | return $scopeList; |
109 | } |
110 | |
111 | public function readByRequestId($requestId, $source, $resolveReferences = 0) |
112 | { |
113 | $scopeList = new Collection(); |
114 | $providerList = (new Provider())->readListBySource($source, 0, true, $requestId); |
115 | |
116 | foreach ($providerList as $provider) { |
117 | $scopeListByProvider = $this->readByProviderId($provider->getId(), $resolveReferences); |
118 | if ($scopeListByProvider->count()) { |
119 | $scopeList->addList($scopeListByProvider); |
120 | } |
121 | } |
122 | return $scopeList->withUniqueScopes(); |
123 | } |
124 | |
125 | public function readByDepartmentId($departmentId, $resolveReferences = 0) |
126 | { |
127 | $scopeList = new Collection(); |
128 | if ($resolveReferences > 0) { |
129 | $query = new Query\Scope(Query\Base::SELECT); |
130 | $query->addEntityMapping() |
131 | ->addResolvedReferences($resolveReferences) |
132 | ->addConditionDepartmentId($departmentId); |
133 | $result = $this->fetchList($query, new Entity()); |
134 | } else { |
135 | $result = $this->getReader()->perform( |
136 | (new Query\Scope(Query\Base::SELECT))->getQuerySimpleDepartmentMatch(), |
137 | [$departmentId] |
138 | ); |
139 | } |
140 | if ($result) { |
141 | foreach ($result as $entity) { |
142 | if (0 == $resolveReferences) { |
143 | $entity = new Entity( |
144 | array( |
145 | 'id' => $entity['id'], |
146 | 'contact' => ['name' => $entity['contact__name']], |
147 | '$ref' => '/scope/' . $entity['id'] . '/' |
148 | ) |
149 | ); |
150 | $scopeList->addEntity($entity); |
151 | } else { |
152 | if ($entity instanceof Entity) { |
153 | $entity = $this->readResolvedReferences($entity, $resolveReferences); |
154 | $scopeList->addEntity($entity); |
155 | } |
156 | } |
157 | } |
158 | } |
159 | return $scopeList; |
160 | } |
161 | public function readListBySource($source, $resolveReferences = 0) |
162 | { |
163 | $this->testSource($source); |
164 | $query = new Query\Request(Query\Base::SELECT); |
165 | $query->setResolveLevel($resolveReferences); |
166 | $query->addConditionRequestSource($source); |
167 | $query->addEntityMapping(); |
168 | $requestList = $this->readCollection($query); |
169 | return ($requestList->count()) ? $requestList->sortByCustomKey('id') : $requestList; |
170 | } |
171 | |
172 | protected function testSource($source) |
173 | { |
174 | if (! (new Source())->readEntity($source)) { |
175 | throw new Exception\Source\UnknownDataSource(); |
176 | } |
177 | } |
178 | |
179 | protected function readCollection($query) |
180 | { |
181 | $requestList = new Collection(); |
182 | $statement = $this->fetchStatement($query); |
183 | while ($requestData = $statement->fetch(\PDO::FETCH_ASSOC)) { |
184 | $request = new Entity($query->postProcessJoins($requestData)); |
185 | $requestList->addEntity($request); |
186 | } |
187 | return $requestList; |
188 | } |
189 | |
190 | public function readList($resolveReferences = 0) |
191 | { |
192 | $scopeList = new Collection(); |
193 | $query = new Query\Scope(Query\Base::SELECT); |
194 | $query->addEntityMapping() |
195 | ->addResolvedReferences($resolveReferences); |
196 | $result = $this->fetchList($query, new Entity()); |
197 | if (count($result)) { |
198 | foreach ($result as $entity) { |
199 | if ($entity instanceof Entity) { |
200 | $entity = $this->readResolvedReferences($entity, $resolveReferences); |
201 | $scopeList->addEntity($entity); |
202 | } |
203 | } |
204 | } |
205 | return $scopeList; |
206 | } |
207 | |
208 | /** |
209 | * get a scope and return true if it is opened |
210 | * |
211 | * * @param |
212 | * scopeId |
213 | * now |
214 | * |
215 | * @return Bool |
216 | */ |
217 | public function readIsOpened($scopeId, $now) |
218 | { |
219 | $isOpened = false; |
220 | $availabilityList = (new Availability())->readOpeningHoursListByDate($scopeId, $now, 2); |
221 | if ($availabilityList->isOpened($now)) { |
222 | $isOpened = true; |
223 | } |
224 | return $isOpened; |
225 | } |
226 | |
227 | public function readIsEnabled($scopeId, $now) |
228 | { |
229 | $query = new Query\Scope(Query\Base::SELECT); |
230 | $query->addEntityMapping() |
231 | ->setResolveLevel(0) |
232 | ->addConditionScopeId($scopeId); |
233 | $scope = $this->fetchOne($query, new Entity()); |
234 | return ( |
235 | $this->readIsOpened($scopeId, $now) && |
236 | $this->readIsGivenNumberInContingent($scopeId) && |
237 | ! $scope->getStatus('ticketprinter', 'deactivated') |
238 | ); |
239 | } |
240 | |
241 | /** |
242 | * get last given waitingnumer and return updated (+1) waitingnumber |
243 | * |
244 | * * @param |
245 | * scopeId |
246 | * now |
247 | * |
248 | * @return Bool |
249 | */ |
250 | public function readWaitingNumberUpdated($scopeId, $dateTime, $respectContingent = true) |
251 | { |
252 | if (! $this->readIsGivenNumberInContingent($scopeId) && $respectContingent) { |
253 | throw new Exception\Scope\GivenNumberCountExceeded(); |
254 | } |
255 | $this->perform( |
256 | (new Query\Scope(Query\Base::SELECT))->getQueryLastWaitingNumber(), |
257 | ['scope_id' => $scopeId] |
258 | ); |
259 | $entity = $this->readEntity($scopeId, 0, true)->updateStatusQueue($dateTime); |
260 | $scope = $this->updateEntity($scopeId, $entity); |
261 | return $scope->getStatus('queue', 'lastGivenNumber'); |
262 | } |
263 | |
264 | /** |
265 | * get last given waitingnumer and return updated (+1) waitingnumber |
266 | * |
267 | * * @param |
268 | * scopeId |
269 | * now |
270 | * |
271 | * @return Bool |
272 | */ |
273 | public function readIsGivenNumberInContingent($scopeId) |
274 | { |
275 | $isInContingent = $this->getReader() |
276 | ->fetchValue((new Query\Scope(Query\Base::SELECT)) |
277 | ->getQueryGivenNumbersInContingent(), ['scope_id' => $scopeId]); |
278 | return ($isInContingent) ? true : false; |
279 | } |
280 | |
281 | /** |
282 | * get list of queues on scope by daytime |
283 | * |
284 | * * @param |
285 | * scopeId |
286 | * now |
287 | * |
288 | * @return number |
289 | */ |
290 | public function readQueueList($scopeId, $dateTime, $resolveReferences = 0) |
291 | { |
292 | if ($resolveReferences > 0) { |
293 | // resolveReferences > 0 is only necessary for a resolved process |
294 | $queueList = (new Process()) |
295 | ->readProcessListByScopeAndTime($scopeId, $dateTime, $resolveReferences - 1) |
296 | ->toQueueList($dateTime); |
297 | } else { |
298 | $queueList = (new Queue()) |
299 | ->readListByScopeAndTime($scopeId, $dateTime, $resolveReferences); |
300 | } |
301 | return $queueList->withSortedArrival(); |
302 | } |
303 | |
304 | /** |
305 | * get waitingtime of scope |
306 | * |
307 | * * @param |
308 | * scopeId |
309 | * now |
310 | * |
311 | * @return \BO\Zmsentities\Scope |
312 | */ |
313 | public function readWithWorkstationCount($scopeId, $dateTime, $resolveReferences = 0) |
314 | { |
315 | //get scope |
316 | $query = new Query\Scope(Query\Base::SELECT); |
317 | $query |
318 | ->addEntityMapping() |
319 | ->addConditionScopeId($scopeId) |
320 | ->addResolvedReferences($resolveReferences) |
321 | ->addSelectWorkstationCount($dateTime); |
322 | $scope = $this->fetchOne($query, new Entity()); |
323 | $scope = $this->readResolvedReferences($scope, $resolveReferences); |
324 | return ($scope->hasId()) ? $scope : null; |
325 | } |
326 | |
327 | public function readQueueListWithWaitingTime($scope, $dateTime, $resolveReferences = 0) |
328 | { |
329 | $timeAverage = $scope->getPreference('queue', 'processingTimeAverage'); |
330 | $scope = (! $timeAverage) ? (new Scope())->readEntity($scope->id) : $scope; |
331 | $queueList = $this->readQueueList($scope->id, $dateTime, $resolveReferences); |
332 | $timeAverage = $scope->getPreference('queue', 'processingTimeAverage'); |
333 | $workstationCount = $scope->getCalculatedWorkstationCount(); |
334 | return $queueList->withEstimatedWaitingTime($timeAverage, $workstationCount, $dateTime); |
335 | } |
336 | |
337 | /** |
338 | * get list of scopes with admin |
339 | * |
340 | * * @param |
341 | * scopeId |
342 | * now |
343 | * |
344 | * @return number |
345 | */ |
346 | public function readListWithScopeAdminEmail($resolveReferences = 0) |
347 | { |
348 | $scopeList = new Collection(); |
349 | $query = new Query\Scope(Query\Base::SELECT); |
350 | $query |
351 | ->addEntityMapping() |
352 | ->addConditionWithAdminEmail() |
353 | ->addResolvedReferences($resolveReferences); |
354 | $result = $this->fetchList($query, new Entity()); |
355 | if (count($result)) { |
356 | foreach ($result as $entity) { |
357 | if ($entity instanceof Entity) { |
358 | $entity = $this->readResolvedReferences($entity, $resolveReferences); |
359 | $scopeList->addEntity($entity); |
360 | } |
361 | } |
362 | } |
363 | return $scopeList; |
364 | } |
365 | |
366 | |
367 | |
368 | |
369 | |
370 | /** |
371 | * write a scope |
372 | * |
373 | * @return Entity |
374 | */ |
375 | public function writeEntity(\BO\Zmsentities\Scope $entity, $parentId) |
376 | { |
377 | self::$cache = []; |
378 | $query = new Query\Scope(Query\Base::INSERT); |
379 | $values = $query->reverseEntityMapping($entity, $parentId); |
380 | $query->addValues($values); |
381 | $this->writeItem($query); |
382 | $lastInsertId = $this->getWriter() |
383 | ->lastInsertId(); |
384 | $this->replacePreferences($entity); |
385 | return $this->readEntity($lastInsertId); |
386 | } |
387 | |
388 | /** |
389 | * update a scope |
390 | * |
391 | * @param |
392 | * scopeId |
393 | * |
394 | * @return Entity |
395 | */ |
396 | public function updateEntity($scopeId, \BO\Zmsentities\Scope $entity, $resolveReferences = 0) |
397 | { |
398 | self::$cache = []; |
399 | $query = new Query\Scope(Query\Base::UPDATE); |
400 | $query->addConditionScopeId($scopeId); |
401 | $values = $query->reverseEntityMapping($entity); |
402 | $query->addValues($values); |
403 | $this->writeItem($query); |
404 | $this->replacePreferences($entity); |
405 | return $this->readEntity($scopeId, $resolveReferences); |
406 | } |
407 | |
408 | public function replacePreferences(\BO\Zmsentities\Scope $entity) |
409 | { |
410 | if (isset($entity['preferences'])) { |
411 | $preferenceQuery = new Preferences(); |
412 | $entityName = 'scope'; |
413 | $entityId = $entity['id']; |
414 | foreach ($entity['preferences'] as $groupName => $groupValues) { |
415 | foreach ($groupValues as $name => $value) { |
416 | $preferenceQuery->replaceProperty($entityName, $entityId, $groupName, $name, $value); |
417 | } |
418 | } |
419 | } |
420 | } |
421 | |
422 | /** |
423 | * update ghostWorkstationCount |
424 | * |
425 | * @param |
426 | * scopeId |
427 | * entity |
428 | * dateTime (now) |
429 | * |
430 | * @return Entity |
431 | */ |
432 | public function updateGhostWorkstationCount(\BO\Zmsentities\Scope $entity, \DateTimeInterface $dateTime) |
433 | { |
434 | $query = new Query\Scope(Query\Base::UPDATE); |
435 | $query->addConditionScopeId($entity->id); |
436 | $values = $query->setGhostWorkstationCountEntityMapping($entity, $dateTime); |
437 | $query->addValues($values); |
438 | $this->writeItem($query); |
439 | return $entity; |
440 | } |
441 | |
442 | /** |
443 | * update emergency |
444 | * |
445 | * @param |
446 | * scopeId |
447 | * entity |
448 | * |
449 | * @return Entity |
450 | */ |
451 | public function updateEmergency($scopeId, \BO\Zmsentities\Scope $entity) |
452 | { |
453 | self::$cache = []; |
454 | $query = new Query\Scope(Query\Base::UPDATE); |
455 | $query->addConditionScopeId($scopeId); |
456 | $values = $query->setEmergencyEntityMapping($entity); |
457 | $query->addValues($values); |
458 | $this->writeItem($query); |
459 | return $this->readEntity($scopeId); |
460 | } |
461 | |
462 | /** |
463 | * update image data for call display image |
464 | * |
465 | * @param |
466 | * scopeId |
467 | * Mimepart entity |
468 | * |
469 | * @return Mimepart entity |
470 | */ |
471 | public function writeImageData($scopeId, \BO\Zmsentities\Mimepart $entity) |
472 | { |
473 | if ($entity->mime && $entity->content) { |
474 | $this->deleteImage($scopeId); |
475 | $extension = $entity->getExtension(); |
476 | if ($extension == 'jpeg') { |
477 | $extension = 'jpg'; //compatibility ZMS1 |
478 | } |
479 | $imageName = 's_' . $scopeId . '_bild.' . $extension; |
480 | $this->getWriter()->perform( |
481 | (new Query\Scope(Query\Base::REPLACE))->getQueryWriteImageData(), |
482 | array( |
483 | 'imagename' => $imageName, |
484 | 'imagedata' => $entity->content |
485 | ) |
486 | ); |
487 | } |
488 | $entity->id = $scopeId; |
489 | return $entity; |
490 | } |
491 | |
492 | /** |
493 | * read image data |
494 | * |
495 | * @param |
496 | * scopeId |
497 | * |
498 | * @return Mimepart entity |
499 | */ |
500 | public function readImageData($scopeId) |
501 | { |
502 | $imageName = 's_' . $scopeId . '_bild'; |
503 | $imageData = new \BO\Zmsentities\Mimepart(); |
504 | $fileData = $this->getReader()->fetchAll( |
505 | (new Query\Scope(Query\Base::SELECT))->getQueryReadImageData(), |
506 | ['imagename' => "$imageName%"] |
507 | ); |
508 | if ($fileData) { |
509 | $imageData->content = $fileData[0]['imagecontent']; |
510 | $imageData->mime = pathinfo($fileData[0]['imagename'])['extension']; |
511 | } |
512 | return $imageData; |
513 | } |
514 | |
515 | /** |
516 | * delete image data for call display image |
517 | * |
518 | * @param |
519 | * scopeId |
520 | * |
521 | * @return Status |
522 | */ |
523 | public function deleteImage($scopeId) |
524 | { |
525 | $imageName = 's_' . $scopeId . '_bild'; |
526 | return $this->perform((new Query\Scope(Query\Base::DELETE))->getQueryDeleteImage(), array( |
527 | 'imagename' => "$imageName%" |
528 | )); |
529 | } |
530 | |
531 | /** |
532 | * remove a scope |
533 | * |
534 | * @param |
535 | * scopeId |
536 | * |
537 | * @return Resource Status |
538 | */ |
539 | public function deleteEntity($scopeId) |
540 | { |
541 | $processListCount = (new Process())->readProcessListCountByScope($scopeId); |
542 | if (0 < $processListCount) { |
543 | throw new Exception\Scope\ScopeHasProcesses(); |
544 | } |
545 | self::$cache = []; |
546 | $entity = $this->readEntity($scopeId); |
547 | $query = new Query\Scope(Query\Base::DELETE); |
548 | $query->addConditionScopeId($scopeId); |
549 | $this->deletePreferences($entity); |
550 | return ($this->deleteItem($query)) ? $entity : null; |
551 | } |
552 | |
553 | public function deletePreferences(\BO\Zmsentities\Scope $entity) |
554 | { |
555 | $preferenceQuery = new Preferences(); |
556 | $entityName = 'scope'; |
557 | $entityId = $entity['id']; |
558 | foreach ($entity['preferences'] as $groupName => $groupValues) { |
559 | foreach (array_keys($groupValues) as $name) { |
560 | $preferenceQuery->deleteProperty($entityName, $entityId, $groupName, $name); |
561 | } |
562 | } |
563 | } |
564 | } |