Lines 81.35% 144 / 177
Methods 72.72% 8 / 11
Classes 0.00% 0 / 1
Name Lines Methods CRAP
 readResponse 100.00% 30 / 30 100.00% 1 / 1 5
 getValidatedForm 81.13% 43 / 53 0.00% 0 / 1 3.06
 readSelectedProcessWithWaitingnumber 100.00% 4 / 4 100.00% 1 / 1 2
 getProcess 100.00% 3 / 3 100.00% 1 / 1 2
 writeQueuedProcess 100.00% 3 / 3 100.00% 1 / 1 1
 isOpened 100.00% 16 / 16 100.00% 1 / 1 4
 printProcessResponse 33.33% 9 / 27 0.00% 0 / 1 8.74
 [BO\Zmsadmin\BaseController] __invoke 100.00% 3 / 3 100.00% 1 / 1 1
 [BO\Zmsadmin\BaseController] getSchemaConstraintList 100.00% 8 / 8 100.00% 1 / 1 4
 [BO\Zmsadmin\BaseController] transformValidationErrors 61.53% 8 / 13 0.00% 0 / 1 15.69
 [BO\Zmsadmin\BaseController] handleEntityWrite 100.00% 17 / 17 100.00% 1 / 1 5
29class ProcessQueue extends BaseController
30{
31    /**
32     * @SuppressWarnings(Param)
33     *
34     * @return ResponseInterface
35     */
36    #[\Override]
37    public function readResponse(
38        RequestInterface $request,
39        ResponseInterface $response,
40        array $args
41    ) {
42        $workstation = \App::$http->readGetResult('/workstation/', ['resolveReferences' => 3])->getEntity();
43
44        $validator = $request->getAttribute('validator');
45        $selectedProcessId = $validator->getParameter('selectedprocess')->isNumber()->getValue();
46
47        if ($selectedProcessId) {
48            $process = $this->readSelectedProcessWithWaitingnumber($selectedProcessId);
49
50            if ($process && $validator->getParameter('print')->isNumber()->getValue()) {
51                return $this->printProcessResponse(
52                    $response,
53                    $process,
54                    $validator->getParameter('printType')->isString()->getValue(),
55                    $workstation->scope['provider']['id']
56                );
57            }
58        }
59
60        $input = $request->getParams();
61        $scope = AppointmentFormHelper::readSelectedScope($request, $workstation);
62        $process = $this->getProcess($input, $scope);
63        $validatedForm = static::getValidatedForm($validator, $process);
64        if ($validatedForm['failed']) {
65            return Render::withJson(
66                $response,
67                $validatedForm
68            );
69        }
70
71        $process = $this->writeQueuedProcess($input, $process);
72        return Render::withHtml(
73            $response,
74            'element/helper/messageHandler.twig',
75            array(
76                'selectedprocess' => $process,
77                'success' => 'process_queued'
78            )
79        );
80    }
81
82    /**
83     * @return (bool|mixed)[]
84     *
85     */
86    public static function getValidatedForm($validator, Process $process): array
87    {
88        $processValidator = new ProcessValidator($process);
89        $delegatedProcess = $processValidator->getDelegatedProcess();
90        $processValidator
91            ->validateName(
92                $validator->getParameter('familyName'),
93                $delegatedProcess->setter('clients', 0, 'familyName')
94            )
95            ->validateMail(
96                $validator->getParameter('email'),
97                $delegatedProcess->setter('clients', 0, 'email')
98            )
99            ->validateTelephone(
100                $validator->getParameter('telephone'),
101                $delegatedProcess->setter('clients', 0, 'telephone')
102            )
103            ->validateSurvey(
104                $validator->getParameter('surveyAccepted'),
105                $delegatedProcess->setter('clients', 0, 'surveyAccepted')
106            )
107            ->validateText(
108                $validator->getParameter('amendment'),
109                $delegatedProcess->setter('amendment')
110            )
111        ;
112
113        $scope = $process->getCurrentScope();
114        if ((int) $scope->getCustomTextfieldActivated()) {
115            $processValidator->validateCustomTextfield(
116                $validator->getParameter('customTextfield'),
117                $delegatedProcess->setter('customTextfield'),
118                (bool) (int) $scope->getCustomTextfieldRequired()
119            );
120        }
121        if ((int) $scope->getCustomTextfield2Activated()) {
122            $processValidator->validateCustomTextfield(
123                $validator->getParameter('customTextfield2'),
124                $delegatedProcess->setter('customTextfield2'),
125                (bool) (int) $scope->getCustomTextfield2Required()
126            );
127        }
128
129        $processValidator
130            ->validateReminderTimestamp(
131                $validator->getParameter('headsUpTime'),
132                $delegatedProcess->setter('reminderTimestamp'),
133                new Condition(
134                    $validator->getParameter('sendReminder')->isNumber()->isNotEqualTo(1)
135                )
136            )
137        ;
138        $processValidator->getCollection()->addValid(
139            $validator->getParameter('sendConfirmation')->isNumber(),
140            $validator->getParameter('sendReminder')->isNumber()
141        );
142
143        $form = $processValidator->getCollection()->getStatus(null, true);
144        $form['failed'] = $processValidator->getCollection()->hasFailed();
145        return $form;
146    }
147
148    protected function readSelectedProcessWithWaitingnumber($selectedProcessId)
149    {
150        $result = null;
151        if ($selectedProcessId) {
152            $result = \App::$http->readGetResult('/process/' . $selectedProcessId . '/')->getEntity();
153        }
154        return $result;
155    }
156
157    protected function getProcess($input, $scope)
158    {
159        $process = new Process();
160        $notice = (! $this->isOpened($scope)) ? 'Außerhalb der Ã–ffnungszeiten gebucht! ' : '';
161        return $process->withUpdatedData($input, \App::$now, $scope, $notice);
162    }
163
164    protected function writeQueuedProcess($input, $process): Process
165    {
166        $process = \App::$http->readPostResult('/workstation/process/waitingnumber/', $process)->getEntity();
167        AppointmentFormHelper::updateMail($input, $process);
168        return $process;
169    }
170
171    protected function isOpened($scope)
172    {
173        if ($scope->getResolveLevel() < 1) {
174            $scope =  \App::$http->readGetResult('/scope/' . $scope->getId() . '/', [
175                'resolveReferences' => 1,
176                'gql' => Helper\GraphDefaults::getScope()
177            ])
178                ->getEntity();
179        }
180        $isOpened = false;
181        try {
182            $isOpened = \App::$http
183                ->readGetResult('/scope/' . $scope->getId() . '/availability/', ['resolveReferences' => 0])
184                ->getCollection()
185                ->withScope($scope)
186                ->isOpened(\App::$now);
187        } catch (\BO\Zmsclient\Exception $exception) {
188            if ($exception->template == 'BO\\Zmsbackend\\Availability\\Exception\\AvailabilityNotFound') {
189                $isOpened = false;
190            }
191        }
192        return $isOpened;
193    }
194
195    private function printProcessResponse(
196        ResponseInterface $response,
197        Process $process,
198        ?string $printType = null,
199        ?int $providerId = null
200    ): ResponseInterface {
201        if ($printType === 'mail') {
202            $mergedMailTemplates = \App::$http->readGetResult('/merged-mailtemplates/' . $providerId . '/')
203                ->getCollection();
204
205            $templates = [];
206
207            foreach ($mergedMailTemplates as $template) {
208                $templates[$template->name] = $template->value;
209            };
210
211            $templateProvider = new MailTemplateArrayProvider();
212            $templateProvider->setTemplates($templates);
213
214            $config = \App::$http->readGetResult('/config/')->getEntity();
215
216            $mail = (new Mail())
217                ->setTemplateProvider($templateProvider)
218                ->toResolvedEntity($process, $config, 'appointment');
219
220            return Render::withHtml(
221                $response,
222                'page/printAppointmentMail.twig',
223                [
224                    'render' => $mail->getHtmlPart()
225                ]
226            );
227        }
228
229        return Render::withHtml(
230            $response,
231            'page/printWaitingNumber.twig',
232            array(
233                'title' => ($process->isWithAppointment()) ? 'Vorgangsnummer drucken' : 'Wartenummer drucken',
234                'process' => $process
235            )
236        );
237    }
238}

Inherited from BO\Zmsadmin\BaseController

21    public function __invoke(RequestInterface $request, ResponseInterface $response, array $args)
22    {
23        $request = $this->initRequest($request);
24        $noCacheResponse = \BO\Slim\Render::withLastModified($response, time(), '0');
25        return $this->readResponse($request, $noCacheResponse, $args);
26    }
41    public function getSchemaConstraintList($schema): array
42    {
43        $list = [];
44        $locale = \App::$language->getLocale();
45        foreach ($schema->properties as $key => $property) {
46            if (isset($property['x-locale'])) {
47                $constraints = $property['x-locale'][$locale];
48                if ($constraints) {
49                    $list[$key]['description'] = $constraints['messages'];
50                }
51            }
52        }
53        return $list;
54    }
65    protected function transformValidationErrors($errorData)
66    {
67        if (!is_array($errorData) && !($errorData instanceof \Traversable)) {
68            return [];
69        }
70        $transformed = [];
71        foreach ($errorData as $pointer => $item) {
72            // Extract field name from JSON pointer (e.g., "/id" -> "id", "/contact/email" -> "contact/email")
73            // If the key doesn't start with "/", it's already a field name, so use it as-is
74            $fieldName = (strpos($pointer, '/') === 0) ? ltrim($pointer, '/') : $pointer;
75            // Handle root level errors
76            if ($fieldName === '' || $fieldName === null) {
77                $fieldName = '_root';
78            }
79            // Ensure the item structure is correct (has 'messages' array)
80            if (is_array($item) && isset($item['messages'])) {
81                $transformed[$fieldName] = $item;
82            } elseif (is_array($item)) {
83                // If item is an array but doesn't have 'messages', wrap it
84                $transformed[$fieldName] = $item;
85            } else {
86                $transformed[$fieldName] = $item;
87            }
88        }
89        return $transformed;
90    }
99    protected function handleEntityWrite(callable $httpCall)
100    {
101        try {
102            return $httpCall();
103        } catch (\BO\Zmsclient\Exception $exception) {
104            if ('BO\Zmsentities\Exception\SchemaValidation' == $exception->template) {
105                return [
106                    'template' => 'exception/bo/zmsentities/exception/schemavalidation.twig',
107                    'include' => true,
108                    'data' => $this->transformValidationErrors($exception->data)
109                ];
110            }
111
112            $template = TwigExceptionHandler::getExceptionTemplate($exception);
113            if (
114                '' != $exception->template
115                && \App::$slim->getContainer()->get('view')->getLoader()->exists($template)
116            ) {
117                return [
118                    'template' => $template,
119                    'include' => true,
120                    'data' => $this->transformValidationErrors($exception->data)
121                ];
122            }
123
124            throw $exception;
125        }
126    }