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