NormalizeIvaMntTotalTrait   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Test Coverage

Coverage 81.82%

Importance

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

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 53
    protected function normalizeIvaMntTotal(DocumentBagInterface $bag): void
54
    {
55 53
        $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 53
            $bag->getTipoDocumento()->esBoleta()
61
            && (
62 53
                empty($data['Encabezado']['IdDoc']['IndMntNeto'])
63 53
                || $data['Encabezado']['IdDoc']['IndMntNeto'] != 2
64
            )
65
        ) {
66 5
            $total = (int) $data['Encabezado']['Totales']['MntTotal']
67 5
                - (int)$data['Encabezado']['Totales']['MntExe']
68 5
            ;
69
            if (
70 5
                $total
71
                && (
72 5
                    empty($data['Encabezado']['Totales']['MntNeto'])
73 5
                    || empty($data['Encabezado']['Totales']['IVA'])
74
                )
75
            ) {
76 2
                list(
77 2
                    $data['Encabezado']['Totales']['MntNeto'],
78 2
                    $data['Encabezado']['Totales']['IVA']
79 2
                ) = Utils::calcularNetoIVA(
80 2
                    $total,
81 2
                    $data['Encabezado']['Totales']['TasaIVA']
82 2
                        ?? $bag->getTipoDocumento()->getDefaultTasaIVA()
83 2
                );
84
            }
85
        }
86
87
        // Agregar IVA y monto total.
88 53
        if (!empty($data['Encabezado']['Totales']['MntNeto'])) {
89 36
            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 36
                    empty($data['Encabezado']['Totales']['IVA'])
100 36
                    && !empty($data['Encabezado']['Totales']['TasaIVA'])
101
                ) {
102 34
                    $data['Encabezado']['Totales']['IVA'] = round(
103 34
                        $data['Encabezado']['Totales']['MntNeto']
104 34
                            * ($data['Encabezado']['Totales']['TasaIVA'] / 100)
105 34
                    );
106
                }
107
            }
108 36
            if (empty($data['Encabezado']['Totales']['MntTotal'])) {
109 34
                $data['Encabezado']['Totales']['MntTotal'] =
110 34
                    $data['Encabezado']['Totales']['MntNeto']
111 34
                ;
112 34
                if (!empty($data['Encabezado']['Totales']['IVA'])) {
113 34
                    $data['Encabezado']['Totales']['MntTotal'] +=
114 34
                        $data['Encabezado']['Totales']['IVA']
115 34
                    ;
116
                }
117 34
                if (!empty($data['Encabezado']['Totales']['MntExe'])) {
118
                    $data['Encabezado']['Totales']['MntTotal'] +=
119
                        $data['Encabezado']['Totales']['MntExe']
120
                    ;
121
                }
122
            }
123
        } else {
124
            if (
125 17
                !$data['Encabezado']['Totales']['MntTotal']
126 17
                && !empty($data['Encabezado']['Totales']['MntExe'])
127
            ) {
128 11
                $data['Encabezado']['Totales']['MntTotal'] =
129 11
                    $data['Encabezado']['Totales']['MntExe']
130 11
                ;
131
            }
132
        }
133
134
        // Si hay IVA definido se cambia a valor entero. El IVA no es decimal.
135 53
        if (is_numeric($data['Encabezado']['Totales']['IVA'] ?? null)) {
136 37
            $data['Encabezado']['Totales']['IVA'] =
137 37
                (int) $data['Encabezado']['Totales']['IVA']
138 37
            ;
139
        }
140
141
        // Si hay impuesto retenido o adicional se contabiliza en el total.
142 53
        if (!empty($data['Encabezado']['Totales']['ImptoReten'])) {
143 5
            foreach ($data['Encabezado']['Totales']['ImptoReten'] as &$ImptoReten) {
144 5
                $tipo = $this
145 5
                    ->repositoryManager
146 5
                    ->getRepository(ImpuestoAdicionalRetencion::class)
147 5
                    ->find($ImptoReten['TipoImp'])
148 5
                    ->getTipo()
149 5
                ;
150
                // Si es una retención, se resta al total y se traspasa a IVA
151
                // no retenido en caso que corresponda.
152 5
                if ($tipo === 'R') {
153 3
                    $data['Encabezado']['Totales']['MntTotal'] -=
154 3
                        $ImptoReten['MontoImp']
155 3
                    ;
156 3
                    if ($ImptoReten['MontoImp'] != $data['Encabezado']['Totales']['IVA']) {
157 1
                        $data['Encabezado']['Totales']['IVANoRet'] =
158 1
                            $data['Encabezado']['Totales']['IVA']
159 1
                                - $ImptoReten['MontoImp']
160 1
                        ;
161
                    }
162
                }
163
164
                // Si es impuesto adicional se suma al total.
165 2
                elseif ($tipo === 'A' && isset($ImptoReten['MontoImp'])) {
166 2
                    $data['Encabezado']['Totales']['MntTotal'] +=
167 2
                        $ImptoReten['MontoImp']
168 2
                    ;
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 53
            !empty($data['Encabezado']['Totales']['CredEC'])
177 53
            && 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 53
        if (!in_array($data['Encabezado']['IdDoc']['TipoDTE'], [39, 41])) {
193
            if (
194 48
                !empty($data['Encabezado']['Totales']['MntTotal'])
195 48
                && !empty($data['Encabezado']['Totales']['MontoNF'])
196
            ) {
197 1
                $data['Encabezado']['Totales']['MontoPeriodo'] =
198 1
                    $data['Encabezado']['Totales']['MntTotal']
199 1
                        + $data['Encabezado']['Totales']['MontoNF']
200 1
                ;
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 53
        if (is_numeric($data['Encabezado']['Totales']['MntTotal'] ?? null)) {
208 53
            if (!$bag->getTipoDocumento()->esExportacion()) {
209 46
                $data['Encabezado']['Totales']['MntTotal'] =
210 46
                    (int) $data['Encabezado']['Totales']['MntTotal']
211 46
                ;
212
            }
213
        }
214
215
        // Actualizar los datos normalizados.
216 53
        $bag->setNormalizedData($data);
217
    }
218
}
219