Test Failed
Push — master ( 8cbe19...3a660b )
by Esteban De La Fuente
06:47
created

TemplateDataFormatter   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Test Coverage

Coverage 70%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 5
eloc 75
dl 0
loc 121
ccs 63
cts 90
cp 0.7
rs 10
c 1
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B createHandlers() 0 104 4
A __construct() 0 3 1
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 Derafu\Enum\Currency;
28
use Derafu\L10n\Cl\Rut\Rut;
29
use Derafu\Renderer\Abstract\AbstractHandlerFormatter;
30
use Derafu\Repository\Contract\RepositoryManagerInterface;
31
use Derafu\Support\Date;
32
use libredte\lib\Core\Package\Billing\Component\Document\Contract\TipoDocumentoInterface;
33
use libredte\lib\Core\Package\Billing\Component\Document\Entity\AduanaMoneda;
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\FormaPagoExportacion;
39
use libredte\lib\Core\Package\Billing\Component\Document\Entity\ImpuestoAdicionalRetencion;
40
use libredte\lib\Core\Package\Billing\Component\Document\Entity\MedioPago;
41
use libredte\lib\Core\Package\Billing\Component\Document\Entity\TagXml;
42
use libredte\lib\Core\Package\Billing\Component\Document\Entity\Traslado;
43
use TCPDF2DBarcode;
44
45
/**
46
 * Servicio para traducir los datos de los documentos a su representación para
47
 * ser utilizada en la renderización del documento.
48
 */
49
class TemplateDataFormatter extends AbstractHandlerFormatter
50
{
51
    /**
52
     * Constructor del handler.
53
     *
54
     * @param RepositoryManagerInterface $repositoryManager
55
     */
56 53
    public function __construct(
57
        private RepositoryManagerInterface $repositoryManager
58
    ) {
59 53
    }
60
61
    /**
62
     * Mapa de campos a handlers para los documentos tributarios electrónicos.
63
     *
64
     * @return array
65
     */
66 53
    protected function createHandlers(): array
67
    {
68 53
        return [
69
            // Tipos de documento.
70 53
            'TipoDTE' => $this->repositoryManager->getRepository(
71 53
                TipoDocumentoInterface::class
72 53
            ),
73 53
            'TpoDocRef' => 'alias:TipoDTE',
74
            // RUT.
75 53
            'RUTEmisor' => fn (string $rut) => Rut::formatFull($rut),
76 53
            'RUTRecep' => 'alias:RUTEmisor',
77 53
            'RUTSolicita' => 'alias:RUTEmisor',
78 53
            'RUTTrans' => 'alias:RUTEmisor',
79 53
            'RUTChofer' => 'alias:RUTEmisor',
80
            // Comuna.
81 53
            'CdgSIISucur' => fn (string $comuna) =>
82 53
                $this->repositoryManager->getRepository(
83 53
                    Comuna::class
84 53
                )->find($comuna)->getDireccionRegional()
85 53
            ,
86 53
            'CiudadOrigen' => fn (string $comuna) =>
87
                $this->repositoryManager->getRepository(
88
                    Comuna::class
89
                )->find($comuna)->getCiudad()
90 53
            ,
91 53
            'CiudadRecep' => 'alias:CiudadOrigen',
92
            // Fechas largas.
93 53
            'FchEmis' => fn (string $fecha) => Date::formatSpanish($fecha),
94 53
            'FchRef' => 'alias:FchEmis',
95 53
            'FchVenc' => 'alias:FchEmis',
96 53
            'FchCancel' => 'alias:FchEmis',
97
            // Fechas cortas.
98 53
            'PeriodoDesde' => function (string $fecha) {
99
                $timestamp = strtotime($fecha);
100
                return date('d/m/Y', $timestamp);
101 53
            },
102 53
            'PeriodoHasta' => 'alias:PeriodoDesde',
103 53
            'FchPago' => 'alias:PeriodoDesde',
104
            // Solo año de una fecha.
105 53
            'FchResol' => fn (string $fecha) => explode('-', $fecha, 2)[0],
106
            // Datos de Aduana.
107 53
            'Aduana' => function (string $tagXmlAndValue) {
108
                [$tagXml, $value] = explode(':', $tagXmlAndValue);
109
                $xmlTagEntity = $this->repositoryManager->getRepository(
110
                    TagXml::class
111
                )->find($tagXml);
112
                $name = $xmlTagEntity->getGlosa();
113
                $entityClass = $xmlTagEntity->getEntity();
114
                if ($entityClass) {
115
                    $description = $this->repositoryManager->getRepository(
116
                        $entityClass
117
                    )->find($value)->getGlosa();
118
                } else {
119
                    $description = $this->handle($tagXml, $value);
120
                }
121
                if ($name && !in_array($description, [false, null, ''], true)) {
122
                    return $name . ': ' . $description;
123
                }
124
                return '';
125 53
            },
126 53
            'TotItems' => 'alias:Number',
127
            // Otros datos que se mapean de un código a su glosa usando un
128
            // repositorio.
129 53
            'TipoImp' => $this->repositoryManager->getRepository(
130 53
                ImpuestoAdicionalRetencion::class
131 53
            ),
132 53
            'MedioPago' => $this->repositoryManager->getRepository(
133 53
                MedioPago::class
134 53
            ),
135 53
            'FmaPago' => $this->repositoryManager->getRepository(
136 53
                FormaPago::class
137 53
            ),
138 53
            'FmaPagExp' => $this->repositoryManager->getRepository(
139 53
                FormaPagoExportacion::class
140 53
            ),
141 53
            'Nacionalidad' => $this->repositoryManager->getRepository(
142 53
                AduanaPais::class
143 53
            ),
144 53
            'CodPaisRecep' => 'alias:Nacionalidad',
145 53
            'IndTraslado' => $this->repositoryManager->getRepository(
146 53
                Traslado::class
147 53
            ),
148 53
            'CodViaTransp' => $this->repositoryManager->getRepository(
149 53
                AduanaTransporte::class
150 53
            ),
151
            //  Timbre Electrónico del Documento (TED).
152 53
            'TED' => function (string $timbre) {
153 53
                $pdf417 = new TCPDF2DBarcode($timbre, 'PDF417,,5');
154 53
                $png = $pdf417->getBarcodePngData(1, 1, [0,0,0]);
155 53
                return 'data:image/png;base64,' . base64_encode($png);
156 53
            },
157
            // Montos sin decimales y formato de Chile en separadores.
158 53
            'Number' => function (int|float|string $num) {
159
                $num = round((float) $num);
160
                return number_format($num, 0, ',', '.');
161 53
            },
162
            // Montos según moneda.
163 53
            'MontoMoneda' => function (string $value) {
164
                [$codigo, $num] = explode(':', $value);
165
                $result = $this->repositoryManager->getRepository(
166
                    AduanaMoneda::class
167
                )->findBy(['glosa' => $codigo]);
168
                $currency = ($result[0] ?? null)?->getCurrency() ?? Currency::XXX;
169
                return $currency->format((float) $num);
170 53
            },
171 53
        ];
172
    }
173
}
174