Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.30% covered (success)
97.30%
36 / 37
87.50% covered (success)
87.50%
7 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
FiscalController
97.30% covered (success)
97.30%
36 / 37
87.50% covered (success)
87.50%
7 / 8
14
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 respond
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 respondDownload
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 extractUploadedFileData
91.67% covered (success)
91.67%
11 / 12
0.00% covered (danger)
0.00%
0 / 1
3.01
 authorization
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 validate
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 download
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 preview
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5use Psr\Http\Message\ResponseInterface as Response;
6use Psr\Http\Message\ServerRequestInterface as Request;
7use UppServices\FiscalService;
8
9/**
10 * Slim controller for fiscal endpoints.
11 * Delegates to FiscalService.
12 */
13class FiscalController
14{
15    private readonly FiscalService $fiscalService;
16
17    public function __construct(FiscalService $fiscalService)
18    {
19        $this->fiscalService = $fiscalService;
20    }
21
22    private function respond(Response $response, array $result): Response
23    {
24        $response->getBody()->write($result['output']);
25        return $response->withHeader('Content-Type', $result['contentType']);
26    }
27
28    private function respondDownload(Response $response, array $result): Response
29    {
30        $response->getBody()->write($result['output']);
31        $response = $response->withHeader('Content-Type', $result['contentType']);
32        if (isset($result['filename'])) {
33            $response = $response->withHeader('Content-Disposition', 'attachment; filename="'.$result['filename'].'"');
34        }
35        return $response;
36    }
37
38    /**
39     * @param array<string, \Psr\Http\Message\UploadedFileInterface|\Psr\Http\Message\UploadedFileInterface[]> $uploadedFiles
40     * @return array<string, mixed>
41     */
42    private function extractUploadedFileData(array $uploadedFiles): array
43    {
44        $payload = [];
45        $certificate = $uploadedFiles['certificate'] ?? null;
46        if (is_array($certificate)) {
47            $certificate = $certificate[0] ?? null;
48        }
49
50        if ($certificate instanceof \Psr\Http\Message\UploadedFileInterface) {
51            $stream = $certificate->getStream();
52            $stream->rewind();
53            $contents = $stream->getContents();
54            $payload['certificateContents'] = base64_encode($contents);
55            $payload['certificateFilename'] = (string) ($certificate->getClientFilename() ?? '');
56            $payload['certificateMediaType'] = (string) ($certificate->getClientMediaType() ?? '');
57        }
58
59        return $payload;
60    }
61
62    /** POST /fiscal/authorization - generate and sign fiscal authorization PDF. */
63    public function authorization(Request $request, Response $response): Response
64    {
65        $payload = $request->getParsedBody();
66        if (!is_array($payload)) {
67            $payload = [];
68        }
69
70        $uploadData = $this->extractUploadedFileData($request->getUploadedFiles());
71        $payload = array_merge($payload, $uploadData);
72        return $this->respond($response, $this->fiscalService->authorization($request->getQueryParams(), $payload));
73    }
74
75    /** POST /fiscal/validate - validate certificate before signing. */
76    public function validate(Request $request, Response $response): Response
77    {
78        $payload = $request->getParsedBody();
79        if (!is_array($payload)) {
80            $payload = [];
81        }
82
83        $uploadData = $this->extractUploadedFileData($request->getUploadedFiles());
84        $payload = array_merge($payload, $uploadData);
85        return $this->respond($response, $this->fiscalService->validate($request->getQueryParams(), $payload));
86    }
87
88    /** GET /fiscal/download - download signed authorization PDF. */
89    public function download(Request $request, Response $response): Response
90    {
91        return $this->respondDownload($response, $this->fiscalService->download($request->getQueryParams()));
92    }
93
94    /** POST /fiscal/preview - generate unsigned fiscal authorization PDF for review. */
95    public function preview(Request $request, Response $response): Response
96    {
97        $payload = $request->getParsedBody();
98        if (!is_array($payload)) {
99            $payload = [];
100        }
101
102        return $this->respondDownload($response, $this->fiscalService->preview($request->getQueryParams(), $payload));
103    }
104}