Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
73.33% covered (warning)
73.33%
44 / 60
40.00% covered (danger)
40.00%
2 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
ProcessConfirm
73.33% covered (warning)
73.33%
44 / 60
40.00% covered (danger)
40.00%
2 / 5
16.20
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
 updateOverviewCalendar
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
1
 testProcessData
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 validateProcessLimits
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
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 \Psr\Http\Message\ResponseInterface
24     */
25    #[\Override]
26    public function readResponse(
27        \Psr\Http\Message\RequestInterface $request,
28        \Psr\Http\Message\ResponseInterface $response,
29        array $args
30    ) {
31        \BO\Zmsdb\Connection\Select::setCriticalReadSession();
32
33        $resolveReferences = Validator::param('resolveReferences')->isNumber()->setDefault(3)->getValue();
34        $input = Validator::input()->isJson()->assertValid()->getValue();
35        $entity = new \BO\Zmsentities\Process($input);
36        $entity->testValid();
37        $this->testProcessData($entity);
38
39        $userAccount = (new Helper\User($request))->readWorkstation()->getUseraccount();
40        $process = (new Process())->readEntity($entity->id, $entity->authKey, 2);
41
42        //$this->validateProcessLimits($process); Should be moved to zmscitizenapi.
43        if ('preconfirmed' != $process->status && 'reserved' != $process->status) {
44            throw new Exception\Process\ProcessNotPreconfirmedAnymore();
45        }
46
47        $this->updateOverviewCalendar($process);
48
49        $process = (new Process())->updateProcessStatus(
50            $process,
51            'confirmed',
52            \App::$now,
53            $resolveReferences,
54            $userAccount
55        );
56        $this->writeMails($request, $process);
57        $message = Response\Message::create($request);
58        $message->data = $process;
59
60        $response = Render::withLastModified($response, time(), '0');
61        $response = Render::withJson($response, $message->setUpdatedMetaData(), $message->getStatuscode());
62        return $response;
63    }
64    protected function writeMails($request, $process)
65    {
66        if ($process->hasScopeAdmin() && $process->sendAdminMailOnConfirmation()) {
67            $authority = $request->getUri()->getAuthority();
68            $validator = $request->getAttribute('validator');
69            $initiator = $validator->getParameter('initiator')
70                ->isString()
71                ->setDefault("$authority API-User")
72                ->getValue();
73            $config = (new Config())->readEntity();
74            $mail = (new \BO\Zmsentities\Mail())
75            ->setTemplateProvider(new \BO\Zmsdb\Helper\MailTemplateProvider($process))
76            ->toResolvedEntity($process, $config, 'appointment', $initiator);
77            (new Mail())->writeInQueueWithAdmin($mail, \App::$now);
78        }
79    }
80
81    private function updateOverviewCalendar(\BO\Zmsentities\Process $process): void
82    {
83        $appointment = $process->getFirstAppointment();
84        $scopeId = (int) $appointment->scope->id;
85
86        $timezone = new \DateTimeZone(\BO\Zmsdb\Connection\Select::$connectionTimezone);
87        $startsAt = (new \DateTimeImmutable('@' . $appointment->date))->setTimezone($timezone);
88
89        $slotCount = (int)($appointment->slotCount ?? 0);
90        $slotTimeInMinutes = (int)($appointment->availability->slotTimeInMinutes ?? 0);
91        $durationMinutes   = $slotCount * $slotTimeInMinutes;
92
93        $endsAt = $startsAt->modify('+' . $durationMinutes . ' minutes');
94
95        (new \BO\Zmsdb\OverviewCalendar())->insert(
96            $scopeId,
97            (int) $process->id,
98            'confirmed',
99            $startsAt,
100            $endsAt
101        );
102    }
103
104    protected function testProcessData($entity)
105    {
106        $authCheck = (new Process())->readAuthKeyByProcessId($entity->id);
107        if (! $authCheck) {
108            throw new Exception\Process\ProcessNotFound();
109        } elseif ($authCheck['authKey'] !== $entity->authKey) {
110            throw new Exception\Process\AuthKeyMatchFailed();
111        }
112    }
113
114    protected function validateProcessLimits(\BO\Zmsentities\Process $process)
115    {
116        if (! (new Process())->isAppointmentSlotCountAllowed($process)) {
117            throw new Exception\Process\MoreThanAllowedSlotsPerAppointment();
118        }
119
120        if (! (new Process())->isServiceQuantityAllowed($process)) {
121            throw new Exception\Process\MoreThanAllowedQuantityPerService();
122        }
123    }
124}