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