Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
91.15% covered (success)
91.15%
237 / 260
82.14% covered (warning)
82.14%
23 / 28
CRAP
0.00% covered (danger)
0.00%
0 / 1
Scope
91.15% covered (success)
91.15%
237 / 260
82.14% covered (warning)
82.14%
23 / 28
80.00
0.00% covered (danger)
0.00%
0 / 1
 readEntity
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
4
 readResolvedReferences
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 readByClusterId
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
5
 readByProviderId
65.00% covered (warning)
65.00%
13 / 20
0.00% covered (danger)
0.00%
0 / 1
6.07
 readByRequestId
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 readByDepartmentId
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
1 / 1
6
 readListBySource
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 testSource
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 readCollection
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 readList
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
4
 readIsOpened
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 readIsEnabled
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
3
 readWaitingNumberUpdated
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 readIsGivenNumberInContingent
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 readQueueList
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 readWithWorkstationCount
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
2
 readQueueListWithWaitingTime
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 readListWithScopeAdminEmail
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
4
 writeEntity
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 updateEntity
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 replacePreferences
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 updateGhostWorkstationCount
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 updateEmergency
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 writeImageData
93.33% covered (success)
93.33%
14 / 15
0.00% covered (danger)
0.00%
0 / 1
4.00
 readImageData
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
2
 deleteImage
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 deleteEntity
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 deletePreferences
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace BO\Zmsdb;
4
5use BO\Zmsentities\Scope as Entity;
6use BO\Zmsentities\Collection\ScopeList as Collection;
7
8/**
9 *
10 * @SuppressWarnings(Public)
11 * @SuppressWarnings(Coupling)
12 * @SuppressWarnings(Complexity)
13 * @SuppressWarnings(TooManyMethods)
14 *
15 */
16class 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}