Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
98.25% |
168 / 171 |
|
57.14% |
4 / 7 |
CRAP | |
0.00% |
0 / 1 |
ExchangeWaitingscope | |
98.25% |
168 / 171 |
|
57.14% |
4 / 7 |
21 | |
0.00% |
0 / 1 |
readEntity | |
100.00% |
43 / 43 |
|
100.00% |
1 / 1 |
4 | |||
readSubjectList | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
2 | |||
readPeriodList | |
100.00% |
22 / 22 |
|
100.00% |
1 / 1 |
4 | |||
readByDateTime | |
100.00% |
19 / 19 |
|
100.00% |
1 / 1 |
2 | |||
writeWaitingTimeCalculated | |
95.24% |
20 / 21 |
|
0.00% |
0 / 1 |
3 | |||
writeWaitingTime | |
96.30% |
26 / 27 |
|
0.00% |
0 / 1 |
4 | |||
updateWaitingStatistics | |
96.43% |
27 / 28 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace BO\Zmsdb; |
4 | |
5 | use BO\Zmsentities\Exchange; |
6 | |
7 | class ExchangeWaitingscope extends Base implements Interfaces\ExchangeSubject |
8 | { |
9 | public function readEntity( |
10 | $subjectid, |
11 | \DateTimeInterface $datestart, |
12 | \DateTimeInterface $dateend, |
13 | $period = 'day' |
14 | ) { |
15 | $scope = (new Scope())->readEntity($subjectid); |
16 | $entity = new Exchange(); |
17 | $entity['title'] = "Wartestatistik " . $scope->contact->name . " " . $scope->shortName; |
18 | $entity->setPeriod($datestart, $dateend, $period); |
19 | $entity->addDictionaryEntry('subjectid', 'string', 'ID of a scope', 'scope.id'); |
20 | $entity->addDictionaryEntry('date', 'string', 'date of report entry'); |
21 | $entity->addDictionaryEntry('hour', 'string', 'hour of report entry'); |
22 | $entity->addDictionaryEntry('waitingcount', 'number', 'amount of waiting spontaneous clients'); |
23 | $entity->addDictionaryEntry('waitingtime', 'number', 'real waitingtime for spontaneous clients'); |
24 | $entity->addDictionaryEntry('waytime', 'number', 'real waytime for spontaneous clients'); |
25 | $entity->addDictionaryEntry('waitingcalculated', 'number', 'calculated waitingtime for spontaneous clients'); |
26 | $entity->addDictionaryEntry('waitingcount_termin', 'number', 'amount of waiting clients with termin'); |
27 | $entity->addDictionaryEntry('waitingtime_termin', 'number', 'real waitingtime with termin'); |
28 | $entity->addDictionaryEntry('waytime_termin', 'number', 'real waytime with appointment'); |
29 | $entity->addDictionaryEntry('waitingcalculated_termin', 'number', 'calculated waitingtime with termin'); |
30 | $subjectIdList = explode(',', $subjectid); |
31 | |
32 | foreach ($subjectIdList as $subjectid) { |
33 | $raw = $this |
34 | ->getReader() |
35 | ->fetchAll( |
36 | constant("\BO\Zmsdb\Query\ExchangeWaitingscope::QUERY_READ_" . strtoupper($period)), |
37 | [ |
38 | 'scopeid' => $subjectid, |
39 | 'datestart' => $datestart->format('Y-m-d'), |
40 | 'dateend' => $dateend->format('Y-m-d') |
41 | ] |
42 | ); |
43 | |
44 | foreach ($raw as $entry) { |
45 | foreach (range(0, 23) as $hour) { |
46 | $entity->addDataSet([ |
47 | $subjectid, |
48 | $entry['datum'], |
49 | $hour, |
50 | $entry[sprintf('wartende_ab_%02s_spontan', $hour)], |
51 | $entry[sprintf('echte_zeit_ab_%02s_spontan', $hour)], |
52 | $entry[sprintf('wegezeit_ab_%02s_spontan', $hour)], |
53 | $entry[sprintf('zeit_ab_%02s_spontan', $hour)], |
54 | $entry[sprintf('wartende_ab_%02s_termin', $hour)], |
55 | $entry[sprintf('echte_zeit_ab_%02s_termin', $hour)], |
56 | $entry[sprintf('wegezeit_ab_%02s_termin', $hour)], |
57 | $entry[sprintf('zeit_ab_%02s_termin', $hour)], |
58 | ]); |
59 | } |
60 | } |
61 | } |
62 | return $entity; |
63 | } |
64 | |
65 | public function readSubjectList() |
66 | { |
67 | $raw = $this->getReader()->fetchAll(Query\ExchangeWaitingscope::QUERY_SUBJECTS, []); |
68 | $entity = new Exchange(); |
69 | $entity['title'] = "Wartestatistik"; |
70 | $entity->setPeriod(new \DateTimeImmutable(), new \DateTimeImmutable()); |
71 | $entity->addDictionaryEntry('subject', 'string', 'Standort ID', 'scope.id'); |
72 | $entity->addDictionaryEntry('periodstart', 'string', 'Datum von'); |
73 | $entity->addDictionaryEntry('periodend', 'string', 'Datum bis'); |
74 | $entity->addDictionaryEntry('description', 'string', 'Standort Beschreibung'); |
75 | foreach ($raw as $entry) { |
76 | $entity->addDataSet(array_values($entry)); |
77 | } |
78 | return $entity; |
79 | } |
80 | |
81 | public function readPeriodList($subjectid, $period = 'day') |
82 | { |
83 | $scope = (new Scope())->readEntity($subjectid); |
84 | $entity = new Exchange(); |
85 | $entity['title'] = "Wartestatistik " . $scope->contact->name . " " . $scope->shortName; |
86 | $entity->setPeriod(new \DateTimeImmutable(), new \DateTimeImmutable(), $period); |
87 | $entity->addDictionaryEntry('period'); |
88 | |
89 | $montsList = $this->getReader()->fetchAll( |
90 | constant("\BO\Zmsdb\Query\ExchangeWaitingscope::QUERY_PERIODLIST_MONTH"), |
91 | [ |
92 | 'scopeid' => $subjectid, |
93 | ] |
94 | ); |
95 | $raw = []; |
96 | foreach ($montsList as $month) { |
97 | $date = new \DateTimeImmutable($month['date']); |
98 | $raw[$date->format('Y')][] = $month['date']; |
99 | rsort($raw[$date->format('Y')]); |
100 | } |
101 | krsort($raw); |
102 | |
103 | foreach ($raw as $year => $months) { |
104 | $entity->addDataSet([$year]); |
105 | foreach ($months as $month) { |
106 | $entity->addDataSet([$month]); |
107 | } |
108 | } |
109 | return $entity; |
110 | } |
111 | |
112 | /** |
113 | * fetch entry by scope and date or create an entry, if it does not exists |
114 | * the returned entry is save for updating |
115 | */ |
116 | public function readByDateTime( |
117 | \BO\Zmsentities\Scope $scope, |
118 | \DateTimeInterface $date, |
119 | bool $isWithAppointment = false |
120 | ) { |
121 | $sql = Query\ExchangeWaitingscope::getQuerySelectByDateTime($date, $isWithAppointment); |
122 | $existingEntry = $this->getReader()->fetchOne( |
123 | $sql, |
124 | [ |
125 | 'scopeid' => $scope->id, |
126 | 'date' => $date->format('Y-m-d'), |
127 | 'hour' => $date->format('H') |
128 | ] |
129 | ); |
130 | if (!$existingEntry) { |
131 | $this->perform( |
132 | Query\ExchangeWaitingscope::QUERY_CREATE, |
133 | [ |
134 | 'scopeid' => $scope->id, |
135 | 'date' => $date->format('Y-m-d'), |
136 | ] |
137 | ); |
138 | $existingEntry = $this->readByDateTime($scope, $date, $isWithAppointment); |
139 | } |
140 | return $existingEntry; |
141 | } |
142 | |
143 | /** |
144 | * Write calculated waiting time and count of queued processes into statistic |
145 | */ |
146 | public function writeWaitingTimeCalculated( |
147 | \BO\Zmsentities\Scope $scope, |
148 | \DateTimeInterface $now, |
149 | bool $isWithAppointment = false |
150 | ) { |
151 | if ($now > (new \DateTime())) { |
152 | return $this; |
153 | } |
154 | |
155 | $queueList = (new Scope())->readQueueListWithWaitingTime($scope, $now); |
156 | |
157 | $existingEntry = $this->readByDateTime($scope, $now, $isWithAppointment); |
158 | $queueEntry = $queueList->getFakeOrLastWaitingnumber(); |
159 | $waitingCalculated = $existingEntry['waitingcalculated'] > $queueEntry['waitingTimeEstimate'] ? |
160 | $existingEntry['waitingcalculated'] |
161 | : $queueEntry['waitingTimeEstimate']; |
162 | |
163 | $this->perform( |
164 | Query\ExchangeWaitingscope::getQueryUpdateByDateTime($now, $isWithAppointment), |
165 | [ |
166 | 'waitingcalculated' => $waitingCalculated, |
167 | 'waitingcount' => $existingEntry['waitingcount'], |
168 | 'waitingtime' => $existingEntry['waitingtime'], |
169 | 'waytime' => $existingEntry['waytime'], |
170 | 'scopeid' => $scope->id, |
171 | 'date' => $now->format('Y-m-d'), |
172 | 'hour' => $now->format('H') |
173 | ] |
174 | ); |
175 | return $this; |
176 | } |
177 | |
178 | /** |
179 | * Write real waiting time into statistics |
180 | */ |
181 | public function writeWaitingTime( |
182 | \BO\Zmsentities\Process $process, |
183 | \DateTimeInterface $now |
184 | ) { |
185 | if ($now > (new \DateTime())) { |
186 | return $this; |
187 | } |
188 | |
189 | $waitingTime = $process->getWaitedMinutes($now); |
190 | $wayTime = $process->getWayMinutes($now); |
191 | $existingEntry = $this->readByDateTime( |
192 | $process->scope, |
193 | $process->getArrivalTime($now), |
194 | $process->isWithAppointment() |
195 | ); |
196 | $waitingTime = $existingEntry['waitingtime'] > $waitingTime ? $existingEntry['waitingtime'] : $waitingTime; |
197 | $wayTime = $existingEntry['waytime'] > $wayTime ? $existingEntry['waytime'] : $wayTime; |
198 | $this->perform( |
199 | Query\ExchangeWaitingscope::getQueryUpdateByDateTime( |
200 | $process->getArrivalTime($now), |
201 | $process->isWithAppointment() |
202 | ), |
203 | [ |
204 | 'waitingcalculated' => $existingEntry['waitingcalculated'], |
205 | 'waitingcount' => $existingEntry['waitingcount'], |
206 | 'waitingtime' => $waitingTime, |
207 | 'waytime' => $wayTime, |
208 | 'scopeid' => $process->scope->id, |
209 | 'date' => $now->format('Y-m-d'), |
210 | 'hour' => $now->format('H') |
211 | ] |
212 | ); |
213 | return $this; |
214 | } |
215 | |
216 | public function updateWaitingStatistics( |
217 | \BO\Zmsentities\Process $process, |
218 | \DateTimeInterface $now |
219 | ) { |
220 | if ($now > (new \DateTime())) { |
221 | return $this; |
222 | } |
223 | |
224 | $newWaitingTime = $process->getWaitedMinutes($now); |
225 | $newWayTime = $process->getWayMinutes($now); |
226 | |
227 | $existingEntry = $this->readByDateTime( |
228 | $process->scope, |
229 | $process->getArrivalTime($now), |
230 | $process->isWithAppointment() |
231 | ); |
232 | |
233 | $waitingCount = $existingEntry['waitingcount'] + 1; |
234 | |
235 | $averageWaitingTime = ($existingEntry['waitingtime'] * $existingEntry['waitingcount'] + $newWaitingTime) / $waitingCount; |
236 | $averageWayTime = ($existingEntry['waytime'] * $existingEntry['waitingcount'] + $newWayTime) / $waitingCount; |
237 | |
238 | $this->perform( |
239 | Query\ExchangeWaitingscope::getQueryUpdateByDateTime( |
240 | $process->getArrivalTime($now), |
241 | $process->isWithAppointment() |
242 | ), |
243 | [ |
244 | 'waitingcalculated' => $existingEntry['waitingcalculated'], |
245 | 'waitingcount' => $waitingCount, |
246 | 'waitingtime' => $averageWaitingTime, |
247 | 'waytime' => $averageWayTime, |
248 | 'scopeid' => $process->scope->id, |
249 | 'date' => $now->format('Y-m-d'), |
250 | 'hour' => $now->format('H') |
251 | ] |
252 | ); |
253 | |
254 | return $this; |
255 | } |
256 | } |