Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
81.10% covered (warning)
81.10%
103 / 127
83.33% covered (warning)
83.33%
15 / 18
CRAP
0.00% covered (danger)
0.00%
0 / 1
Ticketprinter
81.10% covered (warning)
81.10%
103 / 127
83.33% covered (warning)
83.33%
15 / 18
43.27
0.00% covered (danger)
0.00%
0 / 1
 readEntity
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 readList
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 readByHash
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 readByButtonList
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 omitButtonsWithMissingScopeOrRequest
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 validateButton
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
3.07
 validateScopeButton
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
2
 validateRequestButton
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
12
 findRequest
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 hasScopeOrRequestButton
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 readExceptions
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 readWithContactData
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 readSingleScopeFromButtonList
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 writeEntityWithHash
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 writeEntity
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 readByOrganisationId
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 deleteEntity
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 readExpiredTicketprinterList
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace BO\Zmsbackend\Ticketprinter\Service;
4
5use BO\Zmsentities\Ticketprinter as Entity;
6use BO\Zmsentities\Collection\TicketprinterList as Collection;
7
8/**
9 *
10 * @SuppressWarnings(CouplingBetweenObjects)
11 */
12class Ticketprinter extends \BO\Zmsbackend\Base
13{
14    public function readEntity($itemId)
15    {
16        $query = new \BO\Zmsbackend\Ticketprinter\Repository\Ticketprinter(\BO\Zmsbackend\Query\Base::SELECT);
17        $query
18            ->addEntityMapping()
19            ->addConditionTicketprinterId($itemId);
20        $ticketprinter = $this->fetchOne($query, new Entity());
21        $ticketprinter = $this->readWithContactData($ticketprinter);
22        $ticketprinter->enabled = (1 == $ticketprinter->enabled);
23        return $ticketprinter;
24    }
25
26    protected function readList($statement)
27    {
28        $ticketprinterList = new Collection();
29        while ($entityData = $statement->fetch(\PDO::FETCH_ASSOC)) {
30            $entity = new Entity($entityData);
31            $ticketprinterList->addEntity($entity);
32        }
33        return $ticketprinterList;
34    }
35
36    public function readByHash($hash)
37    {
38        $query = new \BO\Zmsbackend\Ticketprinter\Repository\Ticketprinter(\BO\Zmsbackend\Query\Base::SELECT);
39        $query
40            ->addEntityMapping()
41            ->addConditionHash($hash);
42        $ticketprinter = $this->fetchOne($query, new Entity());
43        $ticketprinter = $this->readWithContactData($ticketprinter);
44        $ticketprinter->enabled = (1 == $ticketprinter->enabled);
45        return $ticketprinter;
46    }
47
48    public function readByButtonList(Entity $ticketprinter, \DateTimeImmutable $now)
49    {
50        if (count($ticketprinter->buttons) > 6) {
51            throw new \BO\Zmsbackend\Ticketprinter\Exception\TooManyButtons();
52        }
53
54        $ticketprinter->buttons = $this->omitButtonsWithMissingScopeOrRequest($ticketprinter->buttons, $now);
55        if (! $this->hasScopeOrRequestButton($ticketprinter)) {
56            throw new \BO\Zmsbackend\Ticketprinter\Exception\UnvalidButtonList();
57        }
58
59        $this->readExceptions($ticketprinter);
60        return $this->readWithContactData($ticketprinter);
61    }
62
63    /**
64     * @param iterable<int, array<string, mixed>> $buttons
65     * @return array<int, array<string, mixed>>
66     */
67    private function omitButtonsWithMissingScopeOrRequest(iterable $buttons, \DateTimeImmutable $now): array
68    {
69        $kept = [];
70        foreach ($buttons as $button) {
71            $button = $this->validateButton($button, $now);
72            if ($button !== null) {
73                $kept[] = $button;
74            }
75        }
76        return $kept;
77    }
78
79    /**
80     * @param array<string, mixed> $button
81     * @return array<string, mixed>|null
82     */
83    private function validateButton(array $button, \DateTimeImmutable $now): ?array
84    {
85        if (($button['type'] ?? '') === 'scope') {
86            return $this->validateScopeButton($button, $now);
87        }
88        if (($button['type'] ?? '') === 'request') {
89            return $this->validateRequestButton($button, $now);
90        }
91        return $button;
92    }
93
94    /**
95     * @param array<string, mixed> $button
96     * @return array<string, mixed>|null
97     */
98    private function validateScopeButton(array $button, \DateTimeImmutable $now): ?array
99    {
100        $scopeId = $button['scope']['id'];
101        $query = new \BO\Zmsbackend\Scope\Service\Scope();
102        $scope = $query->readWithWorkstationCount($scopeId, $now);
103        if (! $scope) {
104            \App::$log->warning('Ticketprinter: skip missing scope id', [
105                'scopeId' => $scopeId,
106            ]);
107            return null;
108        }
109        $button['scope'] = $scope;
110        $button['enabled'] = $query->readIsEnabled($scope->id, $now);
111        $button['name'] = $scope->getPreference('ticketprinter', 'buttonName');
112        return $button;
113    }
114
115    /**
116     * @param array<string, mixed> $button
117     * @return array<string, mixed>|null
118     */
119    private function validateRequestButton(array $button, \DateTimeImmutable $now): ?array
120    {
121        $parts = explode('-', (string) $button['request']['id']);
122        $scopeId = $parts[0];
123        $requestId = $parts[1] ?? '';
124        $scope = (new \BO\Zmsbackend\Scope\Service\Scope())->readWithWorkstationCount($scopeId, $now);
125        if (! $scope) {
126            \App::$log->warning('Ticketprinter: skip missing scope id', [
127                'scopeId' => $scopeId,
128            ]);
129            return null;
130        }
131        $request = $this->findRequest($requestId);
132        if (! $request) {
133            \App::$log->warning('Ticketprinter: skip missing request id', [
134                'requestId' => $requestId,
135            ]);
136            return null;
137        }
138        $button['scope'] = $scope;
139        $button['requestId'] = $requestId;
140        $button['enabled'] = (new \BO\Zmsbackend\Scope\Service\Scope())->readIsEnabled($scope->id, $now);
141        $button['name'] = $request->getProperty('name');
142        return $button;
143    }
144
145    private function findRequest(string $requestId): ?\BO\Zmsentities\Request
146    {
147        try {
148            return (new \BO\Zmsbackend\Request\Service\Request())->readEntity('dldb', $requestId);
149        } catch (\BO\Zmsbackend\Request\Exception\RequestNotFound) {
150            return null;
151        }
152    }
153
154    private function hasScopeOrRequestButton(Entity $ticketprinter): bool
155    {
156        foreach ($ticketprinter->buttons as $button) {
157            if (in_array($button['type'] ?? '', ['scope', 'request'], true)) {
158                return true;
159            }
160        }
161        return false;
162    }
163
164    protected function readExceptions(Entity $ticketprinter)
165    {
166        $query = new \BO\Zmsbackend\Scope\Service\Scope();
167        $scope = $this->readSingleScopeFromButtonList($ticketprinter);
168        if ($scope && ! $query->readIsGivenNumberInContingent($scope['id'])) {
169            throw new \BO\Zmsbackend\Scope\Exception\GivenNumberCountExceeded();
170        }
171    }
172
173    protected function readWithContactData(Entity $entity): Entity
174    {
175        $contact = new \BO\Zmsentities\Contact();
176
177        if (1 == $entity->getScopeList()->count()) {
178            $department = (new \BO\Zmsbackend\Department\Service\Department())->readByScopeId($entity->getScopeList()->getFirst()->id);
179            $contact->name = $department->name;
180        }
181
182        $entity->contact = $contact;
183        return $entity;
184    }
185
186    public function readSingleScopeFromButtonList(Entity $ticketprinter): \BO\Zmsentities\Scope|null
187    {
188        $scope = null;
189        if (1 == $ticketprinter->getScopeList()->count()) {
190            $scope = $ticketprinter->getScopeList()->getFirst();
191            $scope = (new \BO\Zmsbackend\Scope\Service\Scope())->readEntity($scope['id']);
192        }
193        return $scope;
194    }
195
196    public function writeEntityWithHash($organisationId, $ticketprinterName = '')
197    {
198        $query = new \BO\Zmsbackend\Ticketprinter\Repository\Ticketprinter(\BO\Zmsbackend\Query\Base::INSERT);
199        $ticketprinter = (new Entity())->getHashWith($organisationId);
200        $ticketprinter->name = $ticketprinterName;
201
202        $organisation = (new \BO\Zmsbackend\Organisation\Service\Organisation())->readEntity($organisationId);
203
204        $values = $query->reverseEntityMapping($ticketprinter, $organisation->id);
205        $owner = (new \BO\Zmsbackend\Owner\Service\Owner())->readByOrganisationId($organisationId);
206        $values['kundenid'] = $owner->id;
207        $query->addValues($values);
208        $this->writeItem($query);
209        $lastInsertId = $this->getWriter()->lastInsertId();
210        return $this->readEntity($lastInsertId);
211    }
212
213    public function writeEntity(Entity $entity, $organisationId)
214    {
215        $query = new \BO\Zmsbackend\Ticketprinter\Repository\Ticketprinter(\BO\Zmsbackend\Query\Base::INSERT);
216        $values = $query->reverseEntityMapping($entity, $organisationId);
217
218        $owner = (new \BO\Zmsbackend\Owner\Service\Owner())->readByOrganisationId($organisationId);
219        $values['kundenid'] = $owner->id;
220
221        $query->addValues($values);
222        $this->writeItem($query);
223        $lastInsertId = $this->getWriter()->lastInsertId();
224        return $this->readEntity($lastInsertId);
225    }
226
227    public function readByOrganisationId($organisationId)
228    {
229        $query = new \BO\Zmsbackend\Ticketprinter\Repository\Ticketprinter(\BO\Zmsbackend\Query\Base::SELECT);
230        $query
231            ->addEntityMapping()
232            ->addConditionOrganisationId($organisationId);
233        $statement = $this->fetchStatement($query);
234        return $this->readList($statement);
235    }
236
237    public function deleteEntity($itemId)
238    {
239        $query =  new \BO\Zmsbackend\Ticketprinter\Repository\Ticketprinter(\BO\Zmsbackend\Query\Base::DELETE);
240        $query->addConditionTicketprinterId($itemId);
241        return $this->deleteItem($query);
242    }
243
244    public function readExpiredTicketprinterList($expirationDate): Collection
245    {
246        $selectQuery = new \BO\Zmsbackend\Ticketprinter\Repository\Ticketprinter(\BO\Zmsbackend\Query\Base::SELECT);
247        $selectQuery
248            ->addEntityMapping()
249            ->addConditionDeleteInterval($expirationDate);
250        $statement = $this->fetchStatement($selectQuery);
251        return $this->readList($statement);
252    }
253}