Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.14% covered (success)
94.14%
209 / 222
70.59% covered (warning)
70.59%
12 / 17
CRAP
0.00% covered (danger)
0.00%
0 / 1
Department
94.14% covered (success)
94.14%
209 / 222
70.59% covered (warning)
70.59%
12 / 17
77.16
0.00% covered (danger)
0.00%
0 / 1
 readEntity
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
8
 readResolvedReferences
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
2
 readList
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
4
 readEntitiesByIds
92.86% covered (success)
92.86%
13 / 14
0.00% covered (danger)
0.00%
0 / 1
5.01
 readByScopeId
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 readByOrganisationId
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
4
 deleteEntity
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
8
 writeEntity
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
1 / 1
5
 updateEntity
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
4
 writeDepartmentDayoffs
94.12% covered (success)
94.12%
16 / 17
0.00% covered (danger)
0.00%
0 / 1
5.01
 writeDepartmentLinks
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
5.02
 writeDepartmentMail
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 writeDepartmentNotifications
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
7
 updateDepartmentMail
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 updateDepartmentNotifications
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
5
 readQueueList
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 removeCache
87.50% covered (warning)
87.50%
7 / 8
0.00% covered (danger)
0.00%
0 / 1
6.07
1<?php
2
3namespace BO\Zmsdb;
4
5use BO\Zmsdb\Application as App;
6use BO\Zmsentities\Department as Entity;
7use BO\Zmsentities\Collection\DepartmentList as Collection;
8
9/**
10 * @SuppressWarnings(Coupling)
11 * @SuppressWarnings(Complexity)
12 *
13 */
14class Department extends Base
15{
16    /**
17     *
18     * @var Array \BO\Zmsentities\Department
19     */
20    public static $departmentCache = array();
21
22    public function readEntity($departmentId, $resolveReferences = 0, $disableCache = false)
23    {
24        $cacheKey = "department-$departmentId-$resolveReferences";
25
26        if (!$disableCache && App::$cache && App::$cache->has($cacheKey)) {
27            $department = App::$cache->get($cacheKey);
28        }
29
30        if (empty($department)) {
31            $query = new Query\Department(Query\Base::SELECT);
32            $query->addEntityMapping()
33                ->addResolvedReferences($resolveReferences)
34                ->addConditionDepartmentId($departmentId);
35            $department = $this->fetchOne($query, new Entity());
36
37            if (App::$cache) {
38                App::$cache->set($cacheKey, $department);
39            }
40        }
41
42        if (isset($department['id']) && $department['id']) {
43            $department = $this->readResolvedReferences($department, $resolveReferences, $disableCache);
44            return $department->withOutClusterDuplicates();
45        }
46
47        return null;
48    }
49
50    public function readResolvedReferences(
51        \BO\Zmsentities\Schema\Entity $entity,
52        $resolveReferences,
53        $disableCache = false
54    ) {
55        $entity['links'] = (new Link())->readByDepartmentId($entity->id, $disableCache);
56        $entity['scopes'] = (new Scope())
57            ->readByDepartmentId($entity->id, $resolveReferences - 1, $disableCache)
58            ->sortByContactName();
59        if (0 < $resolveReferences) {
60            $entity['clusters'] = (new Cluster())->readByDepartmentId(
61                $entity->id,
62                $resolveReferences - 1,
63                $disableCache
64            );
65            $entity['dayoff'] = (new DayOff())->readOnlyByDepartmentId($entity->id, $disableCache);
66        }
67        return $entity;
68    }
69
70    public function readList($resolveReferences = 0)
71    {
72        $departmentList = new Collection();
73        $query = new Query\Department(Query\Base::SELECT);
74        $query->addEntityMapping();
75        $query->addResolvedReferences($resolveReferences);
76        $result = $this->fetchList($query, new Entity());
77        if (count($result)) {
78            foreach ($result as $department) {
79                $department = $this->readResolvedReferences($department, $resolveReferences);
80                if ($department instanceof Entity) {
81                    $departmentList->addEntity($department->withOutClusterDuplicates());
82                }
83            }
84        }
85        return $departmentList;
86    }
87
88    public function readEntitiesByIds(array $departmentIds, $resolveReferences = 0)
89    {
90        if (empty($departmentIds)) {
91            return [];
92        }
93
94        $query = new Query\Department(Query\Base::SELECT);
95        $query->addEntityMapping()
96            ->addResolvedReferences($resolveReferences)
97            ->addConditionDepartmentIds($departmentIds);
98
99        $departments = [];
100        $result = $this->fetchList($query, new Entity());
101
102        foreach ($result as $department) {
103            if ($department instanceof Entity) {
104                $department = $this->readResolvedReferences($department, $resolveReferences);
105                if ($department instanceof Entity) {
106                    $departments[$department->id] = $department->withOutClusterDuplicates();
107                }
108            }
109        }
110
111        return $departments;
112    }
113
114    public function readByScopeId($scopeId, $resolveReferences = 0)
115    {
116        $query = new Query\Department(Query\Base::SELECT);
117        $query->addEntityMapping()
118            ->addResolvedReferences($resolveReferences)
119            ->addConditionScopeId($scopeId);
120        $department = $this->fetchOne($query, new Entity());
121        $department = $this->readResolvedReferences($department, $resolveReferences);
122        return (isset($department['id']) && $department['id']) ? $department->withOutClusterDuplicates() : null;
123    }
124
125    public function readByOrganisationId($organisationId, $resolveReferences = 0)
126    {
127        $departmentList = new Collection();
128        $query = new Query\Department(Query\Base::SELECT);
129        $query
130            ->addEntityMapping()
131            ->addResolvedReferences($resolveReferences)
132            ->addConditionOrganisationId($organisationId);
133        $result = $this->fetchList($query, new Entity());
134        if (count($result)) {
135            foreach ($result as $department) {
136                if ($department instanceof Entity) {
137                    $department = $this->readResolvedReferences($department, $resolveReferences);
138                    $departmentList->addEntity($department->withOutClusterDuplicates());
139                }
140            }
141        }
142        return $departmentList;
143    }
144
145    /**
146     * remove a department
147     *
148     * @param
149     *            departmentId
150     *
151     * @return Resource Status
152     */
153    public function deleteEntity($departmentId)
154    {
155        $entity = $this->readEntity($departmentId, 1);
156        if ($entity) {
157            if (
158                0 < $entity->toProperty()->scopes->get()->count()
159                || 0 < $entity->toProperty()->clusters->get()->count()
160            ) {
161                throw new Exception\Department\ScopeListNotEmpty();
162            }
163
164            self::$departmentCache = [];
165            $query = new Query\Department(Query\Base::DELETE);
166            $query->addConditionDepartmentId($departmentId);
167            $entityDelete = $this->deleteItem($query);
168            $emailDelete = $this->perform(Query\Department::QUERY_MAIL_DELETE, array(
169                $departmentId
170            ));
171            $notificationsDelete = $this->perform(Query\Department::QUERY_NOTIFICATIONS_DELETE, array(
172                $departmentId
173            ));
174        }
175
176        $this->removeCache($entity);
177
178        return ($entity && $entityDelete && $emailDelete && $notificationsDelete) ? $entity : null;
179    }
180
181    /**
182     * write a department
183     *
184     * @param Department $entity
185     *
186     * @return Entity
187     */
188    public function writeEntity(\BO\Zmsentities\Department $entity, $parentId)
189    {
190        self::$departmentCache = [];
191        $query = new Query\Department(Query\Base::INSERT);
192        $values = $query->reverseEntityMapping($entity, $parentId);
193        // get owner by organisation
194        $owner = (new Owner())->readByOrganisationId($parentId);
195        $values['KundenID'] = $owner->id;
196        $query->addValues($values);
197        $this->writeItem($query);
198        $lastInsertId = $this->getWriter()
199            ->lastInsertId();
200        if ($entity->toProperty()->links->isAvailable()) {
201            $this->writeDepartmentLinks($lastInsertId, $entity->links);
202        }
203        if ($entity->toProperty()->dayoff->isAvailable()) {
204            $this->writeDepartmentDayoffs($lastInsertId, $entity->dayoff);
205        }
206        if ($entity->toProperty()->email->isAvailable()) {
207            $this->writeDepartmentMail(
208                $lastInsertId,
209                $entity->email,
210                $entity->sendEmailReminderEnabled,
211                $entity->sendEmailReminderMinutesBefore
212            );
213        }
214        if ($entity->getNotificationPreferences()) {
215            $this->writeDepartmentNotifications($lastInsertId, $entity->getNotificationPreferences());
216        }
217
218        $this->removeCache($entity);
219
220        return $this->readEntity($lastInsertId);
221    }
222
223    /**
224     * update a department
225     *
226     * @param
227     *            departmentId
228     *
229     * @return Entity
230     */
231    public function updateEntity($departmentId, \BO\Zmsentities\Department $entity)
232    {
233        self::$departmentCache = [];
234        $query = new Query\Department(Query\Base::UPDATE);
235        $query->addConditionDepartmentId($departmentId);
236        $values = $query->reverseEntityMapping($entity);
237        $query->addValues($values);
238        $this->writeItem($query);
239        if ($entity->toProperty()->links->isAvailable()) {
240            $this->writeDepartmentLinks($departmentId, $entity->links);
241        }
242        if ($entity->toProperty()->dayoff->isAvailable()) {
243            $this->writeDepartmentDayoffs($departmentId, $entity->dayoff);
244        }
245        if ($entity->toProperty()->email->isAvailable()) {
246            $this->updateDepartmentMail(
247                $departmentId,
248                $entity->email,
249                $entity->sendEmailReminderEnabled,
250                $entity->sendEmailReminderMinutesBefore
251            );
252        }
253        $this->updateDepartmentNotifications($departmentId, $entity->getNotificationPreferences());
254        $this->removeCache($entity);
255        return $this->readEntity($departmentId, 0, true);
256    }
257
258    /**
259     * create dayoff preferences of a department
260     *
261     * @param
262     *            departmentId,
263     *            dayoffs
264     *
265     * @return Boolean
266     */
267    protected function writeDepartmentDayoffs($departmentId, $dayoffList)
268    {
269        if (!$departmentId) {
270            throw new Exception\Department\InvalidId();
271        }
272        $existingDayoffs = (new DayOff())->readOnlyByDepartmentId($departmentId);
273        if ($existingDayoffs->count()) {
274            foreach ($existingDayoffs as $item) {
275                $query = new DayOff();
276                $query->deleteEntity($item->getId());
277            }
278        }
279
280        foreach ($dayoffList as $dayoff) {
281            $query = new Query\DayOff(Query\Base::INSERT);
282            $query->addValues(
283                [
284                    'behoerdenid' => $departmentId,
285                    'Feiertag' => $dayoff['name'],
286                    'Datum' => (new \DateTimeImmutable('@' . $dayoff['date']))->format('Y-m-d')
287                ]
288            );
289            $this->writeItem($query);
290        }
291    }
292
293    /**
294     * create links preferences of a department
295     *
296     * @param
297     *            departmentId,
298     *            links
299     *
300     * @return Boolean
301     */
302    protected function writeDepartmentLinks($departmentId, $links)
303    {
304        if (!$departmentId) {
305            throw new Exception\Department\InvalidId();
306        }
307        $existingLinks = (new Link())->readByDepartmentId($departmentId);
308        if ($existingLinks->count()) {
309            foreach ($existingLinks as $item) {
310                $query = new Link();
311                $query->deleteEntity($item->getId());
312            }
313        }
314
315        foreach ($links as $link) {
316            $link = new \BO\Zmsentities\Link($link);
317            $query = new Link();
318            $query->writeEntity($link, $departmentId);
319        }
320    }
321
322    /**
323     * create mail preferences of a department
324     *
325     * @param
326     *            departmentId,
327     *            email
328     *
329     * @return Boolean
330     */
331    protected function writeDepartmentMail(
332        $departmentId,
333        $email,
334        $sendEmailReminderEnabled,
335        $sendEmailReminderMinutesBefore
336    ) {
337        self::$departmentCache = [];
338        $result = $this->perform(Query\Department::QUERY_MAIL_INSERT, array(
339            $departmentId,
340            $email,
341            $sendEmailReminderEnabled,
342            $sendEmailReminderMinutesBefore
343        ));
344        return $result;
345    }
346
347    /**
348     * create notification preferences of a department
349     *
350     * @param
351     *            departmentId,
352     *            preferences
353     *
354     * @return Boolean
355     */
356    protected function writeDepartmentNotifications($departmentId, $preferences)
357    {
358        self::$departmentCache = [];
359
360        $result = $this->perform(
361            Query\Department::QUERY_NOTIFICATIONS_INSERT,
362            array(
363                $departmentId,
364                (isset($preferences['enabled']) && $preferences['enabled']) ? 1 : 0,
365                $preferences['identification'],
366                (isset($preferences['sendConfirmationEnabled']) && $preferences['sendConfirmationEnabled']) ? 1 : 0,
367                (isset($preferences['sendReminderEnabled']) && $preferences['sendReminderEnabled']) ? 1 : 0
368            )
369        );
370        return $result;
371    }
372
373    /**
374     * update mail preferences of a department
375     *
376     * @param
377     *            departmentId,
378     *            email
379     *
380     * @return Boolean
381     */
382    protected function updateDepartmentMail(
383        $departmentId,
384        $email,
385        $sendEmailReminderEnabled,
386        $sendEmailReminderMinutesBefore
387    ) {
388        self::$departmentCache = [];
389        $query = Query\Department::QUERY_MAIL_UPDATE;
390        return $this->fetchAffected($query, array(
391            'email' => $email,
392            'departmentId' => $departmentId,
393            'sendEmailReminderEnabled' => $sendEmailReminderEnabled,
394            'sendEmailReminderMinutesBefore' => $sendEmailReminderMinutesBefore
395        ));
396    }
397
398    /**
399     * update notification preferences of a department
400     *
401     * @param
402     *            departmentId,
403     *            preferences
404     *
405     * @return Boolean
406     */
407    protected function updateDepartmentNotifications($departmentId, $preferences)
408    {
409        self::$departmentCache = [];
410        $query = Query\Department::QUERY_NOTIFICATIONS_UPDATE;
411        return $this->fetchAffected(
412            $query,
413            array(
414                'enabled' =>
415                    (isset($preferences['enabled'])) ? $preferences['enabled'] : 0,
416                'identification' =>
417                    (isset($preferences['identification'])) ? $preferences['identification'] : 0,
418                'sendConfirmationEnabled' =>
419                    (isset($preferences['sendConfirmationEnabled'])) ? $preferences['sendConfirmationEnabled'] : 0,
420                'sendReminderEnabled' =>
421                    (isset($preferences['sendReminderEnabled'])) ? $preferences['sendReminderEnabled'] : 0,
422                'departmentId' => $departmentId
423            )
424        );
425    }
426
427    public function readQueueList(
428        $departmentId,
429        \DateTimeInterface $dateTime,
430        $resolveReferences = 0
431    ) {
432        $queueList = new \BO\Zmsentities\Collection\QueueList();
433        $department = $this->readEntity($departmentId, 2);
434
435        foreach ($department->getScopeList() as $scope) {
436            $scope = (new Scope())->readWithWorkstationCount($scope->id, $dateTime);
437            $scopeQueueList = (new Scope())
438                ->readQueueListWithWaitingTime($scope, $dateTime, $resolveReferences);
439            if (0 < $scopeQueueList->count()) {
440                $queueList->addList($scopeQueueList);
441            }
442        }
443        return $queueList;
444    }
445
446    public function removeCache($department)
447    {
448        if (!App::$cache || !isset($department->id)) {
449            return;
450        }
451
452        if (App::$cache->has("department-$department->id-0")) {
453            App::$cache->delete("department-$department->id-0");
454        }
455
456        if (App::$cache->has("department-$department->id-1")) {
457            App::$cache->delete("department-$department->id-1");
458        }
459
460        if (App::$cache->has("department-$department->id-2")) {
461            App::$cache->delete("department-$department->id-2");
462        }
463    }
464}