NormalizeIvaMntTotalTrait   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Test Coverage

Coverage 84.85%

Importance

Changes 0
Metric Value
eloc 92
dl 0
loc 183
ccs 84
cts 99
cp 0.8485
rs 9.92
c 0
b 0
f 0
wmc 31

1 Method

Rating   Name   Duplication   Size   Complexity  
F normalizeIvaMntTotal() 0 164 31
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\Worker\Normalizer\Trait;
26
27
use libredte\lib\Core\Package\Billing\Component\Document\Contract\DocumentBagInterface;
28
use libredte\lib\Core\Package\Billing\Component\Document\Entity\ImpuestoAdicionalRetencion;
29
use libredte\lib\Core\Package\Billing\Component\Document\Worker\Normalizer\Helper\Utils;
30
31
/**
32
 * Reglas de normalización para el IVA y monto total del documento.
33
 */
34
trait NormalizeIvaMntTotalTrait
35
{
36
    /**
37
     * Calcula el monto del IVA y el monto total del documento a partir del
38
     * monto neto y la tasa de IVA si es que existe.
39
     *
40
     * WARNING: Si es una boleta y tiene impuestos adicionales, no se
41
     * consideran los casos de esos impuestos adicionales. Se deberán indicar
42
     * los campos de MntNeto e IVA y no usar esta parte de la normalización.
43
     *
44
     * WARNING: Si el valor IndMntNeto es 2 indica que los montos de las líneas
45
     * son netos en cuyo caso no aplica el cálculo de neto e IVA a partir del
46
     * total y deberá venir informado de otra forma (aun no definido).
47
     *
48
     * @param DocumentBagInterface $bag Bolsa con los datos a normalizar.
49
     * @return void
50
     * @todo Revisar si los WARNING de la descripción del método realmente son
51
     * un problema y, si lo son, corregirlos.
52
     */
53 107
    protected function normalizeIvaMntTotal(DocumentBagInterface $bag): void
54
    {
55 107
        $data = $bag->getNormalizedData();
56
57
        // Si es una boleta y no están los datos de monto neto ni IVA se
58
        // calculan.
59
        if (
60 107
            $bag->getTipoDocumento()->esBoleta()
61
            && (
62 107
                empty($data['Encabezado']['IdDoc']['IndMntNeto'])
63 107
                || $data['Encabezado']['IdDoc']['IndMntNeto'] != 2
64
            )
65
        ) {
66 12
            $total = (int) $data['Encabezado']['Totales']['MntTotal']
67 12
                - (int)$data['Encabezado']['Totales']['MntExe']
68 12
            ;
69
            if (
70 12
                $total
71
                && (
72 12
                    empty($data['Encabezado']['Totales']['MntNeto'])
73 12
                    || empty($data['Encabezado']['Totales']['IVA'])
74
                )
75
            ) {
76 6
                list(
77 6
                    $data['Encabezado']['Totales']['MntNeto'],
78 6
                    $data['Encabezado']['Totales']['IVA']
79 6
                ) = Utils::calcularNetoIVA(
80 6
                    $total,
81 6
                    $data['Encabezado']['Totales']['TasaIVA']
82 6
                        ?? $bag->getTipoDocumento()->getDefaultTasaIVA()
83 6
                );
84
            }
85
        }
86
87
        // Agregar IVA y monto total.
88 107
        if (!empty($data['Encabezado']['Totales']['MntNeto'])) {
89 71
            if ($data['Encabezado']['IdDoc']['MntBruto'] == 1) {
90
                list(
91
                    $data['Encabezado']['Totales']['MntNeto'],
92
                    $data['Encabezado']['Totales']['IVA']
93
                ) = Utils::calcularNetoIVA(
94
                    $data['Encabezado']['Totales']['MntNeto'],
95
                    $data['Encabezado']['Totales']['TasaIVA']
96
                );
97
            } else {
98
                if (
99 71
                    empty($data['Encabezado']['Totales']['IVA'])
100 71
                    && !empty($data['Encabezado']['Totales']['TasaIVA'])
101
                ) {
102 66
                    $data['Encabezado']['Totales']['IVA'] = round(
103 66
                        $data['Encabezado']['Totales']['MntNeto']
104 66
                            * ($data['Encabezado']['Totales']['TasaIVA'] / 100)
105 66
                    );
106
                }
107
            }
108 71
            if (empty($data['Encabezado']['Totales']['MntTotal'])) {
109 66
                $data['Encabezado']['Totales']['MntTotal'] =
110 66
                    $data['Encabezado']['Totales']['MntNeto']
111 66
                ;
112 66
                if (!empty($data['Encabezado']['Totales']['IVA'])) {
113 66
                    $data['Encabezado']['Totales']['MntTotal'] +=
114 66
                        $data['Encabezado']['Totales']['IVA']
115 66
                    ;
116
                }
117 66
                if (!empty($data['Encabezado']['Totales']['MntExe'])) {
118 1
                    $data['Encabezado']['Totales']['MntTotal'] +=
119 1
                        $data['Encabezado']['Totales']['MntExe']
120 1
                    ;
121
                }
122
            }
123
        } else {
124
            if (
125 37
                !$data['Encabezado']['Totales']['MntTotal']
126 37
                && !empty($data['Encabezado']['Totales']['MntExe'])
127
            ) {
128 26
                $data['Encabezado']['Totales']['MntTotal'] =
129 26
                    $data['Encabezado']['Totales']['MntExe']
130 26
                ;
131
            }
132
        }
133
134
        // Si hay IVA definido se cambia a valor entero. El IVA no es decimal.
135 107
        if (is_numeric($data['Encabezado']['Totales']['IVA'] ?? null)) {
136 75
            $data['Encabezado']['Totales']['IVA'] =
137 75
                (int) $data['Encabezado']['Totales']['IVA']
138 75
            ;
139
        }
140
141
        // Si hay impuesto retenido o adicional se contabiliza en el total.
142 107
        if (!empty($data['Encabezado']['Totales']['ImptoReten'])) {
143 11
            foreach ($data['Encabezado']['Totales']['ImptoReten'] as &$ImptoReten) {
144 11
                $tipo = $this
145 11
                    ->entityComponent
146 11
                    ->getRepository(ImpuestoAdicionalRetencion::class)
147 11
                    ->find($ImptoReten['TipoImp'])
148 11
                    ->getTipo()
149 11
                ;
150
                // Si es una retención, se resta al total y se traspasa a IVA
151
                // no retenido en caso que corresponda.
152 11
                if ($tipo === 'R') {
153 7
                    $data['Encabezado']['Totales']['MntTotal'] -=
154 7
                        $ImptoReten['MontoImp']
155 7
                    ;
156 7
                    if ($ImptoReten['MontoImp'] != $data['Encabezado']['Totales']['IVA']) {
157 2
                        $data['Encabezado']['Totales']['IVANoRet'] =
158 2
                            $data['Encabezado']['Totales']['IVA']
159 2
                                - $ImptoReten['MontoImp']
160 2
                        ;
161
                    }
162
                }
163
164
                // Si es impuesto adicional se suma al total.
165 4
                elseif ($tipo === 'A' && isset($ImptoReten['MontoImp'])) {
166 4
                    $data['Encabezado']['Totales']['MntTotal'] +=
167 4
                        $ImptoReten['MontoImp']
168 4
                    ;
169
                }
170
            }
171
        }
172
173
        // Si hay crédito aasociado al impuesto (IVA) por ser empresa
174
        // constructora se descuenta del total.
175
        if (
176 107
            !empty($data['Encabezado']['Totales']['CredEC'])
177 107
            && method_exists($this, 'getDefaultCredEC')
178
        ) {
179
            if ($data['Encabezado']['Totales']['CredEC'] === true) {
180
                $data['Encabezado']['Totales']['CredEC'] = round(
181
                    $data['Encabezado']['Totales']['IVA']
182
                        * $this->getDefaultCredEC()
183
                );
184
            }
185
            $data['Encabezado']['Totales']['MntTotal'] -=
186
                $data['Encabezado']['Totales']['CredEC']
187
            ;
188
        }
189
190
        // Si hay monto total y monto no facturable se agrega el monto del
191
        // periodo.
192 107
        if (!in_array($data['Encabezado']['IdDoc']['TipoDTE'], [39, 41])) {
193
            if (
194 96
                !empty($data['Encabezado']['Totales']['MntTotal'])
195 96
                && !empty($data['Encabezado']['Totales']['MontoNF'])
196
            ) {
197 2
                $data['Encabezado']['Totales']['MontoPeriodo'] =
198 2
                    $data['Encabezado']['Totales']['MntTotal']
199 2
                        + $data['Encabezado']['Totales']['MontoNF']
200 2
                ;
201
            }
202
        }
203
204
        // Si hay monto total definido, y el documento no es de exportación, se
205
        // cambia a valor entero. El monto total no es decimal en documentos
206
        // nacionales.
207 107
        if (is_numeric($data['Encabezado']['Totales']['MntTotal'] ?? null)) {
208 107
            if (!$bag->getTipoDocumento()->esExportacion()) {
209 92
                $data['Encabezado']['Totales']['MntTotal'] =
210 92
                    (int) $data['Encabezado']['Totales']['MntTotal']
211 92
                ;
212
            }
213
        }
214
215
        // Actualizar los datos normalizados.
216 107
        $bag->setNormalizedData($data);
217
    }
218
}
219