NormalizeDetalleTrait   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 199
Duplicated Lines 0 %

Test Coverage

Coverage 84.25%

Importance

Changes 0
Metric Value
wmc 33
eloc 116
c 0
b 0
f 0
dl 0
loc 199
ccs 107
cts 127
cp 0.8425
rs 9.76

1 Method

Rating   Name   Duplication   Size   Complexity  
F normalizeDetalle() 0 189 33
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\Worker\Normalizer\Helper\Utils;
29
30
/**
31
 * Reglas de normalización para el detalle de los documentos.
32
 */
33
trait NormalizeDetalleTrait
34
{
35
    /**
36
     * Normaliza los detalles del documento.
37
     *
38
     * @param DocumentBagInterface $bag Bolsa con los datos a normalizar.
39
     * @return void
40
     * @todo Revisar cómo se aplican descuentos y recargos. ¿Debería ser un
41
     * porcentaje del monto original?.
42
     */
43 107
    protected function normalizeDetalle(DocumentBagInterface $bag): void
44
    {
45 107
        $data = $bag->getNormalizedData();
46
47 107
        if (!isset($data['Detalle'][0])) {
48 7
            $data['Detalle'] = [
49 7
                $data['Detalle'],
50 7
            ];
51
        }
52
53 107
        $sumarMontoNF = (
54 107
            !isset($data['Encabezado']['Totales']['MontoNF'])
55 107
            || $data['Encabezado']['Totales']['MontoNF'] === false
56 107
        );
57
58 107
        $item = 1;
59 107
        foreach ($data['Detalle'] as &$d) {
60 107
            $d = array_merge([
61 107
                'NroLinDet' => $item++,
62 107
                'CdgItem' => false,
63 107
                'IndExe' => false,
64 107
                'Retenedor' => false,
65 107
                'NmbItem' => false,
66 107
                'DscItem' => false,
67 107
                'QtyRef' => false,
68 107
                'UnmdRef' => false,
69 107
                'PrcRef' => false,
70 107
                'QtyItem' => false,
71 107
                'Subcantidad' => false,
72 107
                'FchElabor' => false,
73 107
                'FchVencim' => false,
74 107
                'UnmdItem' => false,
75 107
                'PrcItem' => false,
76 107
                'DescuentoPct' => false,
77 107
                'DescuentoMonto' => false,
78 107
                'RecargoPct' => false,
79 107
                'RecargoMonto' => false,
80 107
                'CodImpAdic' => false,
81 107
                'MontoItem' => false,
82 107
            ], $d);
83
84
            // Corregir datos.
85 107
            $d['NmbItem'] = mb_substr($d['NmbItem'], 0, 80);
86 107
            if (!empty($d['DscItem'])) {
87 6
                $d['DscItem'] = mb_substr($d['DscItem'], 0, 1000);
88
            }
89
90
            // Normalizar.
91 107
            if ($bag->getTipoDocumento()->esExportacion()) {
92 16
                $d['IndExe'] = 1;
93
            }
94 107
            if (is_array($d['CdgItem'])) {
95 6
                $d['CdgItem'] = array_merge([
96 6
                    'TpoCodigo' => false,
97 6
                    'VlrCodigo' => false,
98 6
                ], $d['CdgItem']);
99
                if (
100 6
                    $d['Retenedor'] === false
101 6
                    && $d['CdgItem']['TpoCodigo'] === 'CPCS'
102
                ) {
103
                    $d['Retenedor'] = true;
104
                }
105
            }
106 107
            if ($d['Retenedor'] !== false) {
107 1
                if (!is_array($d['Retenedor'])) {
108
                    $d['Retenedor'] = ['IndAgente' => 'R'];
109
                }
110 1
                $d['Retenedor'] = array_merge([
111 1
                    'IndAgente' => 'R',
112 1
                    'MntBaseFaena' => false,
113 1
                    'MntMargComer' => false,
114 1
                    'PrcConsFinal' => false,
115 1
                ], $d['Retenedor']);
116
            }
117 107
            if ($d['CdgItem'] !== false && !is_array($d['CdgItem'])) {
118
                $d['CdgItem'] = [
119
                    'TpoCodigo' => empty($d['Retenedor']['IndAgente'])
120
                        ? 'INT1'
121
                        : 'CPCS'
122
                    ,
123
                    'VlrCodigo' => $d['CdgItem'],
124
                ];
125
            }
126 107
            if ($d['PrcItem']) {
127 102
                if (!$d['QtyItem']) {
128
                    $d['QtyItem'] = 1;
129
                }
130 102
                if (empty($d['MontoItem'])) {
131 102
                    $d['MontoItem'] = Utils::round(
132 102
                        (float) $d['QtyItem'] * (float)$d['PrcItem'],
133 102
                        $data['Encabezado']['Totales']['TpoMoneda']
134 102
                    );
135
136
                    // Aplicar descuento.
137 102
                    if ($d['DescuentoPct']) {
138 5
                        $d['DescuentoMonto'] = round(
139 5
                            $d['MontoItem'] * (float) $d['DescuentoPct'] / 100
140 5
                        );
141
                    }
142 102
                    $d['MontoItem'] -= $d['DescuentoMonto'];
143
144
                    // Aplicar recargo.
145 102
                    if ($d['RecargoPct']) {
146
                        $d['RecargoMonto'] = round(
147
                            $d['MontoItem'] * (float) $d['RecargoPct'] / 100
148
                        );
149
                    }
150 102
                    $d['MontoItem'] += $d['RecargoMonto'];
151
152
                    // Aproximar monto del item.
153 102
                    $d['MontoItem'] = Utils::round(
154 102
                        $d['MontoItem'],
155 102
                        $data['Encabezado']['Totales']['TpoMoneda']
156 102
                    );
157
                }
158
            }
159
            // Si el monto del item es vacío se estandariza como "0".
160 5
            elseif (empty($d['MontoItem'])) {
161 5
                $d['MontoItem'] = 0;
162
            }
163
164
            // Sumar valor del monto a MntNeto o MntExe según corresponda.
165 107
            if ($d['MontoItem']) {
166
                // Si no es boleta.
167 102
                if (!$bag->getTipoDocumento()->esBoleta()) {
168
                    // Si es exento o no facturable.
169 91
                    if (!empty($d['IndExe'])) {
170 26
                        if ($d['IndExe'] == 1) {
171 26
                            $data['Encabezado']['Totales']['MntExe'] +=
172 26
                                $d['MontoItem']
173 26
                            ;
174 2
                        } elseif ($d['IndExe'] == 2) {
175 2
                            if ($sumarMontoNF) {
176 2
                                if (empty($data['Encabezado']['Totales']['MontoNF'])) {
177 2
                                    $data['Encabezado']['Totales']['MontoNF'] = 0;
178
                                }
179 2
                                $data['Encabezado']['Totales']['MontoNF'] +=
180 2
                                    $d['MontoItem']
181 2
                                ;
182
                            }
183
                        }
184
                    }
185
186
                    // Si es afecto, se agrega al monto neto.
187
                    else {
188 66
                        if (empty($data['Encabezado']['Totales']['MntNeto'])) {
189 66
                            $data['Encabezado']['Totales']['MntNeto'] = 0;
190
                        }
191 66
                        $data['Encabezado']['Totales']['MntNeto'] +=
192 66
                            $d['MontoItem']
193 66
                        ;
194
                    }
195
                }
196
197
                // Si es boleta.
198
                else {
199
                    // Si es exento o no facturable.
200 12
                    if (!empty($d['IndExe'])) {
201 6
                        if ($d['IndExe'] == 1) {
202 6
                            $data['Encabezado']['Totales']['MntExe'] +=
203 6
                                $d['MontoItem']
204 6
                            ;
205 6
                            $data['Encabezado']['Totales']['MntTotal'] +=
206 6
                                $d['MontoItem']
207 6
                            ;
208
                        } elseif ($d['IndExe'] == 2) {
209
                            if ($sumarMontoNF) {
210
                                if (empty($data['Encabezado']['Totales']['MontoNF'])) {
211
                                    $data['Encabezado']['Totales']['MontoNF'] = 0;
212
                                }
213
                                $data['Encabezado']['Totales']['MontoNF'] +=
214
                                    $d['MontoItem']
215
                                ;
216
                            }
217
                        }
218
                    }
219
220
                    // Si es afecto, sólo agregar al monto total.
221
                    else {
222 6
                        $data['Encabezado']['Totales']['MntTotal'] +=
223 6
                            $d['MontoItem']
224 6
                        ;
225
                    }
226
                }
227
            }
228
        }
229
230
        // Actualizar los datos normalizados.
231 107
        $bag->setNormalizedData($data);
232
    }
233
}
234