CsvBatchProcessorStrategy::createDocument()   F
last analyzed

Complexity

Conditions 21
Paths 377

Size

Total Lines 134
Code Lines 69

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 53
CRAP Score 44.536

Importance

Changes 0
Metric Value
cc 21
eloc 69
c 0
b 0
f 0
nc 377
nop 1
dl 0
loc 134
ccs 53
cts 85
cp 0.6235
crap 44.536
rs 1.1208

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