Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
99.41% covered (success)
99.41%
169 / 170
94.44% covered (success)
94.44%
17 / 18
CRAP
0.00% covered (danger)
0.00%
0 / 1
Cluster
99.41% covered (success)
99.41%
169 / 170
94.44% covered (success)
94.44%
17 / 18
54
0.00% covered (danger)
0.00%
0 / 1
 readEntity
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
2
 readResolvedReferences
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 readEntityWithOpenedScopeStatus
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 readList
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
4
 readByScopeId
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
2
 readByDepartmentId
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
5
 readQueueList
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 readOpenedScopeList
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
5
 readEnabledScopeList
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 readScopeWithShortestWaitingTime
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
7
 readWithScopeWorkstationCount
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 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%
8 / 8
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
2
 writeEntity
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 updateEntity
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 writeAssignedScopes
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace BO\Zmsdb;
4
5use BO\Zmsentities\Cluster as Entity;
6use BO\Zmsentities\Collection\ClusterList as Collection;
7
8/**
9 *
10 * @SuppressWarnings(Public)
11 * @SuppressWarnings(Coupling)
12 * @SuppressWarnings(Complexity)
13 *
14 */
15class Cluster extends Base
16{
17    /**
18    * read entity
19    *
20    * @param
21    * itemId
22    * resolveReferences
23    *
24    * @return Resource Entity
25    */
26    public function readEntity($itemId, $resolveReferences = 0)
27    {
28        $query = new Query\Cluster(Query\Base::SELECT);
29        $query
30            ->addEntityMapping()
31            ->addResolvedReferences($resolveReferences)
32            ->addConditionClusterId($itemId);
33        $cluster = $this->fetchOne($query, new Entity());
34        if (! $cluster->hasId()) {
35            return null;
36        }
37        return $this->readResolvedReferences($cluster, $resolveReferences);
38    }
39
40    public function readResolvedReferences(\BO\Zmsentities\Schema\Entity $entity, $resolveReferences)
41    {
42        $entity['scopes'] = (new Scope())->readByClusterId($entity->id, $resolveReferences);
43        return $entity;
44    }
45
46    public function readEntityWithOpenedScopeStatus($itemId, \DateTimeInterface $now, $resolveReferences = 0)
47    {
48        $entity = $this->readEntity($itemId, $resolveReferences);
49        foreach ($entity->scopes as $scope) {
50            $scope->setStatusAvailability('isOpened', (new Scope())->readIsOpened($scope->getId(), $now));
51        }
52        return $entity;
53    }
54
55    /**
56    * read list of clusters
57    *
58    * @param
59    * resolveReferences
60    *
61    * @return Resource Collection
62    */
63    public function readList($resolveReferences = 0)
64    {
65        $clusterList = new Collection();
66        $query = new Query\Cluster(Query\Base::SELECT);
67        $query
68            ->addResolvedReferences($resolveReferences)
69            ->addEntityMapping();
70        $result = $this->fetchList($query, new Entity());
71        if (count($result)) {
72            foreach ($result as $entity) {
73                if ($entity instanceof Entity) {
74                    $entity = $this->readResolvedReferences($entity, $resolveReferences);
75                    $clusterList->addEntity($entity);
76                }
77            }
78        }
79        return $clusterList;
80    }
81
82    public function readByScopeId($scopeId, $resolveReferences = 0)
83    {
84        $query = new Query\Cluster(Query\Base::SELECT);
85        $query
86            ->addEntityMapping()
87            ->addResolvedReferences($resolveReferences)
88            ->addConditionScopeId($scopeId);
89        $entity = $this->fetchOne($query, new Entity());
90        if (! $entity->hasId()) {
91            return null;
92        }
93        $entity = $this->readResolvedReferences($entity, $resolveReferences);
94        return $entity;
95    }
96
97    public function readByDepartmentId($departmentId, $resolveReferences = 0)
98    {
99        $clusterList = new Collection();
100        $query = new Query\Cluster(Query\Base::SELECT);
101        $query
102            ->addEntityMapping()
103            ->addResolvedReferences($resolveReferences)
104            ->addConditionDepartmentId($departmentId);
105        $result = $this->fetchList($query, new Entity());
106        if (count($result)) {
107            foreach ($result as $entity) {
108                if ($entity instanceof Entity && !$clusterList->hasEntity($entity->id)) {
109                    $entity = $this->readResolvedReferences($entity, $resolveReferences);
110                    $clusterList->addEntity($entity);
111                }
112            }
113        }
114        return $clusterList;
115    }
116
117    /**
118     * get a queueList by cluster id and dateTime
119     *
120     ** @param
121     *            clusterId
122     *            now
123     *
124     * @return Bool
125     */
126    public function readQueueList(
127        $clusterId,
128        \DateTimeInterface $dateTime,
129        $resolveReferences = 0
130    ) {
131        $cluster = $this->readEntity($clusterId, 1);
132        $queueList = new \BO\Zmsentities\Collection\QueueList();
133        foreach ($cluster->scopes as $scope) {
134            $scope = (new Scope())->readWithWorkstationCount($scope->id, $dateTime);
135            $scopeQueueList = (new Scope())
136                ->readQueueListWithWaitingTime($scope, $dateTime, $resolveReferences);
137            if (0 < $scopeQueueList->count()) {
138                $queueList->addList($scopeQueueList);
139            }
140        }
141        return $queueList->withSortedWaitingTime();
142    }
143
144    /**
145     * get a scopeList with opened scopes
146     *
147     ** @param
148     *            clusterId
149     *            now
150     *
151     * @return Bool
152     */
153    public function readOpenedScopeList($clusterId, \DateTimeInterface $dateTime)
154    {
155        $scopeList = new \BO\Zmsentities\Collection\ScopeList();
156        $cluster = $this->readEntity($clusterId, 1);
157        if ($cluster && $cluster->toProperty()->scopes->get()) {
158            foreach ($cluster->scopes as $scope) {
159                $availabilityList = (new Availability())->readOpeningHoursListByDate($scope['id'], $dateTime, 2);
160                if ($availabilityList->isOpened($dateTime)) {
161                    $scope->setStatusAvailability('isOpened', true);
162                    $scopeList->addEntity($scope);
163                }
164            }
165        }
166        return $scopeList;
167    }
168
169    public function readEnabledScopeList($clusterId, \DateTimeInterface $dateTime)
170    {
171        $scopeList = new \BO\Zmsentities\Collection\ScopeList();
172        foreach ($this->readOpenedScopeList($clusterId, $dateTime) as $scope) {
173            if ((new Scope())->readIsGivenNumberInContingent($scope['id'])) {
174                $scopeList->addEntity($scope);
175            }
176        }
177        return $scopeList;
178    }
179
180    /**
181     * get the scope with shortest estimated waitingtime
182     *
183     ** @param
184     *            clusterId
185     *            now
186     *
187     * @return Bool
188     */
189    public function readScopeWithShortestWaitingTime($clusterId, \DateTimeInterface $dateTime)
190    {
191        $scopeList = $this->readOpenedScopeList($clusterId, $dateTime)->getArrayCopy();
192        $nextScope = array_shift($scopeList);
193        $preferedScope = null;
194        $preferedWaitingTime = 0;
195        while ($nextScope) {
196            $scope = (new Scope())->readWithWorkstationCount($nextScope->id, $dateTime);
197            $queueList = (new Scope())->readQueueListWithWaitingTime($scope, $dateTime);
198            $data = $scope->getWaitingTimeFromQueueList($queueList, $dateTime);
199            if (
200                $scope->getCalculatedWorkstationCount() > 0 &&
201                $data &&
202                ($data['waitingTimeEstimate'] <= $preferedWaitingTime || 0 == $preferedWaitingTime)
203            ) {
204                $preferedWaitingTime = $data['waitingTimeEstimate'];
205                $preferedScope = $scope;
206            }
207            $nextScope = array_shift($scopeList);
208        }
209        if (! $preferedScope) {
210            throw new Exception\Cluster\ScopesWithoutWorkstationCount();
211        }
212        return $preferedScope;
213    }
214
215    /**
216     * get cluster with scopes workstation count
217     *
218     * * @param
219     * scopeId
220     * now
221     *
222     * @return number
223     */
224    public function readWithScopeWorkstationCount($clusterId, $dateTime, $resolveReferences = 0)
225    {
226        $scopeQuery = new Scope();
227        $scopeList = new \BO\Zmsentities\Collection\ScopeList();
228        $cluster = $this->readEntity($clusterId, $resolveReferences);
229        if ($cluster->toProperty()->scopes->get()) {
230            foreach ($cluster->scopes as $scope) {
231                $entity = $scopeQuery->readWithWorkstationCount($scope->id, $dateTime, $resolveReferences = 0);
232                if ($entity) {
233                    $scopeList->addEntity($entity);
234                }
235            }
236        }
237        $cluster->scopes = $scopeList;
238        return $cluster;
239    }
240
241    /**
242     * update image data for call display image
243     *
244     * @param
245     *         clusterId
246     *         Mimepart entity
247     *
248     * @return Mimepart entity
249     */
250    public function writeImageData($clusterId, \BO\Zmsentities\Mimepart $entity)
251    {
252        if ($entity->mime && $entity->content) {
253            $this->deleteImage($clusterId);
254            $extension = $entity->getExtension();
255            if ($extension == 'jpeg') {
256                $extension = 'jpg'; //compatibility ZMS1
257            }
258            $imageName = 'c_' . $clusterId . '_bild.' . $extension;
259            $this->perform(
260                (new Query\Scope(Query\Base::REPLACE))->getQueryWriteImageData(),
261                array(
262                'imagename' => $imageName,
263                'imagedata' => $entity->content
264                )
265            );
266        }
267        $entity->id = $clusterId;
268        return $entity;
269    }
270
271    /**
272     * read image data
273     *
274     * @param
275     *         clusterId
276     *
277     * @return Mimepart entity
278     */
279    public function readImageData($clusterId)
280    {
281        $imageName = 'c_' . $clusterId . '_bild';
282        $imageData = new \BO\Zmsentities\Mimepart();
283        $fileData = $this->getReader()->fetchAll(
284            (new Query\Scope(Query\Base::SELECT))->getQueryReadImageData(),
285            ['imagename' => "$imageName%"]
286        );
287        if ($fileData) {
288            $imageData->content = $fileData[0]['imagecontent'];
289            $imageData->mime = pathinfo($fileData[0]['imagename'])['extension'];
290        }
291        return $imageData;
292    }
293
294    /**
295     * delete image data for calldisplay image
296     *
297     * @param
298     *         clusterId
299     *
300     * @return Status
301     */
302    public function deleteImage($clusterId)
303    {
304        $imageName = 'c_' . $clusterId . '_bild';
305        $result = $this->perform(
306            (new Query\Scope(Query\Base::DELETE))->getQueryDeleteImage(),
307            array(
308            'imagename' => "$imageName%"
309            )
310        );
311        return $result;
312    }
313
314    /**
315    * remove an cluster
316    *
317    * @param
318    * itemId
319    *
320    * @return Resource Status
321    */
322    public function deleteEntity($itemId)
323    {
324        $result = false;
325        $query =  new Query\Cluster(Query\Base::DELETE);
326        $query->addConditionClusterId($itemId);
327        if ($this->deleteItem($query)) {
328            $result = $this->perform(
329                (new Query\Cluster(Query\Base::DELETE))->getQueryDeleteAssignedScopes(),
330                ['clusterId' => $itemId]
331            );
332        }
333        return $result;
334    }
335
336    /**
337     * write an cluster
338     *
339     * @param
340     * entity
341     *
342     * @return Entity
343     */
344    public function writeEntity(\BO\Zmsentities\Cluster $entity)
345    {
346        $query = new Query\Cluster(Query\Base::INSERT);
347        $values = $query->reverseEntityMapping($entity);
348        $query->addValues($values);
349        $this->writeItem($query);
350        $lastInsertId = $this->getWriter()->lastInsertId();
351        if ($entity->toProperty()->scopes->isAvailable()) {
352            $this->writeAssignedScopes($lastInsertId, $entity->scopes);
353        }
354        return $this->readEntity($lastInsertId, 1);
355    }
356
357    /**
358     * update an cluster
359     *
360     * @param
361     * clusterId, entity
362     *
363     * @return Entity
364     */
365    public function updateEntity($clusterId, \BO\Zmsentities\Cluster $entity)
366    {
367        $query = new Query\Cluster(Query\Base::UPDATE);
368        $query->addConditionClusterId($clusterId);
369        $values = $query->reverseEntityMapping($entity);
370        $query->addValues($values);
371        $this->writeItem($query);
372        if ($entity->toProperty()->scopes->isAvailable()) {
373            $this->writeAssignedScopes($clusterId, $entity->scopes);
374        }
375        return $this->readEntity($clusterId, 1);
376    }
377
378    /**
379     * create links preferences of a department
380     *
381     * @param
382     *            departmentId,
383     *            links
384     *
385     * @return Boolean
386     */
387    protected function writeAssignedScopes($clusterId, $scopeList)
388    {
389        $this->perform(
390            (new Query\Cluster(Query\Base::DELETE))->getQueryDeleteAssignedScopes(),
391            ['clusterId' => $clusterId]
392        );
393        foreach ($scopeList as $scope) {
394            if (0 < $scope['id']) {
395                $this->perform(
396                    (new Query\Cluster(Query\Base::REPLACE))->getQueryWriteAssignedScopes(),
397                    array(
398                    'clusterId' => $clusterId,
399                    'scopeId' => $scope['id']
400                    )
401                );
402            }
403        }
404    }
405}