Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
84.42% covered (warning)
84.42%
65 / 77
25.00% covered (danger)
25.00%
1 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
WorkstationProcess
84.42% covered (warning)
84.42%
65 / 77
25.00% covered (danger)
25.00%
1 / 4
23.83
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.24% covered (warning)
88.24%
15 / 17
0.00% covered (danger)
0.00%
0 / 1
7.08
 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\Zmsbackend\Workstation\Api;
9
10use BO\Slim\Render;
11use BO\Mellon\Validator;
12use BO\Zmsbackend\Workstation\Service\Workstation;
13use BO\Zmsbackend\Process\Service\Process as Query;
14
15/**
16 * @SuppressWarnings(Coupling)
17 */
18class WorkstationProcess extends \BO\Zmsbackend\Api\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\Zmsbackend\Connection\Select::setTransaction(true);
31        \BO\Zmsbackend\Connection\Select::getWriteConnection();
32
33        try {
34            $workstation = (new \BO\Zmsbackend\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 \BO\Zmsbackend\Workstation\Exception\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 \BO\Zmsbackend\Workstation\Service\Workstation())->writeAssignedProcess($workstation, $process, \App::$now);
68            \BO\Zmsbackend\Connection\Select::writeCommit();
69            $message = \BO\Zmsbackend\Api\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\Zmsbackend\Connection\Select::writeRollback();
77
78            if ($e->getMessage() === 'PROCESS_ALREADY_ASSIGNED') {
79                $exception = new \BO\Zmsbackend\Process\Exception\ProcessAlreadyCalled();
80                $exception->data = [
81                    'processId' => $input['id'] ?? null
82                ];
83                throw $exception;
84            }
85
86            throw $e;
87        } catch (\Throwable $e) {
88            \BO\Zmsbackend\Connection\Select::writeRollback();
89            throw $e;
90        }
91    }
92
93    /**
94     * @return void
95     */
96    protected function validateProcessCurrentDate(\BO\Zmsentities\Process|null $process)
97    {
98        if (!$process || !$process->hasId() || !$process->isWithAppointment()) {
99            return;
100        }
101
102        $appointment = $process->getFirstAppointment();
103        if (!$appointment || !$appointment['date']) {
104            return;
105        }
106
107        $now = \App::getNow();
108        $today = $now->setTime(0, 0, 0);
109        $appointmentDateTime = $appointment->toDateTime();
110        $appointmentDate = $appointmentDateTime->setTime(0, 0, 0);
111
112        if ($appointmentDate != $today) {
113            $exception = new \BO\Zmsbackend\Process\Exception\ProcessNotCurrentDate();
114            $exception->data = [
115                'processId' => $process->getId(),
116                'appointmentDate' => $appointmentDateTime->format('d.m.Y'),
117                'appointmentTime' => $appointmentDateTime->format('H:i') . ' Uhr'
118            ];
119            throw $exception;
120        }
121    }
122
123    /**
124     * @return void
125     */
126    protected function testProcessData(\BO\Zmsentities\Process $entity)
127    {
128        $authCheck = (new Query())->readAuthKeyByProcessId($entity->id);
129        if (! $authCheck) {
130            throw new \BO\Zmsbackend\Process\Exception\ProcessNotFound();
131        } elseif ($authCheck['authKey'] !== $entity->authKey) {
132            throw new \BO\Zmsbackend\Process\Exception\AuthKeyMatchFailed();
133        }
134        \BO\Zmsbackend\Helper\Matching::testCurrentScopeHasRequest($entity);
135    }
136
137    /**
138     * @return void
139     */
140    protected function testProcess(\BO\Zmsentities\Process $process, $workstation, $allowClusterWideCall)
141    {
142        if ('called' == $process->status || 'processing' == $process->status) {
143            throw new \BO\Zmsbackend\Process\Exception\ProcessAlreadyCalled();
144        }
145        if ('reserved' == $process->getStatus()) {
146            throw new \BO\Zmsbackend\Process\Exception\ProcessReservedNotCallable();
147        }
148        if (! $allowClusterWideCall) {
149            $workstation->validateProcessScopeAccess($workstation->getScopeList(), $process);
150        }
151        $process->testValid();
152    }
153}