Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
71.43% covered (warning)
71.43%
45 / 63
25.00% covered (danger)
25.00%
1 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ProcessConfirm
71.43% covered (warning)
71.43%
45 / 63
25.00% covered (danger)
25.00%
1 / 4
23.74
0.00% covered (danger)
0.00%
0 / 1
 readResponse
95.83% covered (success)
95.83%
23 / 24
0.00% covered (danger)
0.00%
0 / 1
3
 writeMails
8.33% covered (danger)
8.33%
1 / 12
0.00% covered (danger)
0.00%
0 / 1
9.93
 updateOverallCalendar
72.73% covered (warning)
72.73%
16 / 22
0.00% covered (danger)
0.00%
0 / 1
7.99
 testProcessData
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
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\Zmsdb\Process;
12use BO\Zmsdb\Mail;
13use BO\Zmsdb\Config;
14use BO\Mellon\Validator;
15
16/**
17 * @SuppressWarnings(CouplingBetweenObjects)
18 */
19class ProcessConfirm extends BaseController
20{
21    /**
22     * @SuppressWarnings(Param)
23     * @return String
24     */
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::setCriticalReadSession();
31
32        $resolveReferences = Validator::param('resolveReferences')->isNumber()->setDefault(3)->getValue();
33        $input = Validator::input()->isJson()->assertValid()->getValue();
34        $entity = new \BO\Zmsentities\Process($input);
35        $entity->testValid();
36        $this->testProcessData($entity);
37
38        $userAccount = (new Helper\User($request))->readWorkstation()->getUseraccount();
39        $process = (new Process())->readEntity($entity->id, $entity->authKey);
40        if ('preconfirmed' != $process->status && 'reserved' != $process->status) {
41            throw new Exception\Process\ProcessNotPreconfirmedAnymore();
42        }
43
44        $this->updateOverallCalendar($process);
45
46        $process = (new Process())->updateProcessStatus(
47            $process,
48            'confirmed',
49            \App::$now,
50            $resolveReferences,
51            $userAccount
52        );
53        $this->writeMails($request, $process);
54        $message = Response\Message::create($request);
55        $message->data = $process;
56
57        $response = Render::withLastModified($response, time(), '0');
58        $response = Render::withJson($response, $message->setUpdatedMetaData(), $message->getStatuscode());
59        return $response;
60    }
61    protected function writeMails($request, $process)
62    {
63        if ($process->hasScopeAdmin() && $process->sendAdminMailOnConfirmation()) {
64            $authority = $request->getUri()->getAuthority();
65            $validator = $request->getAttribute('validator');
66            $initiator = $validator->getParameter('initiator')
67                ->isString()
68                ->setDefault("$authority API-User")
69                ->getValue();
70            $config = (new Config())->readEntity();
71            $mail = (new \BO\Zmsentities\Mail())
72            ->setTemplateProvider(new \BO\Zmsdb\Helper\MailTemplateProvider($process))
73            ->toResolvedEntity($process, $config, 'appointment', $initiator);
74            (new Mail())->writeInQueueWithAdmin($mail, \App::$now);
75        }
76    }
77
78    private function updateOverallCalendar(\BO\Zmsentities\Process $process): void
79    {
80        $appointment = $process->getFirstAppointment();
81        if (!$appointment || !$appointment->date || !$appointment->scope) {
82             \App::$log->warning('process.confirm.skipped_no_appointment', [
83                 'process_id' => $process->id,
84             ]);
85            return;
86        }
87
88        $scopeId = (int) $appointment->scope->id;
89
90        $time = (new \DateTimeImmutable('@' . $appointment->date))
91            ->setTimezone(new \DateTimeZone(\BO\Zmsdb\Connection\Select::$connectionTimezone))
92            ->format('Y-m-d H:i:00');
93
94        $duration = 0;
95        foreach ($process->requests as $req) {
96            if (!empty($req['data']['duration'])) {
97                $duration += (int) $req['data']['duration'];
98            }
99        }
100
101        $duration = $duration ?: 5;
102        $slotUnits = (int) ceil($duration / 5);
103
104        (new \BO\Zmsdb\OverallCalendar())->book(
105            $scopeId,
106            $time,
107            $process->id,
108            $slotUnits
109        );
110    }
111
112    protected function testProcessData($entity)
113    {
114        $authCheck = (new Process())->readAuthKeyByProcessId($entity->id);
115        if (! $authCheck) {
116            throw new Exception\Process\ProcessNotFound();
117        } elseif ($authCheck['authKey'] != $entity->authKey && $authCheck['authName'] != $entity->authKey) {
118            throw new Exception\Process\AuthKeyMatchFailed();
119        }
120    }
121}