Test Failed
Push — master ( ebf0dd...8dc6a9 )
by Esteban De La Fuente
05:48
created

TemplateDataHandler::getHandler()   A

Complexity

Conditions 6
Paths 8

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 11.9895

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 17
c 1
b 0
f 0
nc 8
nop 1
dl 0
loc 30
ccs 9
cts 20
cp 0.45
crap 11.9895
rs 9.0777
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * LibreDTE: Biblioteca PHP (Núcleo).
7
 * Copyright (C) LibreDTE <https://www.libredte.cl>
8
 *
9
 * Este programa es software libre: usted puede redistribuirlo y/o modificarlo
10
 * bajo los términos de la Licencia Pública General Affero de GNU publicada por
11
 * la Fundación para el Software Libre, ya sea la versión 3 de la Licencia, o
12
 * (a su elección) cualquier versión posterior de la misma.
13
 *
14
 * Este programa se distribuye con la esperanza de que sea útil, pero SIN
15
 * GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD
16
 * PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la Licencia Pública
17
 * General Affero de GNU para obtener una información más detallada.
18
 *
19
 * Debería haber recibido una copia de la Licencia Pública General Affero de
20
 * GNU junto a este programa.
21
 *
22
 * En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
23
 */
24
25
namespace libredte\lib\Core\Package\Billing\Component\Document\Service;
26
27
use Closure;
28
use Derafu\Lib\Core\Helper\Rut;
29
use Derafu\Lib\Core\Package\Prime\Component\Entity\Contract\EntityComponentInterface;
30
use Derafu\Lib\Core\Package\Prime\Component\Template\Contract\DataHandlerInterface;
31
use Derafu\Lib\Core\Package\Prime\Component\Template\Service\DataHandler;
32
use Derafu\Lib\Core\Support\Store\Contract\RepositoryInterface;
33
use libredte\lib\Core\Package\Billing\Component\Document\Contract\TipoDocumentoInterface;
34
use libredte\lib\Core\Package\Billing\Component\Document\Entity\AduanaPais;
35
use libredte\lib\Core\Package\Billing\Component\Document\Entity\AduanaTransporte;
36
use libredte\lib\Core\Package\Billing\Component\Document\Entity\Comuna;
37
use libredte\lib\Core\Package\Billing\Component\Document\Entity\FormaPago;
38
use libredte\lib\Core\Package\Billing\Component\Document\Entity\TagXml;
39
use libredte\lib\Core\Package\Billing\Component\Document\Entity\Traslado;
40
use libredte\lib\Core\Package\Billing\Component\Document\Exception\RendererException;
41
use TCPDF2DBarcode;
42
43
/**
44
 * Servicio para traducir los datos de los documentos a su representación para
45
 * ser utilizada en la renderización del documento.
46
 */
47
class TemplateDataHandler implements DataHandlerInterface
48
{
49
    /**
50
     * Mapa de handlers.
51
     *
52
     * @var array
53
     */
54
    private array $handlers;
55
56
    /**
57
     * Handler por defecto para manejar los casos.
58
     *
59
     * @var DataHandlerInterface
60
     */
61
    private DataHandlerInterface $handler;
62
63
    /**
64
     * Constructor del handler.
65
     *
66
     * @param EntityComponentInterface $entityComponent
67
     * @param DataHandlerInterface|null $handler
68
     */
69 54
    public function __construct(
70
        private EntityComponentInterface $entityComponent,
71
        DataHandlerInterface $handler = null
72
    ) {
73 54
        $this->handler = $handler ?? new DataHandler();
74
    }
75
76
    /**
77
     * @inheritDoc
78
     */
79 54
    public function handle(string $id, mixed $data): string
80
    {
81
        // Si no hay valor asignado en los datos se entrega un string vacio.
82 54
        if (!$data) {
83 18
            return '';
84
        }
85
86
        // Buscar el handler.
87 54
        $handler = $this->getHandler($id);
88
89
        // Ejecutar el handler sobre los datos para formatearlos.
90 54
        assert($this->handler instanceof DataHandler);
91 54
        return $this->handler->handle($id, $data, $handler);
0 ignored issues
show
Unused Code introduced by
The call to Derafu\Lib\Core\Package\...dlerInterface::handle() has too many arguments starting with $handler. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

91
        return $this->handler->/** @scrutinizer ignore-call */ handle($id, $data, $handler);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
92
    }
93
94
    /**
95
     * Obtiene el handler de un campo a partir de su ID.
96
     *
97
     * @param string $id
98
     * @return Closure|RepositoryInterface
99
     */
100 54
    private function getHandler(string $id): Closure|RepositoryInterface
101
    {
102 54
        if (!isset($this->handlers)) {
103 54
            $this->handlers = $this->createHandlers();
104
        }
105
106 54
        if (!isset($this->handlers[$id])) {
107
            throw new RendererException(sprintf(
108
                'El formato para %s no está definido. Los disponibles son: %s.',
109
                $id,
110
                implode(', ', array_keys($this->handlers))
111
            ));
112
        }
113
114 54
        if (is_string($this->handlers[$id]) && str_starts_with($this->handlers[$id], 'alias:')) {
115 50
            [$alias, $handler] = explode(':', $this->handlers[$id], 2);
116
117 50
            if (!isset($this->handlers[$handler])) {
118
                throw new RendererException(sprintf(
119
                    'El alias %s del formato para %s no está definido. Los disponibles son: %s.',
120
                    $handler,
121
                    $id,
122
                    implode(', ', array_keys($this->handlers))
123
                ));
124
            }
125
126 50
            return $this->handlers[$handler];
127
        }
128
129 54
        return $this->handlers[$id];
130
    }
131
132
    /**
133
     * Mapa de campos a handlers para los documentos tributarios electrónicos.
134
     *
135
     * @return array
136
     */
137 54
    private function createHandlers(): array
138
    {
139 54
        return [
140
            // Tipos de documento.
141 54
            'TipoDTE' => $this->entityComponent->getRepository(
142 54
                TipoDocumentoInterface::class
143 54
            ),
144 54
            'TpoDocRef' => 'alias:TipoDTE',
145
            // RUT.
146 54
            'RUTEmisor' => fn (string $rut) => Rut::formatFull($rut),
147 54
            'RUTRecep' => 'alias:RUTEmisor',
148 54
            'RUTSolicita' => 'alias:RUTEmisor',
149 54
            'RUTTrans' => 'alias:RUTEmisor',
150 54
            'RUTChofer' => 'alias:RUTEmisor',
151
            // Comuna.
152 54
            'CdgSIISucur' => fn (string $comuna) =>
153 53
                $this->entityComponent->getRepository(
154 53
                    Comuna::class
155 53
                )->find($comuna)->getDireccionRegional()
156 54
            ,
157 54
            'CiudadOrigen' => fn (string $comuna) =>
158
                $this->entityComponent->getRepository(
159
                    Comuna::class
160
                )->find($comuna)->getCiudad()
161 54
            ,
162 54
            'CiudadRecep' => 'alias:CiudadOrigen',
163
            // Fechas largas.
164 54
            'FchEmis' => function (string $fecha) {
165 54
                $timestamp = strtotime($fecha);
166 54
                return date('d/m/Y', $timestamp); // TODO: Formato largo.
167 54
            },
168 54
            'FchRef' => 'alias:FchEmis',
169 54
            'FchVenc' => 'alias:FchEmis',
170
            // Fechas cortas.
171 54
            'PeriodoDesde' => function (string $fecha) {
172 1
                $timestamp = strtotime($fecha);
173 1
                return date('d/m/Y', $timestamp);
174 54
            },
175 54
            'PeriodoHasta' => 'alias:PeriodoDesde',
176
            // Solo año de una fecha.
177 54
            'FchResol' => function (string $fecha) {
178
                return explode('-', $fecha, 2)[0];
179 54
            },
180
            // Datos de Aduana.
181 54
            'Aduana' => function (string $tagXmlAndValue) {
182
                [$tagXml, $value] = explode(':', $tagXmlAndValue);
183
                $xmlTagEntity = $this->entityComponent->getRepository(
184
                    TagXml::class
185
                )->find($tagXml);
186
                $name = $xmlTagEntity->getGlosa();
187
                $entityClass = $xmlTagEntity->getEntity();
188
                if ($entityClass) {
189
                    $description = $this->entityComponent->getRepository(
190
                        $entityClass
191
                    )->find($value)->getGlosa();
192
                } else {
193
                    $description = $this->handle($tagXml, $value);
194
                }
195
                if ($name && !in_array($description, [false, null, ''], true)) {
196
                    return $name . ': ' . $description;
197
                }
198
                return '';
199 54
            },
200
            // Otros datos que se mapean de un código a su glosa usando un
201
            // repositorio.
202 54
            'FmaPago' => $this->entityComponent->getRepository(
203 54
                FormaPago::class
204 54
            ),
205 54
            'Nacionalidad' => $this->entityComponent->getRepository(
206 54
                AduanaPais::class
207 54
            ),
208 54
            'CodPaisRecep' => 'alias:Nacionalidad',
209 54
            'IndTraslado' => $this->entityComponent->getRepository(
210 54
                Traslado::class
211 54
            ),
212 54
            'CodViaTransp' => $this->entityComponent->getRepository(
213 54
                AduanaTransporte::class
214 54
            ),
215
            //  Timbre Electrónico del Documento (TED).
216 54
            'TED' => function (string $timbre) {
217 54
                $pdf417 = new TCPDF2DBarcode($timbre, 'PDF417,,5');
218 54
                $png = $pdf417->getBarcodePngData(1, 1, [0,0,0]);
219 54
                return 'data:image/png;base64,' . base64_encode($png);
220 54
            }
221 54
        ];
222
    }
223
}
224