CsvBatchProcessorStrategy::setInitialDTE()   F
last analyzed

Complexity

Conditions 15
Paths 16384

Size

Total Lines 67
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 57
CRAP Score 15

Importance

Changes 0
Metric Value
cc 15
eloc 61
c 0
b 0
f 0
nc 16384
nop 1
dl 0
loc 67
ccs 57
cts 57
cp 1
crap 15
rs 1.7499

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\BatchProcessor\Strategy\Spreadsheet;
26
27
use Derafu\Lib\Core\Foundation\Abstract\AbstractStrategy;
28
use Derafu\Lib\Core\Helper\Csv;
29
use Derafu\Lib\Core\Helper\Date;
30
use Derafu\Lib\Core\Package\Prime\Component\Entity\Contract\EntityComponentInterface;
31
use libredte\lib\Core\Package\Billing\Component\Document\Contract\BatchProcessorStrategyInterface;
32
use libredte\lib\Core\Package\Billing\Component\Document\Contract\DocumentBatchInterface;
33
use libredte\lib\Core\Package\Billing\Component\Document\Entity\AduanaMoneda;
34
use libredte\lib\Core\Package\Billing\Component\Document\Exception\BatchProcessorException;
35
36
/**
37
 * Estrategia "billing.document.batch_processor.strategy:spreadsheet.csv".
38
 *
39
 * Procesa en lote los documentos tributarios de un archivo CSV con el formato
40
 * estándar de LibreDTE.
41
 */
42
class CsvBatchProcessorStrategy extends AbstractStrategy implements BatchProcessorStrategyInterface
43
{
44
    /**
45
     * Constructor de la estrategia con sus dependencias.
46
     *
47
     * @param EntityComponentInterface $entityComponent
48
     */
49 1
    public function __construct(
50
        private EntityComponentInterface $entityComponent
51
    ) {
52 1
    }
53
54
    /**
55
     * {@inheritDoc}
56
     */
57 1
    public function process(DocumentBatchInterface $batch): array
58
    {
59
        // Cargar archivo CSV y obtener los datos.
60 1
        $datos = Csv::read($batch->getFile());
61 1
        $n_datos = count($datos);
62 1
        $documentos = [];
63 1
        $documento = [];
64
65
        // Procesar cada fila del archivo.
66 1
        for ($i = 1; $i < $n_datos; $i++) {
67
            // Si la fila corresponde a un documento nuevo.
68 1
            if (!empty($datos[$i][0])) {
69
                // Agregar el documento actual al listado si existe.
70 1
                if ($documento) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $documento of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
71 1
                    $documentos[] = $documento;
72
                }
73
                // Crear un nuevo documento.
74 1
                $documento = $this->createDocument($datos[$i]);
75
            } else {
76
                // Si la fila no corresponde a un documento nuevo, agregar
77
                // detalles al documento actual.
78 1
                if (!empty($datos[$i][13])) {
79 1
                    $datosItem = array_merge(
80
                        // Datos originales del item (vienen juntos en el
81
                        // archivo).
82 1
                        array_slice($datos[$i], 11, 8),
83
84
                        // Datos adicionales del item (vienen después del item,
85
                        // "al final", porque se añadieron después de los
86
                        // previos al archivo).
87 1
                        [
88
                            // CodImpAdic.
89 1
                            !empty($datos[$i][38]) ? $datos[$i][38] : null,
90 1
                        ]
91 1
                    );
92
93 1
                    $this->addItem($documento, $datosItem);
94
                }
95
96
                // Agregar referencias al documento.
97 1
                $this->addReference($documento, array_slice($datos[$i], 28, 5));
98
            }
99
        }
100
101
        // Agregar el último documento procesado al listado.
102 1
        $documentos[] = $documento;
103
104 1
        return $documentos;
0 ignored issues
show
introduced by
The expression return $documentos returns an array which contains values of type array which are incompatible with the return type libredte\lib\Core\Packag...tract\DocumentInterface mandated by libredte\lib\Core\Packag...egyInterface::process().
Loading history...
105
    }
106
107
    /**
108
     * Crea un documento a partir de los datos proporcionados.
109
     *
110
     * Verifica los datos mínimos requeridos y genera la estructura base.
111
     *
112
     * También agrega ítems, transporte y referencias al documento.
113
     *
114
     * @param array $datos Datos para crear el documento. Los índices corresponden a:
115
     *   - 0: Tipo de documento (obligatorio).
116
     *   - 1: Folio del documento (obligatorio).
117
     *   - 2: Fecha de emisión (opcional).
118
     *   - 3: Fecha de vencimiento (opcional).
119
     *   - 4: RUT del receptor (obligatorio).
120
     *   - 5: Razón social del receptor (obligatoria si no es boleta).
121
     *   - 6: Giro del receptor (obligatorio si no es boleta).
122
     *   - 7: Contacto del receptor (opcional).
123
     *   - 8: Correo del receptor (opcional, validado si se proporciona).
124
     *   - 9: Dirección del receptor (obligatoria si no es boleta).
125
     *   - 10: Comuna del receptor (obligatoria si no es boleta).
126
     *   - 33: Tipo de moneda (opcional, por defecto USD si aplica).
127
     *   - 34: Número de identificación del receptor extranjero (opcional).
128
     *   - 35: Descuento global (opcional, porcentaje o monto).
129
     *   - 36: Nombre del PDF (opcional).
130
     *   - 37: Forma de pago (opcional, 1, 2 o 3).
131
     *   - 38: Código de impuesto adicional (opcional).
132
     * @return array Estructura del documento generado.
133
     * @throws BatchProcessorException Si faltan datos mínimos o son inválidos.
134
     */
135 1
    private function createDocument(array $datos): array
136
    {
137
        // Verificar datos mínimos obligatorios.
138 1
        if (empty($datos[0])) {
139
            throw new BatchProcessorException('Falta tipo de documento.');
140
        }
141 1
        if (empty($datos[1])) {
142
            throw new BatchProcessorException('Falta folio del documento.');
143
        }
144 1
        if (empty($datos[4])) {
145
            throw new BatchProcessorException('Falta RUT del receptor.');
146
        }
147
148
        // Verificar datos si no es boleta.
149 1
        if (!in_array($datos[0], [39, 41])) {
150 1
            if (empty($datos[5])) {
151
                throw new BatchProcessorException(
152
                    'Falta razón social del receptor.'
153
                );
154
            }
155 1
            if (empty($datos[6])) {
156
                throw new BatchProcessorException(
157
                    'Falta giro del receptor.'
158
                );
159
            }
160 1
            if (empty($datos[9])) {
161
                throw new BatchProcessorException(
162
                    'Falta dirección del receptor.'
163
                );
164
            }
165 1
            if (empty($datos[10])) {
166
                throw new BatchProcessorException(
167
                    'Falta comuna del receptor.'
168
                );
169
            }
170
        }
171
172
        // Crear la estructura base del documento.
173 1
        $documento = $this->setInitialDTE($datos);
174
175
        // Validar correo electrónico.
176 1
        if (!empty($datos[8])) {
177 1
            if (!filter_var($datos[8], FILTER_VALIDATE_EMAIL)) {
178
                throw new BatchProcessorException(sprintf(
179
                    'Correo electrónico %s no es válido.',
180
                    $datos[8]
181
                ));
182
            }
183 1
            $documento['Encabezado']['Receptor']['CorreoRecep'] = mb_substr(
184 1
                trim($datos[8]),
185 1
                0,
186 1
                80
187 1
            );
188
        }
189
190
        // Manejar tipos de moneda para documentos de exportación.
191 1
        if (in_array($documento['Encabezado']['IdDoc']['TipoDTE'], [110,111,112])) {
192
            // Agregar moneda.
193 1
            if (empty($datos[33])) {
194 1
                $datos[33] = 'USD';
195
            }
196 1
            $moneda = $this->getCurrency($datos[33]);
197 1
            if (empty($moneda)) {
198
                throw new BatchProcessorException(
199
                    sprintf(
200
                        'El tipo de moneda %s no está permitido, solo: USD, EUR y CLP.',
201
                        $datos[33]
202
                    )
203
                );
204
            }
205 1
            $documento['Encabezado']['Totales']['TpoMoneda'] = $moneda;
206
207
            // Agregar ID del receptor.
208 1
            if (!empty($datos[34])) {
209 1
                $documento['Encabezado']['Receptor']['Extranjero']['NumId'] = mb_substr(
210 1
                    trim($datos[34]),
211 1
                    0,
212 1
                    20
213 1
                );
214
            }
215
        }
216
217
        // Procesar descuentos globales.
218 1
        if (!empty($datos[35])) {
219 1
            if (strpos($datos[35], '%')) {
220 1
                $TpoValor_global = '%';
221 1
                $ValorDR_global = (float)substr($datos[35], 0, -1);
222
            } else {
223 1
                $TpoValor_global = '$';
224 1
                $ValorDR_global = (float)$datos[35];
225
            }
226 1
            $documento['DscRcgGlobal'][] = [
227 1
                'TpoMov' => 'D',
228 1
                'TpoValor' => $TpoValor_global,
229 1
                'ValorDR' => $ValorDR_global,
230 1
                'IndExeDR' => 1,
231 1
            ];
232
        }
233
234
        // Asignar el nombre del PDF si se proporciona.
235
        // Esto permite asociar un archivo PDF específico al documento.
236 1
        if (!empty($datos[36])) {
237
            $documento['LibreDTE']['pdf']['nombre'] = $datos[36];
238
        }
239
240
        // Procesar forma de pago.
241 1
        if (!empty($datos[37])) {
242
            if (!in_array($datos[37], [1, 2, 3])) {
243
                throw new BatchProcessorException(sprintf(
244
                    'Forma de pago de código %s es incorrecta, debe ser: 1 (contado), 2 (crédito) o 3 (sin costo).',
245
                    $datos[37]
246
                ));
247
            }
248
            $documento['Encabezado']['IdDoc']['FmaPago'] = (int) $datos[37];
249
        }
250
251
        // Agregar ítems, transporte y referencias.
252 1
        $datosItem = array_merge(
253
            // Datos originales del item (vienen juntos en el archivo).
254 1
            array_slice($datos, 11, 8),
255
256
            // Datos adicionales del item (vienen después del item, "al final",
257
            // porque se añadieron después de los previos al archivo)
258 1
            [
259
                // CodImpAdic.
260 1
                !empty($datos[38]) ? $datos[38] : null,
261 1
            ]
262 1
        );
263
264 1
        $this->addItem($documento, $datosItem);
265 1
        $this->addTransport($documento, array_slice($datos, 22, 6));
266 1
        $this->addReference($documento, array_slice($datos, 28, 5));
267
268 1
        return $documento;
269
    }
270
271
    /**
272
     * Genera la estructura inicial del DTE.
273
     *
274
     * Este método crea un arreglo con la estructura base del DTE, incluyendo
275
     * encabezado, emisor, receptor y detalles. Configura valores
276
     * predeterminados para los campos opcionales y procesa algunos datos de
277
     * entrada.
278
     *
279
     * @param array $datos Datos de entrada para generar la estructura del DTE.
280
     * @return array Arreglo con la estructura inicial del DTE.
281
     */
282 1
    private function setInitialDTE(array $datos): array
283
    {
284 1
        return [
285 1
            'Encabezado' => [
286 1
                'IdDoc' => [
287 1
                    'TipoDTE' => (int) $datos[0],
288 1
                    'Folio' => (int) $datos[1],
289 1
                    'FchEmis' => (
290 1
                        !empty($datos[2]) && Date::validateAndConvert($datos[2], 'Y-m-d') !== null
291 1
                    ) ? $datos[2] : date('Y-m-d'),
292 1
                    'TpoTranCompra' => false,
293 1
                    'TpoTranVenta' => false,
294 1
                    'FmaPago' => false,
295 1
                    'FchCancel' => false,
296 1
                    'PeriodoDesde' => !empty($datos[20]) && Date::validateAndConvert($datos[20], 'Y-m-d') !== null
297 1
                        ? $datos[20]
298
                        : false,
299 1
                    'PeriodoHasta' => !empty($datos[21]) && Date::validateAndConvert($datos[21], 'Y-m-d') !== null
300 1
                        ? $datos[21]
301
                        : false,
302 1
                    'MedioPago' => false,
303 1
                    'TpoCtaPago' => false,
304 1
                    'NumCtaPago' => false,
305 1
                    'BcoPago' => false,
306 1
                    'TermPagoGlosa' => !empty($datos[19])
307 1
                        ? mb_substr(trim($datos[19]), 0, 100)
308
                        : false,
309 1
                    'FchVenc' => !empty($datos[3]) && Date::validateAndConvert($datos[3], 'Y-m-d') !== null
310 1
                        ? $datos[3]
311
                        : false,
312 1
                ],
313 1
                'Emisor' => [
314 1
                    'RUTEmisor' => false,
315 1
                    'RznSoc' => false,
316 1
                    'GiroEmis' => false,
317 1
                    'Telefono' => false,
318 1
                    'CorreoEmisor' => false,
319 1
                    'Acteco' => false,
320 1
                    'CdgSIISucur' => false,
321 1
                    'DirOrigen' => false,
322 1
                    'CmnaOrigen' => false,
323 1
                    'CdgVendedor' => false,
324 1
                ],
325 1
                'Receptor' => [
326 1
                    'RUTRecep' => str_replace('.', '', $datos[4]),
327 1
                    'CdgIntRecep' => false,
328 1
                    'RznSocRecep' => !empty($datos[5])
329 1
                        ? mb_substr(trim($datos[5]), 0, 100)
330
                        : false,
331 1
                    'GiroRecep' => !empty($datos[6])
332 1
                        ? mb_substr(trim($datos[6]), 0, 40)
333
                        : false,
334 1
                    'Contacto' => !empty($datos[7])
335 1
                        ? mb_substr(trim($datos[7]), 0, 80)
336
                        : false,
337 1
                    'CorreoRecep' => false,
338 1
                    'DirRecep' => !empty($datos[9])
339 1
                        ? mb_substr(trim($datos[9]), 0, 70)
340
                        : false,
341 1
                    'CmnaRecep' => !empty($datos[10])
342 1
                        ? mb_substr(trim($datos[10]), 0, 20)
343
                        : false,
344 1
                    'CiudadRecep' => false,
345 1
                ],
346 1
                'RUTSolicita' => false,
347 1
            ],
348 1
            'Detalle' => [],
349 1
        ];
350
351
    }
352
353
    /**
354
     * Agrega un ítem al documento.
355
     *
356
     * Procesa los datos de un ítem y lo agrega al arreglo de detalles. Valida
357
     * que los campos mínimos estén presentes y ajusta la longitud de los datos.
358
     *
359
     * @param array &$documento Documento al que se agregará el ítem. Modificado
360
     * directamente.
361
     * @param array $item  Datos del ítem. Los índices corresponden a:
362
     *   - 0: Código del ítem (opcional).
363
     *   - 1: Indicador de exención (opcional).
364
     *   - 2: Nombre del ítem (obligatorio).
365
     *   - 3: Descripción del ítem (opcional).
366
     *   - 4: Cantidad del ítem (obligatorio).
367
     *   - 5: Unidad de medida (opcional).
368
     *   - 6: Precio del ítem (obligatorio).
369
     *   - 7: Descuento (opcional, porcentaje o monto).
370
     *   - 8: Código de impuesto adicional (opcional).
371
     * @return void
372
     * @throws BatchProcessorException Si faltan datos obligatorios.
373
     */
374 1
    private function addItem(array &$documento, array $item): void
375
    {
376
        // Verificar datos mínimos obligatorios.
377 1
        if (empty($item[2])) {
378
            throw new BatchProcessorException(
379
                'Falta nombre del item.'
380
            );
381
        }
382 1
        if (empty($item[4])) {
383
            throw new BatchProcessorException(
384
                'Falta cantidad del item.'
385
            );
386
        }
387 1
        if (empty($item[6])) {
388
            throw new BatchProcessorException(
389
                'Falta precio del item.'
390
            );
391
        }
392
393
        // Crear el detalle del ítem.
394 1
        $detalle = [
395 1
            'NmbItem' => mb_substr(trim($item[2]), 0, 80),
396 1
            'QtyItem' => (float)str_replace(',', '.', $item[4]),
397 1
            'PrcItem' => (float)str_replace(',', '.', $item[6]),
398 1
        ];
399
400
        // Agregar código del ítem si está presente.
401 1
        if (!empty($item[0])) {
402 1
            $detalle['CdgItem'] = [
403 1
                'TpoCodigo' => 'INT1',
404 1
                'VlrCodigo' => mb_substr(trim($item[0]), 0, 35),
405 1
            ];
406
        }
407
408
        // Agregar indicador de exención si está presente.
409 1
        if (!empty($item[1])) {
410 1
            $detalle['IndExe'] = (int)$item[1];
411
        }
412
413
        // Agregar descripción del ítem si está presente.
414 1
        if (!empty($item[3])) {
415 1
            $detalle['DscItem'] = mb_substr(trim($item[3]), 0, 1000);
416
        }
417
418
        // Agregar unidad de medida si está presente.
419 1
        if (!empty($item[5])) {
420 1
            $detalle['UnmdItem'] = mb_substr(trim($item[5]), 0, 4);
421
        }
422
423
424
        // Procesar y agregar descuento si está presente.
425 1
        if (!empty($item[7])) {
426 1
            if (strpos($item[7], '%')) {
427 1
                $detalle['DescuentoPct'] = (float)substr($item[7], 0, -1);
428
            } else {
429 1
                $detalle['DescuentoMonto'] = (float)$item[7];
430
            }
431
        }
432
433
        // Agregar código de impuesto adicional si está presente.
434 1
        if (!empty($item[8])) {
435 1
            $detalle['CodImpAdic'] = (int)trim($item[8]);
436
        }
437
438
        // Agregar el detalle al documento.
439 1
        $documento['Detalle'][] = $detalle;
440
    }
441
442
    /**
443
     * Agrega información de transporte a un documento.
444
     *
445
     * Procesa los datos de transporte proporcionados y los agrega al arreglo
446
     * `Transporte` dentro del documento. Los datos incluyen información de
447
     * patente, transportista, chofer y destino.
448
     *
449
     * @param array &$documento Documento al que se agregará la información de
450
     * transporte. Se pasa por referencia para modificarlo.
451
     * @param array $transporte Datos de transporte a procesar. Los índices son:
452
     *   - 0: Patente del vehículo (opcional).
453
     *   - 1: RUT del transportista (opcional).
454
     *   - 2: RUT del chofer (opcional).
455
     *   - 3: Nombre del chofer (opcional).
456
     *   - 4: Dirección del destino (opcional).
457
     *   - 5: Comuna del destino (opcional).
458
     * @return void Modifica el documento directamente.
459
     */
460 1
    private function addTransport(array &$documento, array $transporte): void
461
    {
462 1
        $vacios = true;
463
464
        // Verificar si todos los datos de transporte están vacíos.
465 1
        foreach ($transporte as $t) {
466 1
            if (!empty($t)) {
467 1
                $vacios = false;
468
            }
469
        }
470 1
        if ($vacios) {
471 1
            return;
472
        }
473
474
        // Procesar cada dato de transporte y agregarlo al documento si está
475
        // presente.
476 1
        if ($transporte[0]) {
477 1
            $documento['Encabezado']['Transporte']['Patente'] = mb_substr(
478 1
                trim($transporte[0]),
479 1
                0,
480 1
                8
481 1
            );
482
        }
483 1
        if ($transporte[1]) {
484
            $documento['Encabezado']['Transporte']['RUTTrans'] = mb_substr(
485
                str_replace('.', '', trim($transporte[1])),
486
                0,
487
                10
488
            );
489
        }
490 1
        if ($transporte[2] && $transporte[3]) {
491
            $documento['Encabezado']['Transporte']['Chofer']['RUTChofer'] =
492
                mb_substr(
493
                    str_replace('.', '', trim($transporte[2])),
494
                    0,
495
                    10
496
                )
497
            ;
498
            $documento['Encabezado']['Transporte']['Chofer']['NombreChofer'] =
499
                mb_substr(
500
                    trim($transporte[3]),
501
                    0,
502
                    30
503
                )
504
            ;
505
        }
506 1
        if ($transporte[4]) {
507 1
            $documento['Encabezado']['Transporte']['DirDest'] = mb_substr(
508 1
                trim($transporte[4]),
509 1
                0,
510 1
                70
511 1
            );
512
        }
513 1
        if ($transporte[5]) {
514 1
            $documento['Encabezado']['Transporte']['CmnaDest'] = mb_substr(
515 1
                trim($transporte[5]),
516 1
                0,
517 1
                20
518 1
            );
519
        }
520
    }
521
522
    /**
523
     * Agrega una referencia a un documento.
524
     *
525
     * Procesa los datos de referencia y los agrega al arreglo `Referencia`
526
     * dentro del documento. Valida los campos obligatorios y ajusta su longitud
527
     * si es necesario.
528
     *
529
     * @param array &$documento Documento al que se agregará la referencia.
530
     * Se pasa por referencia para modificarlo.
531
     * @param array $referencia Datos de la referencia a agregar. Los índices
532
     * deben ser:
533
     *   - 0: Tipo del documento referenciado (obligatorio).
534
     *   - 1: Folio del documento referenciado (obligatorio).
535
     *   - 2: Fecha del documento en formato AAAA-MM-DD (obligatorio).
536
     *   - 3: Código de referencia (opcional).
537
     *   - 4: Razón de la referencia (opcional).
538
     * @return void Modifica el documento directamente.
539
     * @throws BatchProcessorException Si algún campo obligatorio está vacío o
540
     * no es válido.
541
     */
542 1
    private function addReference(array &$documento, array $referencia): void
543
    {
544 1
        $Referencia = [];
545 1
        $vacios = true;
546 1
        foreach ($referencia as $r) {
547 1
            if (!empty($r)) {
548 1
                $vacios = false;
549
            }
550
        }
551 1
        if ($vacios) {
552 1
            return;
553
        }
554 1
        if (empty($referencia[0])) {
555
            throw new BatchProcessorException(
556
                'Tipo del documento de referencia no puede estar vacío.'
557
            );
558
        }
559 1
        $Referencia['TpoDocRef'] = mb_substr(trim($referencia[0]), 0, 3);
560 1
        if (empty($referencia[1])) {
561
            throw new BatchProcessorException(
562
                'Folio del documento de referencia no puede estar vacío.'
563
            );
564
        }
565 1
        $Referencia['FolioRef'] = mb_substr(trim($referencia[1]), 0, 18);
566
567
        if (
568 1
            empty($referencia[2])
569 1
            && Date::validateAndConvert($referencia[2], 'Y-m-d') !== null
570
        ) {
571
            throw new BatchProcessorException(
572
                'Fecha del documento de referencia debe ser en formato AAAA-MM-DD.'
573
            );
574
        }
575 1
        $Referencia['FchRef'] = $referencia[2];
576 1
        if (!empty($referencia[3])) {
577 1
            $Referencia['CodRef'] = (int) $referencia[3];
578
        }
579 1
        if (!empty($referencia[4])) {
580 1
            $Referencia['RazonRef'] = mb_substr(trim($referencia[4]), 0, 90);
581
        }
582 1
        $documento['Referencia'][] = $Referencia;
583
    }
584
585
    /**
586
     * Obtiene la glosa de una moneda a partir de su código ISO.
587
     *
588
     * Este método busca en el repositorio de la entidad `AduanaMoneda` un
589
     * registro que coincida con el código ISO proporcionado. Si encuentra un
590
     * resultado, devuelve la glosa asociada; de lo contrario, retorna `null`.
591
     *
592
     * @param string $moneda Código ISO de la moneda que se desea buscar.
593
     * @return string|null La glosa de la moneda o `null` si no existe.
594
     */
595 1
    private function getCurrency(string $moneda): ?string
596
    {
597
        // Buscar la moneda a través del repositorio.
598 1
        $result = $this->entityComponent
599 1
            ->getRepository(AduanaMoneda::class)
600 1
            ->findBy([
601 1
                'codigo_iso' => $moneda,
602 1
            ]);
603
604
        // Retornar null si no se encuentra ningún resultado.
605 1
        if (empty($result)) {
606
            return null;
607
        }
608
609
        // Retornar la glosa de la primera coincidencia.
610 1
        return $result[0]->getGlosa();
611
    }
612
}
613