DocumentBag::withCaf()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 12
c 1
b 0
f 0
dl 0
loc 15
ccs 13
cts 13
cp 1
rs 9.8666
cc 1
nc 1
nop 1
crap 1
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\Support;
26
27
use Derafu\Lib\Core\Common\Trait\OptionsAwareTrait;
28
use Derafu\Lib\Core\Helper\Arr;
29
use Derafu\Lib\Core\Package\Prime\Component\Certificate\Contract\CertificateInterface;
30
use Derafu\Lib\Core\Package\Prime\Component\Xml\Contract\XmlInterface;
31
use Derafu\Lib\Core\Support\Store\Contract\DataContainerInterface;
32
use libredte\lib\Core\Package\Billing\Component\Document\Contract\DocumentBagInterface;
33
use libredte\lib\Core\Package\Billing\Component\Document\Contract\DocumentInterface;
34
use libredte\lib\Core\Package\Billing\Component\Document\Contract\TipoDocumentoInterface;
35
use libredte\lib\Core\Package\Billing\Component\Document\Exception\DocumentException;
36
use libredte\lib\Core\Package\Billing\Component\Identifier\Contract\CafInterface;
37
use libredte\lib\Core\Package\Billing\Component\TradingParties\Contract\EmisorInterface;
38
use libredte\lib\Core\Package\Billing\Component\TradingParties\Contract\ReceptorInterface;
39
use LogicException;
40
use stdClass;
41
42
/**
43
 * Contenedor de datos del documento tributario electrónico.
44
 *
45
 * Permite "mover" un documento, junto a otros datos asociados, por métodos de
46
 * manera sencilla y, sobre todo, extensible.
47
 */
48
class DocumentBag implements DocumentBagInterface
49
{
50
    use OptionsAwareTrait;
51
52
    /**
53
     * Reglas de esquema de las opciones del documento.
54
     *
55
     * Acá solo se indicarán los índices que deben pueden existir en las
56
     * opciones. No se define el esquema de cada opción pues cada clase que
57
     * utilice estas opciones deberá resolver y validar sus propias opciones.
58
     *
59
     * @var array
60
     */
61
    protected array $optionsSchema = [
62
        'builder' => [
63
            'types' => 'array',
64
            'default' => [],
65
        ],
66
        'normalizer' => [
67
            'types' => 'array',
68
            'default' => [],
69
        ],
70
        'parser' => [
71
            'types' => 'array',
72
            'default' => [],
73
        ],
74
        'renderer' => [
75
            'types' => 'array',
76
            'default' => [],
77
        ],
78
        'sanitizer' => [
79
            'types' => 'array',
80
            'default' => [],
81
        ],
82
        'validator' => [
83
            'types' => 'array',
84
            'default' => [],
85
        ],
86
    ];
87
88
    /**
89
     * Datos originales de entrada que se utilizarán para construir el
90
     * documento tributario.
91
     *
92
     * El formato de estos datos puede ser cualquiera soportado por los parsers.
93
     *
94
     * @var string|null
95
     */
96
    private ?string $inputData;
97
98
    /**
99
     * Datos de entrada procesados (parseados).
100
     *
101
     * Están en el formato estándar de LibreDTE. Que es básicamente el oficial
102
     * del SII.
103
     *
104
     * Estos son los datos que se usarán para construir el documento. Estos
105
     * datos no están normaliados, solo parseados.
106
     *
107
     * @var array|null
108
     */
109
    private ?array $parsedData;
110
111
    /**
112
     * Datos normalizados del documento tributario.
113
     *
114
     * Son los datos con todos sus campos necesarios ya determinados, calculados
115
     * y validados.
116
     *
117
     * La estructura de estos datos depende de los normalizadores.
118
     *
119
     * Importante: si se desactiva la normalización este arreglo contendrá lo
120
     * mismo que $parsedData pues no se tocarán los datos de entrada procesados.
121
     *
122
     * @var array|null
123
     */
124
    private ?array $normalizedData;
125
126
    /**
127
     * Datos de LibreDTE asociados al documento tributario.
128
     *
129
     * Estos son datos que LibreDTE utiliza asociados al documento pero no son
130
     * parte de la estructura oficial que utiliza el SII.
131
     *
132
     * Por ejemplo se puede incluir:
133
     *
134
     *   - Tags de facturas en PDF de boletas. Ejemplo: TermPagoGlosa.
135
     *   - Datos adicionales para los PDF. Ejemplo: historial.
136
     *
137
     * @var array|null
138
     */
139
    private ?array $libredteData;
140
141
    /**
142
     * Instancia del documento XML asociada al DTE.
143
     *
144
     * @var XmlInterface|null
145
     */
146
    private ?XmlInterface $xmlDocument;
147
148
    /**
149
     * Código de Asignación de Folios (CAF) para timbrar el Documento Tributario
150
     * Electrónico (DTE) que se generará.
151
     *
152
     * @var CafInterface|null
153
     */
154
    private ?CafInterface $caf;
155
156
    /**
157
     * Certificado digital (firma electrónica) para la firma del documento.
158
     *
159
     * @var CertificateInterface|null
160
     */
161
    private ?CertificateInterface $certificate;
162
163
    /**
164
     * Entidad con el documento tributario electrónico generado.
165
     *
166
     * @var DocumentInterface|null
167
     */
168
    private ?DocumentInterface $document;
169
170
    /**
171
     * Entidad que representa al tipo de documento tributario que está contenido
172
     * en esta bolsa.
173
     *
174
     * @var TipoDocumentoInterface|null
175
     */
176
    private ?TipoDocumentoInterface $documentType = null;
177
178
    /**
179
     * Emisor del documento tributario.
180
     *
181
     * @var EmisorInterface|null
182
     */
183
    private ?EmisorInterface $emisor = null;
184
185
    /**
186
     * Receptor del documento tributario.
187
     *
188
     * @var ReceptorInterface|null
189
     */
190
    private ?ReceptorInterface $receptor = null;
191
192
    /**
193
     * Arreglo con la estructura del nodo TED del documento.
194
     *
195
     * @var array|null
196
     */
197
    private ?array $timbre = null;
198
199
    /**
200
     * Arreglo con los datos normalizados consolidados con el timbre y la firma
201
     * si existen en la bolsa.
202
     *
203
     * @var array|null
204
     */
205
    private ?array $data = null;
206
207
    /**
208
     * Constructor del contenedor.
209
     *
210
     * Recibe los datos en diferentes formatos para pasarlos a los setters que
211
     * los normalizan y asignan al contenedor.
212
     *
213
     * @param string|array|stdClass|null $inputData
214
     * @param array|null $parsedData
215
     * @param array|null $normalizedData
216
     * @param array|null $libredteData
217
     * @param array|DataContainerInterface $options
218
     * @param XmlInterface|null $xmlDocument
219
     * @param CafInterface|null $caf
220
     * @param CertificateInterface|null $certificate
221
     * @param DocumentInterface|null $document
222
     * @param TipoDocumentoInterface|null $documentType
223
     * @param EmisorInterface|null $emisor
224
     * @param ReceptorInterface|null $receptor
225
     */
226 121
    public function __construct(
227
        string|array|stdClass $inputData = null,
228
        array $parsedData = null,
229
        array $normalizedData = null,
230
        array $libredteData = null,
231
        array|DataContainerInterface $options = [],
232
        XmlInterface $xmlDocument = null,
233
        CafInterface $caf = null,
234
        CertificateInterface $certificate = null,
235
        DocumentInterface $document = null,
236
        TipoDocumentoInterface $documentType = null,
237
        EmisorInterface $emisor = null,
238
        ReceptorInterface $receptor = null
239
    ) {
240 121
        $this
241 121
            ->setInputData($inputData)
242 121
            ->setParsedData($parsedData)
243 121
            ->setNormalizedData($normalizedData)
244 121
            ->setLibredteData($libredteData)
245 121
            ->setOptions($options)
246 121
            ->setXmlDocument($xmlDocument)
247 121
            ->setCaf($caf)
248 121
            ->setCertificate($certificate)
249 121
            ->setDocument($document)
250 121
            ->setDocumentType($documentType)
251 121
            ->setEmisor($emisor)
252 121
            ->setReceptor($receptor)
253 121
        ;
254
    }
255
256
    /**
257
     * {@inheritDoc}
258
     */
259 121
    public function setInputData(string|array|stdClass|null $inputData): static
260
    {
261 121
        if ($inputData === null) {
0 ignored issues
show
introduced by
The condition $inputData === null is always false.
Loading history...
262 112
            $this->inputData = null;
263
264 112
            return $this;
265
        }
266
267 62
        if (!is_string($inputData)) {
0 ignored issues
show
introduced by
The condition is_string($inputData) is always false.
Loading history...
268 6
            $inputData = json_encode($inputData);
269
        }
270
271 62
        $this->inputData = $inputData;
272
273 62
        return $this;
274
    }
275
276
    /**
277
     * {@inheritDoc}
278
     */
279 121
    public function getInputData(): ?string
280
    {
281 121
        return $this->inputData;
282
    }
283
284
    /**
285
     * {@inheritDoc}
286
     */
287 121
    public function setParsedData(?array $parsedData): static
288
    {
289 121
        $this->parsedData = $parsedData;
290
291 121
        return $this;
292
    }
293
294
    /**
295
     * {@inheritDoc}
296
     */
297 120
    public function getParsedData(): ?array
298
    {
299 120
        return $this->parsedData;
300
    }
301
302
    /**
303
     * {@inheritDoc}
304
     */
305 121
    public function setNormalizedData(?array $normalizedData): static
306
    {
307 121
        $this->normalizedData = $normalizedData;
308
309 121
        return $this;
310
    }
311
312
    /**
313
     * {@inheritDoc}
314
     */
315 116
    public function getNormalizedData(): ?array
316
    {
317 116
        return $this->normalizedData;
318
    }
319
320
    /**
321
     * {@inheritDoc}
322
     */
323 121
    public function setLibredteData(?array $libredteData): static
324
    {
325 121
        $this->libredteData = $libredteData;
326
327 121
        return $this;
328
    }
329
330
    /**
331
     * {@inheritDoc}
332
     */
333 53
    public function getLibredteData(): ?array
334
    {
335 53
        return $this->libredteData;
336
    }
337
338
    /**
339
     * {@inheritDoc}
340
     */
341 62
    public function getParserOptions(): array
342
    {
343 62
        return (array) $this->getOptions()->get('parser');
344
    }
345
346
    /**
347
     * {@inheritDoc}
348
     */
349 103
    public function getBuilderOptions(): array
350
    {
351 103
        return (array) $this->getOptions()->get('builder');
352
    }
353
354
    /**
355
     * {@inheritDoc}
356
     */
357 107
    public function getNormalizerOptions(): array
358
    {
359 107
        return (array) $this->getOptions()->get('normalizer');
360
    }
361
362
    /**
363
     * {@inheritDoc}
364
     */
365
    public function getSanitizerOptions(): array
366
    {
367
        return (array) $this->getOptions()->get('sanitizer');
368
    }
369
370
    /**
371
     * {@inheritDoc}
372
     */
373
    public function getValidatorOptions(): array
374
    {
375
        return (array) $this->getOptions()->get('validator');
376
    }
377
378
    /**
379
     * {@inheritDoc}
380
     */
381 103
    public function getRendererOptions(): array
382
    {
383 103
        return (array) $this->getOptions()->get('renderer');
384
    }
385
386
    /**
387
     * {@inheritDoc}
388
     */
389 121
    public function setXmlDocument(?XmlInterface $xmlDocument): static
390
    {
391 121
        $this->xmlDocument = $xmlDocument;
392
393 121
        return $this;
394
    }
395
396
    /**
397
     * {@inheritDoc}
398
     */
399 116
    public function getXmlDocument(): ?XmlInterface
400
    {
401 116
        return $this->xmlDocument;
402
    }
403
404
    /**
405
     * {@inheritDoc}
406
     */
407 121
    public function setCaf(?CafInterface $caf): static
408
    {
409 121
        $this->caf = $caf;
410
411 121
        return $this;
412
    }
413
414
    /**
415
     * {@inheritDoc}
416
     */
417 107
    public function getCaf(): ?CafInterface
418
    {
419 107
        return $this->caf;
420
    }
421
422
    /**
423
     * {@inheritDoc}
424
     */
425 121
    public function setCertificate(?CertificateInterface $certificate): static
426
    {
427 121
        $this->certificate = $certificate;
428
429 121
        return $this;
430
    }
431
432
    /**
433
     * {@inheritDoc}
434
     */
435 107
    public function getCertificate(): ?CertificateInterface
436
    {
437 107
        return $this->certificate;
438
    }
439
440
    /**
441
     * {@inheritDoc}
442
     */
443 121
    public function setDocument(?DocumentInterface $document): static
444
    {
445 121
        $this->document = $document;
446
447 121
        return $this;
448
    }
449
450
    /**
451
     * {@inheritDoc}
452
     */
453 116
    public function getDocument(): ?DocumentInterface
454
    {
455 116
        return $this->document;
456
    }
457
458
    /**
459
     * {@inheritDoc}
460
     */
461 121
    public function setDocumentType(?TipoDocumentoInterface $documentType): static
462
    {
463 121
        $this->documentType = $documentType;
464
465 121
        return $this;
466
    }
467
468
    /**
469
     * {@inheritDoc}
470
     */
471 117
    public function setTipoDocumento(?TipoDocumentoInterface $tipoDocumento): static
472
    {
473 117
        return $this->setDocumentType($tipoDocumento);
474
    }
475
476
    /**
477
     * {@inheritDoc}
478
     */
479 120
    public function getDocumentType(): ?TipoDocumentoInterface
480
    {
481 120
        return $this->documentType;
482
    }
483
484
    /**
485
     * {@inheritDoc}
486
     */
487 120
    public function getTipoDocumento(): ?TipoDocumentoInterface
488
    {
489 120
        return $this->getDocumentType();
490
    }
491
492
    /**
493
     * {@inheritDoc}
494
     */
495 120
    public function getDocumentTypeId(): ?int
496
    {
497 120
        $TipoDTE = $this->parsedData['Encabezado']['IdDoc']['TipoDTE']
498 120
            ?? $this->normalizedData['Encabezado']['IdDoc']['TipoDTE']
499 120
            ?? $this->xmlDocument?->query('//Encabezado/IdDoc/TipoDTE')
500 120
            ?? $this->document?->getCodigo()
501 113
            ?? null
502 120
        ;
503
504 120
        if (!$TipoDTE) {
505 2
            throw new DocumentException(
506 2
                'Falta indicar el tipo de documento (TipoDTE) en los datos del DTE.'
507 2
            );
508
        }
509
510 118
        return (int) $TipoDTE;
511
    }
512
513
    /**
514
     * {@inheritDoc}
515
     */
516 120
    public function getCodigoTipoDocumento(): ?int
517
    {
518 120
        return $this->getDocumentTypeId();
519
    }
520
521
    /**
522
     * {@inheritDoc}
523
     */
524 121
    public function setEmisor(?EmisorInterface $emisor): static
525
    {
526 121
        $this->emisor = $emisor;
527
528 121
        return $this;
529
    }
530
531
    /**
532
     * {@inheritDoc}
533
     */
534 116
    public function getEmisor(): ?EmisorInterface
535
    {
536 116
        return $this->emisor;
537
    }
538
539
    /**
540
     * {@inheritDoc}
541
     */
542 121
    public function setReceptor(?ReceptorInterface $receptor): static
543
    {
544 121
        $this->receptor = $receptor;
545
546 121
        return $this;
547
    }
548
549
    /**
550
     * {@inheritDoc}
551
     */
552 116
    public function getReceptor(): ?ReceptorInterface
553
    {
554 116
        return $this->receptor;
555
    }
556
557
    /**
558
     * {@inheritDoc}
559
     */
560 103
    public function setTimbre(?array $timbre): static
561
    {
562 103
        $this->timbre = $timbre;
563
564 103
        return $this;
565
    }
566
567
    /**
568
     * {@inheritDoc}
569
     */
570 107
    public function getTimbre(): ?array
571
    {
572 107
        return $this->timbre;
573
    }
574
575
    /**
576
     * {@inheritDoc}
577
     */
578 107
    public function getData(): ?array
579
    {
580
        // Si los datos ya estaban generados se entregan.
581 107
        if ($this->data !== null) {
582
            return $this->data;
583
        }
584
585
        // Si no hay datos normalizados se entrega `null`.
586 107
        if (!$this->getNormalizedData()) {
587
            return null;
588
        }
589
590
        // Se arma la estructura del nodo Documento.
591 107
        $tagXml = $this->getTipoDocumento()->getTagXml()->getNombre();
592 107
        $this->data = [
593 107
            'DTE' => [
594 107
                '@attributes' => [
595 107
                    'version' => '1.0',
596 107
                    'xmlns' => 'http://www.sii.cl/SiiDte',
597 107
                ],
598 107
                $tagXml => array_merge(
599 107
                    [
600 107
                        '@attributes' => [
601 107
                            'ID' => $this->getId(),
602 107
                        ],
603 107
                    ],
604 107
                    $this->getNormalizedData(),
605 107
                    (array) $this->getTimbre(),
606 107
                ),
607 107
                //'Signature' => '', // Se agrega al firmar (NO INCLUIR ACÁ).
608 107
            ],
609 107
        ];
610
611
        // Se entrega la estructura con los datos.
612 107
        return $this->data;
613
    }
614
615
    /**
616
     * {@inheritDoc}
617
     */
618 103
    public function getDocumentData(): ?array
619
    {
620 103
        if (!isset($this->document)) {
621
            return null;
622
        }
623
624 103
        $documentData = $this->document->getDatos();
0 ignored issues
show
Bug introduced by
The method getDatos() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

624
        /** @scrutinizer ignore-call */ 
625
        $documentData = $this->document->getDatos();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
625 103
        $documentExtra = $this->libredteData['extra']['dte'] ?? null;
626
627 103
        if (empty($documentExtra)) {
628 102
            return $documentData;
629
        }
630
631 1
        return Arr::mergeRecursiveDistinct($documentData, $documentExtra);
632
    }
633
634
    /**
635
     * {@inheritDoc}
636
     */
637 103
    public function getDocumentExtra(): ?array
638
    {
639 103
        if (!isset($this->document)) {
640
            return null;
641
        }
642
643 103
        $extra = $this->libredteData['extra'] ?? null;
644
645 103
        if (empty($extra)) {
646 102
            return null;
647
        }
648
649 1
        unset($extra['dte']);
650
651 1
        return $extra;
652
    }
653
654
    /**
655
     * {@inheritDoc}
656
     */
657 103
    public function getDocumentStamp(): ?string
658
    {
659 103
        return $this->document?->getTED();
660
    }
661
662
    /**
663
     * {@inheritDoc}
664
     */
665 103
    public function getDocumentAuth(): ?array
666
    {
667 103
        return $this->emisor?->getAutorizacionDte()?->toArray();
668
    }
669
670
    /**
671
     * {@inheritDoc}
672
     */
673 107
    public function getId(): string
674
    {
675 107
        $folio = $this->getFolio();
676
677 107
        if (is_int($folio)) {
678 103
            return sprintf(
679 103
                'LibreDTE_%s_T%03dF%09d',
680 103
                $this->getNormalizedData()['Encabezado']['Emisor']['RUTEmisor'],
681 103
                $this->getNormalizedData()['Encabezado']['IdDoc']['TipoDTE'],
682 103
                $folio
683 103
            );
684
        } else {
685 52
            return sprintf(
686 52
                'LibreDTE_%s_%03d-%s',
687 52
                $this->getNormalizedData()['Encabezado']['Emisor']['RUTEmisor'],
688 52
                $this->getNormalizedData()['Encabezado']['IdDoc']['TipoDTE'],
689 52
                $folio
690 52
            );
691
        }
692
    }
693
694
    /**
695
     * {@inheritDoc}
696
     */
697 52
    public function setFolio(int $folio): static
698
    {
699 52
        if ($this->getXmlDocument()) {
700
            throw new LogicException(
701
                'No es posible asignar el folio si ya se generó el documento XML.'
702
            );
703
        }
704
705 52
        $parsedData = $this->getParsedData();
706 52
        $normalizedData = $this->getNormalizedData();
707
708 52
        if ($parsedData === null && $normalizedData === null) {
709
            throw new LogicException(
710
                'No es posible asignar el folio si no existen datos parseados o normalizados.'
711
            );
712
        }
713
714 52
        if ($parsedData !== null) {
715 52
            $parsedData['Encabezado']['IdDoc']['Folio'] = $folio;
716 52
            $this->setParsedData($parsedData);
717
        }
718
719 52
        if ($normalizedData !== null) {
720 52
            $normalizedData['Encabezado']['IdDoc']['Folio'] = $folio;
721 52
            $this->setNormalizedData($normalizedData);
722
        }
723
724 52
        return $this;
725
    }
726
727
    /**
728
     * {@inheritDoc}
729
     */
730 107
    public function getFolio(): int|string|null
731
    {
732 107
        $data = $this->getNormalizedData() ?? $this->getParsedData();
733
734 107
        $folio = $data['Encabezado']['IdDoc']['Folio'];
735
736 107
        if (!$folio) {
737 52
            return null;
738
        }
739
740 103
        return is_numeric($folio) ? (int) $folio : (string) $folio;
741
    }
742
743
    /**
744
     * {@inheritDoc}
745
     */
746 52
    public function withCaf(CafInterface $caf): DocumentBagInterface
747
    {
748 52
        $class = static::class;
749
750 52
        return new $class(
751 52
            inputData: $this->getInputData(),
752 52
            parsedData: $this->getParsedData(),
753 52
            normalizedData: $this->getNormalizedData(),
754 52
            libredteData: $this->getLibredteData(),
755 52
            options: $this->getOptions(),
756 52
            caf: $caf,
757 52
            certificate: $this->getCertificate(),
758 52
            documentType: $this->getDocumentType(),
759 52
            emisor: $this->getEmisor(),
760 52
            receptor: $this->getReceptor()
761 52
        );
762
    }
763
764
    /**
765
     * {@inheritDoc}
766
     */
767 52
    public function withCertificate(
768
        CertificateInterface $certificate
769
    ): DocumentBagInterface {
770 52
        $class = static::class;
771
772 52
        return new $class(
773 52
            inputData: $this->getInputData(),
774 52
            parsedData: $this->getParsedData(),
775 52
            normalizedData: $this->getNormalizedData(),
776 52
            libredteData: $this->getLibredteData(),
777 52
            options: $this->getOptions(),
778 52
            caf: $this->getCaf(),
779 52
            certificate: $certificate,
780 52
            documentType: $this->getDocumentType(),
781 52
            emisor: $this->getEmisor(),
782 52
            receptor: $this->getReceptor()
783 52
        );
784
    }
785
786
    /**
787
     * {@inheritDoc}
788
     */
789 109
    public function getAlias(): string
790
    {
791 109
        return $this->getTipoDocumento()?->getAlias()
792 109
            ?? (
793 109
                $this->getTipoDocumento()?->getCodigo()
794 1
                    ? 'documento_' .  $this->getTipoDocumento()->getCodigo()
795 2
                    : null
796 109
            )
797 109
            ?? $this->getParsedData()['Encabezado']['IdDoc']['TipoDTE']
798 109
            ?? 'documento_desconocido'
799 109
        ;
800
    }
801
}
802