Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
84.62% covered (warning)
84.62%
66 / 78
25.00% covered (danger)
25.00%
1 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
WorkstationProcess
84.62% covered (warning)
84.62%
66 / 78
25.00% covered (danger)
25.00%
1 / 4
23.76
0.00% covered (danger)
0.00%
0 / 1
 readResponse
82.98% covered (warning)
82.98%
39 / 47
0.00% covered (danger)
0.00%
0 / 1
7.24
 validateProcessCurrentDate
88.89% covered (warning)
88.89%
16 / 18
0.00% covered (danger)
0.00%
0 / 1
7.07
 testProcessData
66.67% covered (warning)
66.67%
4 / 6
0.00% covered (danger)
0.00%
0 / 1
3.33
 testProcess
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2
3/**
4 * @package ZMS API
5 * @copyright BerlinOnline Stadtportal GmbH & Co. KG
6 **/
7
8namespace BO\Zmsapi;
9
10use BO\Slim\Render;
11use BO\Mellon\Validator;
12use BO\Zmsdb\Workstation;
13use BO\Zmsdb\Process as Query;
14
15/**
16 * @SuppressWarnings(Coupling)
17 */
18class WorkstationProcess extends BaseController
19{
20    /**
21     * @SuppressWarnings(Param)
22     * @return \Psr\Http\Message\ResponseInterface
23     */
24    #[\Override]
25    public function readResponse(
26        \Psr\Http\Message\RequestInterface $request,
27        \Psr\Http\Message\ResponseInterface $response,
28        array $args
29    ) {
30        \BO\Zmsdb\Connection\Select::setTransaction(true);
31        \BO\Zmsdb\Connection\Select::getWriteConnection();
32
33        try {
34            $workstation = (new Helper\User($request, 1))->checkPermissions();
35            $input = Validator::input()->isJson()->assertValid()->getValue();
36            $allowClusterWideCall = Validator::param('allowClusterWideCall')->isBool()->setDefault(true)->getValue();
37            if ($workstation->process && $workstation->process->hasId() && $workstation->process->getId() != $input['id']) {
38                $exception = new Exception\Workstation\WorkstationHasAssignedProcess();
39                $exception->data = ['process' => $workstation->process];
40                throw $exception;
41            }
42
43            $entity = new \BO\Zmsentities\Process($input);
44            $entity->testValid();
45            $this->testProcessData($entity);
46            $process = (new Query())->readEntity($entity['id'], $entity['authKey'], 1);
47
48            $this->validateProcessCurrentDate($process);
49
50            $previousStatus = $process->status;
51            $process->status = 'called';
52            $process = (new Query())->updateEntity(
53                $process,
54                \App::$now,
55                0,
56                $previousStatus,
57                $workstation->getUseraccount()
58            );
59
60            $process = new \BO\Zmsentities\Process($input);
61            $this->testProcess($process, $workstation, $allowClusterWideCall);
62            $process->setCallTime(\App::$now);
63            $process->queue['callCount']++;
64
65            $process->status = 'called';
66
67            $workstation->process = (new Workstation())->writeAssignedProcess($workstation, $process, \App::$now);
68            \BO\Zmsdb\Connection\Select::writeCommit();
69            $message = Response\Message::create($request);
70            $message->data = $workstation;
71
72            $response = Render::withLastModified($response, time(), '0');
73            $response = Render::withJson($response, $message->setUpdatedMetaData(), $message->getStatuscode());
74            return $response;
75        } catch (\DomainException $e) {
76            \BO\Zmsdb\Connection\Select::writeRollback();
77
78            if ($e->getMessage() === 'PROCESS_ALREADY_ASSIGNED') {
79                $exception = new Exception\Process\ProcessAlreadyCalled();
80                $exception->data = [
81                    'processId' => $input['id'] ?? null
82                ];
83                throw $exception;
84            }
85
86            throw $e;
87        } catch (\Throwable $e) {
88            \BO\Zmsdb\Connection\Select::writeRollback();
89            throw $e;
90        }
91    }
92
93    protected function validateProcessCurrentDate($process)
94    {
95        if (!$process || !$process->hasId() || !$process->isWithAppointment()) {
96            return;
97        }
98
99        $appointment = $process->getFirstAppointment();
100        if (!$appointment || !$appointment->date) {
101            return;
102        }
103
104        $now = \App::getNow();
105        $today = $now->setTime(0, 0, 0);
106        $appointmentDateTime = new \DateTimeImmutable();
107        $appointmentDateTime = $appointmentDateTime->setTimestamp($appointment->date);
108        $appointmentDate = $appointmentDateTime->setTime(0, 0, 0);
109
110        if ($appointmentDate != $today) {
111            $exception = new Exception\Process\ProcessNotCurrentDate();
112            $exception->data = [
113                'processId' => $process->getId(),
114                'appointmentDate' => $appointmentDateTime->format('d.m.Y'),
115                'appointmentTime' => $appointmentDateTime->format('H:i') . ' Uhr'
116            ];
117            throw $exception;
118        }
119    }
120
121    protected function testProcessData($entity)
122    {
123        $authCheck = (new Query())->readAuthKeyByProcessId($entity->id);
124        if (! $authCheck) {
125            throw new Exception\Process\ProcessNotFound();
126        } elseif ($authCheck['authKey'] !== $entity->authKey) {
127            throw new Exception\Process\AuthKeyMatchFailed();
128        }
129        Helper\Matching::testCurrentScopeHasRequest($entity);
130    }
131
132    protected function testProcess($process, $workstation, $allowClusterWideCall)
133    {
134        if ('called' == $process->status || 'processing' == $process->status) {
135            throw new Exception\Process\ProcessAlreadyCalled();
136        }
137        if ('reserved' == $process->getStatus()) {
138            throw new Exception\Process\ProcessReservedNotCallable();
139        }
140        if (! $allowClusterWideCall) {
141            $workstation->validateProcessScopeAccess($workstation->getScopeList(), $process);
142        }
143        $process->testValid();
144    }
145}