NormalizeDetalleTrait   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 199
Duplicated Lines 0 %

Test Coverage

Coverage 74.02%

Importance

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

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 53
    protected function normalizeDetalle(DocumentBagInterface $bag): void
44
    {
45 53
        $data = $bag->getNormalizedData();
46
47 53
        if (!isset($data['Detalle'][0])) {
48 2
            $data['Detalle'] = [
49 2
                $data['Detalle'],
50 2
            ];
51
        }
52
53 53
        $sumarMontoNF = (
54 53
            !isset($data['Encabezado']['Totales']['MontoNF'])
55 53
            || $data['Encabezado']['Totales']['MontoNF'] === false
56 53
        );
57
58 53
        $item = 1;
59 53
        foreach ($data['Detalle'] as &$d) {
60 53
            $d = array_merge([
61 53
                'NroLinDet' => $item++,
62 53
                'CdgItem' => false,
63 53
                'IndExe' => false,
64 53
                'Retenedor' => false,
65 53
                'NmbItem' => false,
66 53
                'DscItem' => false,
67 53
                'QtyRef' => false,
68 53
                'UnmdRef' => false,
69 53
                'PrcRef' => false,
70 53
                'QtyItem' => false,
71 53
                'Subcantidad' => false,
72 53
                'FchElabor' => false,
73 53
                'FchVencim' => false,
74 53
                'UnmdItem' => false,
75 53
                'PrcItem' => false,
76 53
                'DescuentoPct' => false,
77 53
                'DescuentoMonto' => false,
78 53
                'RecargoPct' => false,
79 53
                'RecargoMonto' => false,
80 53
                'CodImpAdic' => false,
81 53
                'MontoItem' => false,
82 53
            ], $d);
83
84
            // Corregir datos.
85 53
            $d['NmbItem'] = mb_substr($d['NmbItem'], 0, 80);
86 53
            if (!empty($d['DscItem'])) {
87 1
                $d['DscItem'] = mb_substr($d['DscItem'], 0, 1000);
88
            }
89
90
            // Normalizar.
91 53
            if ($bag->getTipoDocumento()->esExportacion()) {
92 7
                $d['IndExe'] = 1;
93
            }
94 53
            if (is_array($d['CdgItem'])) {
95
                $d['CdgItem'] = array_merge([
96
                    'TpoCodigo' => false,
97
                    'VlrCodigo' => false,
98
                ], $d['CdgItem']);
99
                if (
100
                    $d['Retenedor'] === false
101
                    && $d['CdgItem']['TpoCodigo'] === 'CPCS'
102
                ) {
103
                    $d['Retenedor'] = true;
104
                }
105
            }
106 53
            if ($d['Retenedor'] !== false) {
107
                if (!is_array($d['Retenedor'])) {
108
                    $d['Retenedor'] = ['IndAgente' => 'R'];
109
                }
110
                $d['Retenedor'] = array_merge([
111
                    'IndAgente' => 'R',
112
                    'MntBaseFaena' => false,
113
                    'MntMargComer' => false,
114
                    'PrcConsFinal' => false,
115
                ], $d['Retenedor']);
116
            }
117 53
            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 53
            if ($d['PrcItem']) {
127 50
                if (!$d['QtyItem']) {
128
                    $d['QtyItem'] = 1;
129
                }
130 50
                if (empty($d['MontoItem'])) {
131 50
                    $d['MontoItem'] = Utils::round(
132 50
                        (float) $d['QtyItem'] * (float)$d['PrcItem'],
133 50
                        $data['Encabezado']['Totales']['TpoMoneda']
134 50
                    );
135
136
                    // Aplicar descuento.
137 50
                    if ($d['DescuentoPct']) {
138 2
                        $d['DescuentoMonto'] = round(
139 2
                            $d['MontoItem'] * (float) $d['DescuentoPct'] / 100
140 2
                        );
141
                    }
142 50
                    $d['MontoItem'] -= $d['DescuentoMonto'];
143
144
                    // Aplicar recargo.
145 50
                    if ($d['RecargoPct']) {
146
                        $d['RecargoMonto'] = round(
147
                            $d['MontoItem'] * (float) $d['RecargoPct'] / 100
148
                        );
149
                    }
150 50
                    $d['MontoItem'] += $d['RecargoMonto'];
151
152
                    // Aproximar monto del item.
153 50
                    $d['MontoItem'] = Utils::round(
154 50
                        $d['MontoItem'],
155 50
                        $data['Encabezado']['Totales']['TpoMoneda']
156 50
                    );
157
                }
158
            }
159
            // Si el monto del item es vacío se estandariza como "0".
160 3
            elseif (empty($d['MontoItem'])) {
161 3
                $d['MontoItem'] = 0;
162
            }
163
164
            // Sumar valor del monto a MntNeto o MntExe según corresponda.
165 53
            if ($d['MontoItem']) {
166
                // Si no es boleta.
167 50
                if (!$bag->getTipoDocumento()->esBoleta()) {
168
                    // Si es exento o no facturable.
169 45
                    if (!empty($d['IndExe'])) {
170 11
                        if ($d['IndExe'] == 1) {
171 11
                            $data['Encabezado']['Totales']['MntExe'] +=
172 11
                                $d['MontoItem']
173 11
                            ;
174 1
                        } elseif ($d['IndExe'] == 2) {
175 1
                            if ($sumarMontoNF) {
176 1
                                if (empty($data['Encabezado']['Totales']['MontoNF'])) {
177 1
                                    $data['Encabezado']['Totales']['MontoNF'] = 0;
178
                                }
179 1
                                $data['Encabezado']['Totales']['MontoNF'] +=
180 1
                                    $d['MontoItem']
181 1
                                ;
182
                            }
183
                        }
184
                    }
185
186
                    // Si es afecto, se agrega al monto neto.
187
                    else {
188 34
                        if (empty($data['Encabezado']['Totales']['MntNeto'])) {
189 34
                            $data['Encabezado']['Totales']['MntNeto'] = 0;
190
                        }
191 34
                        $data['Encabezado']['Totales']['MntNeto'] +=
192 34
                            $d['MontoItem']
193 34
                        ;
194
                    }
195
                }
196
197
                // Si es boleta.
198
                else {
199
                    // Si es exento o no facturable.
200 5
                    if (!empty($d['IndExe'])) {
201 3
                        if ($d['IndExe'] == 1) {
202 3
                            $data['Encabezado']['Totales']['MntExe'] +=
203 3
                                $d['MontoItem']
204 3
                            ;
205 3
                            $data['Encabezado']['Totales']['MntTotal'] +=
206 3
                                $d['MontoItem']
207 3
                            ;
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 2
                        $data['Encabezado']['Totales']['MntTotal'] +=
223 2
                            $d['MontoItem']
224 2
                        ;
225
                    }
226
                }
227
            }
228
        }
229
230
        // Actualizar los datos normalizados.
231 53
        $bag->setNormalizedData($data);
232
    }
233
}
234