From e5873333bef068bdf4818903ac1afe6257bf1906 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Sat, 5 Mar 2022 01:02:06 -0600 Subject: [PATCH 1/6] Change how to detect how many lines to skip Now it is based on the last common line. Previously it was about the same first lines --- src/Converters/CsvFolderJoinFiles.php | 47 +++++++++++++++------------ 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/src/Converters/CsvFolderJoinFiles.php b/src/Converters/CsvFolderJoinFiles.php index c271bd3..ac3268f 100644 --- a/src/Converters/CsvFolderJoinFiles.php +++ b/src/Converters/CsvFolderJoinFiles.php @@ -78,6 +78,7 @@ function ($path): array { /** * @param array{destination: string, index: int} $first * @param array{destination: string, index: int} $second + * @return int */ private function compareFiles(array $first, array $second): int { @@ -97,42 +98,46 @@ public function writeLines(string $source, string $destination, int $skipFirstLi public function findLinesToSkip(string $firstPath, string $secondPath): int { - $lines = 0; $first = new SplFileObject($firstPath, 'r'); $second = new SplFileObject($secondPath, 'r'); - while ($this->splCurrentLinesAreEqual($first, $second)) { - $first->next(); - $second->next(); - $lines = $lines + 1; + + $firstTenLines = $this->splReadTenLines($first); + $secondTenLines = $this->splReadTenLines($second); + + for ($i = 9; $i > 0; $i--) { + $firstValue = $firstTenLines[$i] ?? null; + $secondValue = $secondTenLines[$i] ?? null; + if (null !== $firstValue && null !== $secondValue && $firstValue === $secondValue) { + return $i + 1; + } } - return $lines; + return 0; } /** - * @param Iterator $first - * @param Iterator $second + * @param Iterator $iterator + * @return array */ - private function splCurrentLinesAreEqual(Iterator $first, Iterator $second): bool + private function splReadTenLines(Iterator $iterator): array { - if (! $first->valid() || ! $second->valid()) { - return false; + $result = []; + $counter = 0; + foreach ($iterator as $line) { + $result[] = $this->splCurrentLinesNormalizeValue($line); + $counter = $counter + 1; + if (10 === $counter) { + break; + } } - $firstValue = $this->splCurrentLinesAreEqualNormalizeValue($first->current()); - $secondValue = $this->splCurrentLinesAreEqualNormalizeValue($second->current()); - return ($firstValue === $secondValue); + return $result; } - private function splCurrentLinesAreEqualNormalizeValue(mixed $current): mixed + private function splCurrentLinesNormalizeValue(string $current): string { - if (! is_string($current)) { - return $current; - } return trim(implode(',', array_map('trim', explode(',', rtrim($current, ','))))); } - /** - * @param string[] $searchterms - */ + /** @param string[] $searchterms */ public function lastLineContains(string $filename, array $searchterms): bool { $lastline = $this->obtainFileLastLine($filename); From bd5142625de9bd951bbf24a20e8e38c2a19bcce2 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Sat, 5 Mar 2022 02:42:32 -0600 Subject: [PATCH 2/6] Add origin for CFDI 4.0. Use wildcard to match link text for version 3.3 and 4.0 --- src/Commands/DumpOrigins.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Commands/DumpOrigins.php b/src/Commands/DumpOrigins.php index 2c3271c..a3a7826 100644 --- a/src/Commands/DumpOrigins.php +++ b/src/Commands/DumpOrigins.php @@ -20,7 +20,13 @@ public function run(): int 'CFDI', 'http://omawww.sat.gob.mx/tramitesyservicios/Paginas/anexo_20_version3-3.htm', 'catCFDI.xls', - 'Catálogos CFDI Versión 3.3(xls)', + 'Catálogos CFDI Versión 3.3*', + ), + new ScrapingOrigin( + 'CFDI', + 'http://omawww.sat.gob.mx/tramitesyservicios/Paginas/anexo_20_version3-3.htm', + 'cfdi_40.xls', + 'Catálogos CFDI Versión 4.0*', ), new ConstantOrigin('Nóminas', "{$common}/catNomina.xls"), new ConstantOrigin('Nóminas - Estados', "{$common}/C_Estado.xls", null, 'nominas_estados.xls'), From 5fb3378ef7dcdb46dd004afde7f95e0e631723c5 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Sat, 5 Mar 2022 02:44:32 -0600 Subject: [PATCH 3/6] Add 25 catalogs from CFDI 4.0 --- src/Importers/Cfdi40/Injectors/Aduanas.php | 43 ++ .../Cfdi40/Injectors/ClavesUnidades.php | 54 ++ .../Cfdi40/Injectors/CodigosPostales.php | 95 +++ src/Importers/Cfdi40/Injectors/Colonias.php | 38 + src/Importers/Cfdi40/Injectors/Estados.php | 46 ++ .../Cfdi40/Injectors/Exportaciones.php | 40 ++ .../Cfdi40/Injectors/FormasDePago.php | 78 ++ src/Importers/Cfdi40/Injectors/Impuestos.php | 55 ++ .../Cfdi40/Injectors/Localidades.php | 47 ++ src/Importers/Cfdi40/Injectors/Meses.php | 40 ++ .../Cfdi40/Injectors/MetodosDePago.php | 47 ++ src/Importers/Cfdi40/Injectors/Monedas.php | 52 ++ src/Importers/Cfdi40/Injectors/Municipios.php | 47 ++ .../Injectors/NumerosPedimentoAduana.php | 57 ++ .../Cfdi40/Injectors/ObjetosDeImpuestos.php | 40 ++ src/Importers/Cfdi40/Injectors/Paises.php | 62 ++ .../Cfdi40/Injectors/PatentesAduanales.php | 45 ++ .../Cfdi40/Injectors/Periodicidades.php | 40 ++ .../Cfdi40/Injectors/ProductosServicios.php | 59 ++ .../Cfdi40/Injectors/RegimenesFiscales.php | 52 ++ .../Cfdi40/Injectors/ReglasTasaCuota.php | 73 ++ .../Cfdi40/Injectors/TiposComprobantes.php | 72 ++ .../Cfdi40/Injectors/TiposFactores.php | 45 ++ .../Cfdi40/Injectors/TiposRelaciones.php | 48 ++ src/Importers/Cfdi40/Injectors/UsosCfdi.php | 64 ++ src/Importers/Cfdi40Catalogs.php | 41 ++ .../Importers/SourcesImporterTest.php | 25 + .../Cfdi40/Injectors/AduanasTest.php | 60 ++ .../Cfdi40/Injectors/ClavesUnidadesTest.php | 66 ++ .../Cfdi40/Injectors/CodigosPostalesTest.php | 88 +++ .../Cfdi40/Injectors/ColoniasTest.php | 68 ++ .../Cfdi40/Injectors/EstadosTest.php | 70 ++ .../Cfdi40/Injectors/ExportacionesTest.php | 68 ++ .../Cfdi40/Injectors/FormasDePagoTest.php | 228 ++++++ .../Cfdi40/Injectors/ImpuestosTest.php | 111 +++ .../Cfdi40/Injectors/LocalidadesTest.php | 71 ++ .../Importers/Cfdi40/Injectors/MesesTest.php | 69 ++ .../Cfdi40/Injectors/MetodosDePagoTest.php | 67 ++ .../Cfdi40/Injectors/MonedasTest.php | 70 ++ .../Cfdi40/Injectors/MunicipiosTest.php | 71 ++ .../Injectors/NumerosPedimentoAduanaTest.php | 123 ++++ .../Injectors/ObjetosDeImpuestoTest.php | 69 ++ .../Importers/Cfdi40/Injectors/PaisesTest.php | 109 +++ .../Injectors/PatentesAduanalesTest.php | 79 +++ .../Cfdi40/Injectors/PeriodicidadesTest.php | 69 ++ .../Injectors/ProductosServiciosTest.php | 67 ++ .../Injectors/RegimenesFiscalesTest.php | 97 +++ .../Cfdi40/Injectors/ReglasTasaCuotaTest.php | 128 ++++ .../Injectors/TiposComprobantesTest.php | 70 ++ .../Cfdi40/Injectors/TiposFactoresTest.php | 67 ++ .../Cfdi40/Injectors/TiposRelacionesTest.php | 80 +++ .../Cfdi40/Injectors/UsosCfdiTest.php | 98 +++ tests/Unit/Importers/Cfdi40CatalogsTest.php | 78 ++ tests/_files/cfdi40/C_Colonia.csv | 661 +++++++++++++++++ tests/_files/cfdi40/C_Localidad.csv | 668 ++++++++++++++++++ tests/_files/cfdi40/C_Municipio.csv | 223 ++++++ tests/_files/cfdi40/c_Aduana.csv | 53 ++ tests/_files/cfdi40/c_ClaveProdServ.csv | 223 ++++++ tests/_files/cfdi40/c_ClaveUnidad.csv | 79 +++ tests/_files/cfdi40/c_CodigoPostal.csv | 458 ++++++++++++ tests/_files/cfdi40/c_Estado.csv | 99 +++ tests/_files/cfdi40/c_Exportacion.csv | 8 + tests/_files/cfdi40/c_FormaPago.csv | 26 + tests/_files/cfdi40/c_Impuesto.csv | 7 + tests/_files/cfdi40/c_Meses.csv | 22 + tests/_files/cfdi40/c_MetodoPago.csv | 6 + tests/_files/cfdi40/c_Moneda.csv | 182 +++++ tests/_files/cfdi40/c_NumPedimentoAduana.csv | 223 ++++++ tests/_files/cfdi40/c_ObjetoImp.csv | 7 + tests/_files/cfdi40/c_Pais.csv | 254 +++++++ tests/_files/cfdi40/c_PatenteAduanal.csv | 232 ++++++ tests/_files/cfdi40/c_Periodicidad.csv | 9 + tests/_files/cfdi40/c_RegimenFiscal.csv | 24 + tests/_files/cfdi40/c_TasaOCuota.csv | 24 + tests/_files/cfdi40/c_TipoDeComprobante.csv | 10 + tests/_files/cfdi40/c_TipoFactor.csv | 7 + tests/_files/cfdi40/c_TipoRelacion.csv | 11 + tests/_files/cfdi40/c_UsoCFDI.csv | 29 + tests/_files/sources/cfdi_40.xls | Bin 0 -> 495616 bytes 79 files changed, 7191 insertions(+) create mode 100644 src/Importers/Cfdi40/Injectors/Aduanas.php create mode 100644 src/Importers/Cfdi40/Injectors/ClavesUnidades.php create mode 100644 src/Importers/Cfdi40/Injectors/CodigosPostales.php create mode 100644 src/Importers/Cfdi40/Injectors/Colonias.php create mode 100644 src/Importers/Cfdi40/Injectors/Estados.php create mode 100644 src/Importers/Cfdi40/Injectors/Exportaciones.php create mode 100644 src/Importers/Cfdi40/Injectors/FormasDePago.php create mode 100644 src/Importers/Cfdi40/Injectors/Impuestos.php create mode 100644 src/Importers/Cfdi40/Injectors/Localidades.php create mode 100644 src/Importers/Cfdi40/Injectors/Meses.php create mode 100644 src/Importers/Cfdi40/Injectors/MetodosDePago.php create mode 100644 src/Importers/Cfdi40/Injectors/Monedas.php create mode 100644 src/Importers/Cfdi40/Injectors/Municipios.php create mode 100644 src/Importers/Cfdi40/Injectors/NumerosPedimentoAduana.php create mode 100644 src/Importers/Cfdi40/Injectors/ObjetosDeImpuestos.php create mode 100644 src/Importers/Cfdi40/Injectors/Paises.php create mode 100644 src/Importers/Cfdi40/Injectors/PatentesAduanales.php create mode 100644 src/Importers/Cfdi40/Injectors/Periodicidades.php create mode 100644 src/Importers/Cfdi40/Injectors/ProductosServicios.php create mode 100644 src/Importers/Cfdi40/Injectors/RegimenesFiscales.php create mode 100644 src/Importers/Cfdi40/Injectors/ReglasTasaCuota.php create mode 100644 src/Importers/Cfdi40/Injectors/TiposComprobantes.php create mode 100644 src/Importers/Cfdi40/Injectors/TiposFactores.php create mode 100644 src/Importers/Cfdi40/Injectors/TiposRelaciones.php create mode 100644 src/Importers/Cfdi40/Injectors/UsosCfdi.php create mode 100644 src/Importers/Cfdi40Catalogs.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/AduanasTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/ClavesUnidadesTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/CodigosPostalesTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/ColoniasTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/EstadosTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/ExportacionesTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/FormasDePagoTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/ImpuestosTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/LocalidadesTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/MesesTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/MetodosDePagoTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/MonedasTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/MunicipiosTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/NumerosPedimentoAduanaTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/ObjetosDeImpuestoTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/PaisesTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/PatentesAduanalesTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/PeriodicidadesTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/ProductosServiciosTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/RegimenesFiscalesTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/ReglasTasaCuotaTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/TiposComprobantesTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/TiposFactoresTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/TiposRelacionesTest.php create mode 100644 tests/Unit/Importers/Cfdi40/Injectors/UsosCfdiTest.php create mode 100644 tests/Unit/Importers/Cfdi40CatalogsTest.php create mode 100644 tests/_files/cfdi40/C_Colonia.csv create mode 100644 tests/_files/cfdi40/C_Localidad.csv create mode 100644 tests/_files/cfdi40/C_Municipio.csv create mode 100644 tests/_files/cfdi40/c_Aduana.csv create mode 100644 tests/_files/cfdi40/c_ClaveProdServ.csv create mode 100644 tests/_files/cfdi40/c_ClaveUnidad.csv create mode 100644 tests/_files/cfdi40/c_CodigoPostal.csv create mode 100644 tests/_files/cfdi40/c_Estado.csv create mode 100644 tests/_files/cfdi40/c_Exportacion.csv create mode 100644 tests/_files/cfdi40/c_FormaPago.csv create mode 100644 tests/_files/cfdi40/c_Impuesto.csv create mode 100644 tests/_files/cfdi40/c_Meses.csv create mode 100644 tests/_files/cfdi40/c_MetodoPago.csv create mode 100644 tests/_files/cfdi40/c_Moneda.csv create mode 100644 tests/_files/cfdi40/c_NumPedimentoAduana.csv create mode 100644 tests/_files/cfdi40/c_ObjetoImp.csv create mode 100644 tests/_files/cfdi40/c_Pais.csv create mode 100644 tests/_files/cfdi40/c_PatenteAduanal.csv create mode 100644 tests/_files/cfdi40/c_Periodicidad.csv create mode 100644 tests/_files/cfdi40/c_RegimenFiscal.csv create mode 100644 tests/_files/cfdi40/c_TasaOCuota.csv create mode 100644 tests/_files/cfdi40/c_TipoDeComprobante.csv create mode 100644 tests/_files/cfdi40/c_TipoFactor.csv create mode 100644 tests/_files/cfdi40/c_TipoRelacion.csv create mode 100644 tests/_files/cfdi40/c_UsoCFDI.csv create mode 100644 tests/_files/sources/cfdi_40.xls diff --git a/src/Importers/Cfdi40/Injectors/Aduanas.php b/src/Importers/Cfdi40/Injectors/Aduanas.php new file mode 100644 index 0000000..eef530a --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/Aduanas.php @@ -0,0 +1,43 @@ +move(3); + $expected = ['c_Aduana', 'Descripción', 'Fecha inicio de vigencia', 'Fecha fin de vigencia']; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_aduanas', new DataFields([ + new PaddingDataField('id', '0', 2), + new TextDataField('texto'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/ClavesUnidades.php b/src/Importers/Cfdi40/Injectors/ClavesUnidades.php new file mode 100644 index 0000000..4904792 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/ClavesUnidades.php @@ -0,0 +1,54 @@ +move(3); + $expected = [ + 'c_ClaveUnidad', + 'Nombre', + 'Descripción', + 'Nota', + 'Fecha de inicio de vigencia', + 'Fecha de fin de vigencia', + 'Símbolo', + ]; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_claves_unidades', new DataFields([ + new PaddingDataField('id', '0', 2), + new TextDataField('texto'), + new TextDataField('descripcion'), + new TextDataField('notas'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + new TextDataField('simbolo'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/CodigosPostales.php b/src/Importers/Cfdi40/Injectors/CodigosPostales.php new file mode 100644 index 0000000..25d8f2e --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/CodigosPostales.php @@ -0,0 +1,95 @@ +move(3); + $expectedLines = [ + [ + 'c_CodigoPostal', + 'c_Estado', + 'c_Municipio', + 'c_Localidad', + 'Estímulo Franja Fronteriza', + 'Fecha inicio de vigencia', + 'Fecha fin de vigencia', + 'Referencias del Huso Horario', + ], + [ + '', + '', + '', + '', + '', + '', + '', + 'Descripción del Huso Horario', + 'Mes_Inicio_Horario_Verano', + 'Día_Inicio_Horario_Verano', + 'Día_Inicio_Horario_Verano', + 'Diferencia_Horaria_Verano', + 'Mes_Inicio_Horario_Invierno', + 'Día_Inicio_Horario_Invierno', + 'Día_Inicio_Horario_Invierno', + 'Diferencia_Horaria_Invierno', + ], + ]; + foreach ($expectedLines as $line => $expected) { + $line = $line + 1; + $headers = array_map(fn ($line): string => trim((string) $line), $csv->readLine()); + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()} line {$line}"); + } + $csv->next(); + } + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_codigos_postales', new DataFields([ + new TextDataField('id'), + new TextDataField('estado'), + new TextDataField('municipio'), + new TextDataField('localidad'), + new BoolDataField('estimulo_frontera', ['1']), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + new TextDataField('huso_descripcion'), + new TextDataField('huso_verano_mes_inicio'), + new TextDataField('huso_verano_dia_inicio'), + new TextDataField('huso_verano_hora_inicio'), + new TextDataField('huso_verano_diferencia'), + new TextDataField('huso_invierno_mes_inicio'), + new TextDataField('huso_invierno_dia_inicio'), + new TextDataField('huso_invierno_hora_inicio'), + new TextDataField('huso_invierno_diferencia'), + ])); + } + + /** @inheritdoc */ + protected function readLinesFromCsv(CsvFile $csv): Generator + { + foreach ($csv->readLines() as $line) { + if ('00000' === $line[0]) { + continue; + } + + yield $line; + } + } +} diff --git a/src/Importers/Cfdi40/Injectors/Colonias.php b/src/Importers/Cfdi40/Injectors/Colonias.php new file mode 100644 index 0000000..2783567 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/Colonias.php @@ -0,0 +1,38 @@ +move(3); + $expected = ['c_Colonia', 'c_CodigoPostal', 'Nombre del asentamiento']; + $headers = $csv->readLine(); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_colonias', new DataFields([ + new PaddingDataField('colonia', '0', 4), + new PaddingDataField('codigo_postal', '0', 5), + new TextDataField('texto'), + ]), ['colonia', 'codigo_postal']); + } +} diff --git a/src/Importers/Cfdi40/Injectors/Estados.php b/src/Importers/Cfdi40/Injectors/Estados.php new file mode 100644 index 0000000..f5e1ca4 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/Estados.php @@ -0,0 +1,46 @@ +move(3); + $expected = [ + 'c_Estado', + 'c_Pais', + 'Nombre del estado', + 'Fecha inicio de vigencia', + 'Fecha fin de vigencia', + ]; + $headers = $csv->readLine(); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_estados', new DataFields([ + new TextDataField('estado'), + new TextDataField('pais'), + new TextDataField('texto'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ]), ['estado', 'pais']); + } +} diff --git a/src/Importers/Cfdi40/Injectors/Exportaciones.php b/src/Importers/Cfdi40/Injectors/Exportaciones.php new file mode 100644 index 0000000..dd605cd --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/Exportaciones.php @@ -0,0 +1,40 @@ +move(3); + $expected = ['c_Exportacion', 'Descripción', 'Fecha inicio de vigencia', 'Fecha fin de vigencia']; + $headers = $csv->readLine(); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_exportaciones', new DataFields([ + new PaddingDataField('id', '0', 2), + new TextDataField('texto'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/FormasDePago.php b/src/Importers/Cfdi40/Injectors/FormasDePago.php new file mode 100644 index 0000000..256ccfa --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/FormasDePago.php @@ -0,0 +1,78 @@ +move(3); + $expected = [ + 'c_FormaPago', + 'Descripción', + 'Bancarizado', + 'Número de operación', + 'RFC del Emisor de la cuenta ordenante', + 'Cuenta Ordenante', + 'Patrón para cuenta ordenante', + 'RFC del Emisor Cuenta de Beneficiario', + 'Cuenta de Benenficiario', + 'Patrón para cuenta Beneficiaria', + 'Tipo Cadena Pago', + 'Nombre del Banco emisor de la cuenta ordenante en caso de extranjero', + 'Fecha inicio de vigencia', + 'Fecha fin de vigencia', + ]; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + $pattern = function (string $input): string { + if ('No' === $input) { + return ''; + } + if ('Opcional' === $input) { + return '\V*'; + } + return $input; + }; + return new DataTable('cfdi_40_formas_pago', new DataFields([ + new PaddingDataField('id', '0', 2), + new TextDataField('texto'), + new BoolDataField('es_bancarizado', ['Sí']), + new BoolDataField('requiere_numero_operacion', [], ['Opcional'], true), + new BoolDataField('permite_banco_ordenante_rfc', [], ['No'], true), + new BoolDataField('permite_cuenta_ordenante', [], ['No'], true), + new TextDataField('patron_cuenta_ordenante', $pattern), + new BoolDataField('permite_banco_beneficiario_rfc', [], ['No'], true), + new BoolDataField('permite_cuenta_beneficiario', [], ['No'], true), + new TextDataField('patron_cuenta_beneficiario', $pattern), + new BoolDataField('permite_tipo_cadena_pago', [], ['No'], true), + new BoolDataField('requiere_banco_ordenante_nombre_ext', [], ['No'], true), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/Impuestos.php b/src/Importers/Cfdi40/Injectors/Impuestos.php new file mode 100644 index 0000000..27ec2cd --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/Impuestos.php @@ -0,0 +1,55 @@ +move(3); + $expected = [ + 'c_Impuesto', + 'Descripción', + 'Retención', + 'Traslado', + 'Local o federal', + 'Fecha inicio de vigencia', + 'Fecha fin de vigencia', + ]; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_impuestos', new DataFields([ + new PaddingDataField('id', '0', 3), + new TextDataField('texto'), + new BoolDataField('retencion', ['Si']), + new BoolDataField('traslado', ['Si']), + new TextDataField('ambito'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/Localidades.php b/src/Importers/Cfdi40/Injectors/Localidades.php new file mode 100644 index 0000000..a4d9ef2 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/Localidades.php @@ -0,0 +1,47 @@ +move(3); + $expected = [ + 'c_Localidad', + 'c_Estado', + 'Descripción', + 'Fecha de inicio de vigencia', + 'Fecha de fin de vigencia', + ]; + $headers = $csv->readLine(); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_localidades', new DataFields([ + new PaddingDataField('localidad', '0', 2), + new TextDataField('estado'), + new TextDataField('texto'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ]), ['localidad', 'estado']); + } +} diff --git a/src/Importers/Cfdi40/Injectors/Meses.php b/src/Importers/Cfdi40/Injectors/Meses.php new file mode 100644 index 0000000..20c9b8e --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/Meses.php @@ -0,0 +1,40 @@ +move(3); + $expected = ['c_Meses', 'Descripción', 'Fecha inicio de vigencia', 'Fecha fin de vigencia']; + $headers = $csv->readLine(); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_meses', new DataFields([ + new PaddingDataField('id', '0', 2), + new TextDataField('texto'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/MetodosDePago.php b/src/Importers/Cfdi40/Injectors/MetodosDePago.php new file mode 100644 index 0000000..f802b30 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/MetodosDePago.php @@ -0,0 +1,47 @@ +move(3); + $expected = [ + 'c_MetodoPago', + 'Descripción', + 'Fecha inicio de vigencia', + 'Fecha fin de vigencia', + ]; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_metodos_pago', new DataFields([ + new TextDataField('id'), + new TextDataField('texto'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/Monedas.php b/src/Importers/Cfdi40/Injectors/Monedas.php new file mode 100644 index 0000000..117d5f9 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/Monedas.php @@ -0,0 +1,52 @@ +move(3); + $expected = [ + 'c_Moneda', + 'Descripción', + 'Decimales', + 'Porcentaje variación', + 'Fecha inicio de vigencia', + 'Fecha fin de vigencia', + ]; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_monedas', new DataFields([ + new TextDataField('id'), + new TextDataField('texto'), + new IntegerDataField('decimales'), + new IntegerDataField('porcentaje_variacion'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/Municipios.php b/src/Importers/Cfdi40/Injectors/Municipios.php new file mode 100644 index 0000000..4c44767 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/Municipios.php @@ -0,0 +1,47 @@ +move(3); + $expected = [ + 'c_Municipio', + 'c_Estado', + 'Descripción', + 'Fecha de inicio de vigencia', + 'Fecha de fin de vigencia', + ]; + $headers = $csv->readLine(); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_municipios', new DataFields([ + new PaddingDataField('municipio', '0', 3), + new TextDataField('estado'), + new TextDataField('texto'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ]), ['municipio', 'estado']); + } +} diff --git a/src/Importers/Cfdi40/Injectors/NumerosPedimentoAduana.php b/src/Importers/Cfdi40/Injectors/NumerosPedimentoAduana.php new file mode 100644 index 0000000..46e4629 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/NumerosPedimentoAduana.php @@ -0,0 +1,57 @@ +move(3); + $expected = [ + 'c_Aduana', + 'Patente', + 'Ejercicio', + 'Cantidad', + 'Fecha inicio de vigencia', + 'Fecha fin de vigencia', + ]; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable( + 'cfdi_40_numeros_pedimento_aduana', + new DataFields([ + new PaddingDataField('aduana', '0', 2), + new PaddingDataField('patente', '0', 4), + new IntegerDataField('ejercicio'), + new IntegerDataField('cantidad'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ]), + [], + true + ); + } +} diff --git a/src/Importers/Cfdi40/Injectors/ObjetosDeImpuestos.php b/src/Importers/Cfdi40/Injectors/ObjetosDeImpuestos.php new file mode 100644 index 0000000..8d0f185 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/ObjetosDeImpuestos.php @@ -0,0 +1,40 @@ +move(3); + $expected = ['c_ObjetoImp', 'Descripción', 'Fecha inicio de vigencia', 'Fecha fin de vigencia']; + $headers = $csv->readLine(); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_objetos_impuestos', new DataFields([ + new PaddingDataField('id', '0', 2), + new TextDataField('texto'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/Paises.php b/src/Importers/Cfdi40/Injectors/Paises.php new file mode 100644 index 0000000..5e7f65f --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/Paises.php @@ -0,0 +1,62 @@ +move(3); + $expected = [ + 'c_Pais', + 'Descripción', + 'Formato de código postal', + 'Formato de Registro de Identidad Tributaria', + 'Validación del Registro de Identidad Tributaria', + 'Agrupaciones', + ]; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + $optionalPattern = function (string $input): string { + if ('' === $input) { + return ''; + } + if (! preg_is_valid($input)) { + throw new RuntimeException("Se ha encontrado un valor que no es un patrón: '$input'"); + } + + return $input; + }; + + return new DataTable('cfdi_40_paises', new DataFields([ + new TextDataField('id'), + new TextDataField('texto'), + new TextDataField('patron_codigo_postal', $optionalPattern), + new TextDataField('patron_identidad_tributaria', $optionalPattern), + new TextDataField('validacion_identidad_tributaria'), + new TextDataField('agrupaciones'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/PatentesAduanales.php b/src/Importers/Cfdi40/Injectors/PatentesAduanales.php new file mode 100644 index 0000000..2708ac6 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/PatentesAduanales.php @@ -0,0 +1,45 @@ +move(3); + $expected = [ + 'C_PatenteAduanal', + 'Inicio de vigencia de la patente', + 'Fin de vigencia de la patente', + ]; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_patentes_aduanales', new DataFields([ + new PaddingDataField('id', '0', 4), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/Periodicidades.php b/src/Importers/Cfdi40/Injectors/Periodicidades.php new file mode 100644 index 0000000..7588ad1 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/Periodicidades.php @@ -0,0 +1,40 @@ +move(3); + $expected = ['c_Periodicidad', 'Descripción', 'Fecha inicio de vigencia', 'Fecha fin de vigencia']; + $headers = $csv->readLine(); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_periodicidades', new DataFields([ + new PaddingDataField('id', '0', 2), + new TextDataField('texto'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/ProductosServicios.php b/src/Importers/Cfdi40/Injectors/ProductosServicios.php new file mode 100644 index 0000000..ba711b5 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/ProductosServicios.php @@ -0,0 +1,59 @@ +move(3); + $expected = [ + 'c_ClaveProdServ', + 'Descripción', + 'Incluir IVA trasladado', + 'Incluir IEPS trasladado', + 'Complemento que debe incluir', + 'FechaInicioVigencia', + 'FechaFinVigencia', + 'Estímulo Franja Fronteriza', + 'Palabras similares', + ]; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_productos_servicios', new DataFields([ + new PaddingDataField('id', '0', 8), + new TextDataField('texto'), + new BoolDataField('iva_trasladado', ['Sí']), + new BoolDataField('ieps_trasladado', ['Sí']), + new TextDataField('complemento'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + new BoolDataField('estimulo_frontera', ['1']), + new TextDataField('similares'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/RegimenesFiscales.php b/src/Importers/Cfdi40/Injectors/RegimenesFiscales.php new file mode 100644 index 0000000..1487f23 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/RegimenesFiscales.php @@ -0,0 +1,52 @@ +move(4); + $expected = [ + 'c_RegimenFiscal', + 'Descripción', + 'Física', + 'Moral', + 'Fecha de inicio de vigencia', + 'Fecha de fin de vigencia', + ]; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_regimenes_fiscales', new DataFields([ + new TextDataField('id'), + new TextDataField('texto'), + new BoolDataField('aplica_fisica', ['Sí']), + new BoolDataField('aplica_moral', ['Sí']), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/ReglasTasaCuota.php b/src/Importers/Cfdi40/Injectors/ReglasTasaCuota.php new file mode 100644 index 0000000..ad755ce --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/ReglasTasaCuota.php @@ -0,0 +1,73 @@ +move(3); + $expectedLines = [ + [ + 'Rango o Fijo', + 'c_TasaOCuota', + '', + 'Impuesto', + 'Factor', + 'Traslado', + 'Retención', + 'Fecha inicio de vigencia', + 'Fecha fin de vigencia', + ], + [ + '', + 'Valor mínimo', + 'Valor máximo', + ], + ]; + + foreach ($expectedLines as $expected) { + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + $csv->next(); + } + } + + public function dataTable(): DataTable + { + return new DataTable( + 'cfdi_40_reglas_tasa_cuota', + new DataFields([ + new TextDataField('tipo'), + new NumberFormatDataField('minimo', 6), + new NumberFormatDataField('valor', 6), + new TextDataField('impuesto'), + new TextDataField('factor'), + new BoolDataField('traslado', ['Sí']), + new BoolDataField('retencion', ['Sí']), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ]), + [], + true + ); + } +} diff --git a/src/Importers/Cfdi40/Injectors/TiposComprobantes.php b/src/Importers/Cfdi40/Injectors/TiposComprobantes.php new file mode 100644 index 0000000..540ffd2 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/TiposComprobantes.php @@ -0,0 +1,72 @@ +sourceFile(), new IgnoreColumns(new RightTrim(), 3)); + } + + public function checkHeaders(CsvFile $csv): void + { + $csv->move(3); + $expected = [ + 'c_TipoDeComprobante', + 'Descripción', + 'Valor máximo', + 'Fecha inicio de vigencia', + 'Fecha fin de vigencia', + ]; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_tipos_comprobantes', new DataFields([ + new TextDataField('id'), + new TextDataField('texto'), + new TextDataField('valor_maximo'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } + + /** @inheritdoc */ + protected function readLinesFromCsv(CsvFile $csv): Generator + { + foreach ($csv->readLines() as $line) { + if ('' === $line[0]) { + continue; + } + if ('N' === $line[0]) { + $line[2] = '999999999999999999.999999'; + $line[3] = ''; + } + yield $line; + } + } +} diff --git a/src/Importers/Cfdi40/Injectors/TiposFactores.php b/src/Importers/Cfdi40/Injectors/TiposFactores.php new file mode 100644 index 0000000..eef842b --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/TiposFactores.php @@ -0,0 +1,45 @@ +move(3); + $expected = [ + 'c_TipoFactor', + 'Fecha inicio de vigencia', + 'Fecha fin de vigencia', + ]; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_tipos_factores', new DataFields([ + new TextDataField('id'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/TiposRelaciones.php b/src/Importers/Cfdi40/Injectors/TiposRelaciones.php new file mode 100644 index 0000000..9164b1d --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/TiposRelaciones.php @@ -0,0 +1,48 @@ +move(3); + $expected = [ + 'c_TipoRelacion', + 'Descripción', + 'Fecha inicio de vigencia', + 'Fecha fin de vigencia', + ]; + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + + $csv->next(); + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_tipos_relaciones', new DataFields([ + new PaddingDataField('id', '0', 2), + new TextDataField('texto'), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + ])); + } +} diff --git a/src/Importers/Cfdi40/Injectors/UsosCfdi.php b/src/Importers/Cfdi40/Injectors/UsosCfdi.php new file mode 100644 index 0000000..b1ea1a3 --- /dev/null +++ b/src/Importers/Cfdi40/Injectors/UsosCfdi.php @@ -0,0 +1,64 @@ +move(3); + $expectedLines = [ + [ + 'c_UsoCFDI', + 'Descripción', + 'Aplica para tipo persona', + '', + 'Fecha inicio de vigencia', + 'Fecha fin de vigencia', + 'Regímen Fiscal Receptor', + ], + [ + '', + '', + 'Física', + 'Moral', + ], + ]; + + foreach ($expectedLines as $expected) { + $headers = array_rtrim($csv->readLine()); + + if ($expected !== $headers) { + throw new RuntimeException("The headers did not match on file {$this->sourceFile()}"); + } + $csv->next(); + } + } + + public function dataTable(): DataTable + { + return new DataTable('cfdi_40_usos_cfdi', new DataFields([ + new TextDataField('id'), + new TextDataField('texto'), + new BoolDataField('aplica_fisica', ['Sí']), + new BoolDataField('aplica_moral', ['Sí']), + new DateDataField('vigencia_desde'), + new DateDataField('vigencia_hasta'), + new TextDataField('regimenes_fiscales_receptores'), // TODO: use CsvListDataField + ])); + } +} diff --git a/src/Importers/Cfdi40Catalogs.php b/src/Importers/Cfdi40Catalogs.php new file mode 100644 index 0000000..3320107 --- /dev/null +++ b/src/Importers/Cfdi40Catalogs.php @@ -0,0 +1,41 @@ +sourceFile = $this->utilFilePath('cfdi40/c_Aduana.csv'); + $this->injector = new Aduanas($this->sourceFile); + } + + public function testAduanasExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTable(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_aduanas', $dataTable->name()); + $this->assertSame( + ['id', 'texto', 'vigencia_desde', 'vigencia_hasta'], + $dataTable->fields()->keys() + ); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/ClavesUnidadesTest.php b/tests/Unit/Importers/Cfdi40/Injectors/ClavesUnidadesTest.php new file mode 100644 index 0000000..6b9a575 --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/ClavesUnidadesTest.php @@ -0,0 +1,66 @@ +sourceFile = $this->utilFilePath('cfdi40/c_ClaveUnidad.csv'); + $this->injector = new ClavesUnidades($this->sourceFile); + } + + public function testClavesUnidadesExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTable(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_claves_unidades', $dataTable->name()); + $expectedKeys = [ + 'id', + 'texto', + 'descripcion', + 'notas', + 'vigencia_desde', + 'vigencia_hasta', + 'simbolo', + ]; + $this->assertSame($expectedKeys, $dataTable->fields()->keys()); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/CodigosPostalesTest.php b/tests/Unit/Importers/Cfdi40/Injectors/CodigosPostalesTest.php new file mode 100644 index 0000000..436dc1e --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/CodigosPostalesTest.php @@ -0,0 +1,88 @@ +sourceFile = $this->utilFilePath('cfdi40/c_CodigoPostal.csv'); + $this->injector = new CodigosPostales($this->sourceFile); + } + + public function testCodigosPostalesExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(5, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTable(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_codigos_postales', $dataTable->name()); + $expectedKeys = [ + 'id', + 'estado', + 'municipio', + 'localidad', + 'estimulo_frontera', + 'vigencia_desde', + 'vigencia_hasta', + 'huso_descripcion', + 'huso_verano_mes_inicio', + 'huso_verano_dia_inicio', + 'huso_verano_hora_inicio', + 'huso_verano_diferencia', + 'huso_invierno_mes_inicio', + 'huso_invierno_dia_inicio', + 'huso_invierno_hora_inicio', + 'huso_invierno_diferencia', + ]; + $this->assertSame($expectedKeys, $dataTable->fields()->keys()); + } + + public function testInject(): void + { + $repository = new Repository(':memory:'); + $this->injector->inject($repository, new NullLogger()); + + $sql = 'select count(*) from ' . $this->injector->dataTable()->name() . ' where (id = :id);'; + $count = (int) $repository->queryOne($sql); + + $this->assertSame(0, $count, 'The id "00000" must not exists in the catalog'); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/ColoniasTest.php b/tests/Unit/Importers/Cfdi40/Injectors/ColoniasTest.php new file mode 100644 index 0000000..98fe2d8 --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/ColoniasTest.php @@ -0,0 +1,68 @@ +sourceFile = $this->utilFilePath('cfdi40/C_Colonia.csv'); + $this->injector = new Colonias($this->sourceFile); + } + + public function testColoniasExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_colonias', $dataTable->name()); + $expectedClasses = [ + 'colonia' => PaddingDataField::class, + 'codigo_postal' => PaddingDataField::class, + 'texto' => TextDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + $this->assertSame(['colonia', 'codigo_postal'], $dataTable->primaryKey()); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/EstadosTest.php b/tests/Unit/Importers/Cfdi40/Injectors/EstadosTest.php new file mode 100644 index 0000000..a18d97c --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/EstadosTest.php @@ -0,0 +1,70 @@ +sourceFile = $this->utilFilePath('cfdi40/c_Estado.csv'); + $this->injector = new Estados($this->sourceFile); + } + + public function testEstadosExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_estados', $dataTable->name()); + $expectedClasses = [ + 'estado' => TextDataField::class, + 'pais' => TextDataField::class, + 'texto' => TextDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + $this->assertSame(['estado', 'pais'], $dataTable->primaryKey()); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/ExportacionesTest.php b/tests/Unit/Importers/Cfdi40/Injectors/ExportacionesTest.php new file mode 100644 index 0000000..d2fb597 --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/ExportacionesTest.php @@ -0,0 +1,68 @@ +sourceFile = $this->utilFilePath('cfdi40/c_Exportacion.csv'); + $this->injector = new Exportaciones($this->sourceFile); + } + + public function testExportacionesExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_exportaciones', $dataTable->name()); + $expectedClasses = [ + 'id' => TextDataField::class, + 'texto' => TextDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/FormasDePagoTest.php b/tests/Unit/Importers/Cfdi40/Injectors/FormasDePagoTest.php new file mode 100644 index 0000000..367c456 --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/FormasDePagoTest.php @@ -0,0 +1,228 @@ +sourceFile = $this->utilFilePath('cfdi40/c_FormaPago.csv'); + $this->injector = new FormasDePago($this->sourceFile); + } + + public function testFormasDePagoExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTable(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_formas_pago', $dataTable->name()); + $expectedKeys = [ + 'id', + 'texto', + 'es_bancarizado', + 'requiere_numero_operacion', + 'permite_banco_ordenante_rfc', + 'permite_cuenta_ordenante', + 'patron_cuenta_ordenante', + 'permite_banco_beneficiario_rfc', + 'permite_cuenta_beneficiario', + 'patron_cuenta_beneficiario', + 'permite_tipo_cadena_pago', + 'requiere_banco_ordenante_nombre_ext', + 'vigencia_desde', + 'vigencia_hasta', + ]; + $this->assertSame($expectedKeys, $dataTable->fields()->keys()); + } + + /** + * @testWith ["ABC", "ABC"] + * ["", "00"] + * ["9", "09"] + */ + public function testTransformId(string $value, string $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [0 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['id']); + } + + public function testContainsTexto(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertInstanceOf(TextDataField::class, $dataTable->fields()->get('texto')); + } + + /** + * @testWith ["Sí", true] + * ["No", false] + * ["", false] + */ + public function testTransformEsBancarizado(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [2 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['es_bancarizado']); + } + + /** + * @testWith ["Opcional", false] + * ["", true] + */ + public function testTransformNumeroOperacion(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [3 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['requiere_numero_operacion']); + } + + /** + * @testWith ["No", false] + * ["", true] + */ + public function testTransformPermiteBancoOrdenanteRfc(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [4 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['permite_banco_ordenante_rfc']); + } + + /** + * @testWith ["No", false] + * ["", true] + */ + public function testTransformPermiteCuentaOrdenante(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [5 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['permite_cuenta_ordenante']); + } + + /** + * @testWith ["[0-9]{10}", "[0-9]{10}"] + * ["Opcional", "\\V*"] + * ["No", ""] + */ + public function testTransformPatronCuentaOrdenante(string $value, string $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [6 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['patron_cuenta_ordenante']); + } + + /** + * @testWith ["No", false] + * ["", true] + */ + public function testTransformPermiteBancoBeneficiarioRfc(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [7 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['permite_banco_beneficiario_rfc']); + } + + /** + * @testWith ["No", false] + * ["", true] + */ + public function testTransformPermiteCuentaBeneficiario(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [8 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['permite_cuenta_beneficiario']); + } + + /** + * @testWith ["[0-9]{10}", "[0-9]{10}"] + * ["Opcional", "\\V*"] + * ["No", ""] + */ + public function testTransformPatronCuentaBeneficiario(string $value, string $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [9 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['patron_cuenta_beneficiario']); + } + + /** + * @testWith ["No", false] + * ["", true] + */ + public function testTransformPermiteTipoCadenaPago(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [10 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['permite_tipo_cadena_pago']); + } + + /** + * @testWith ["No", false] + * ["", true] + */ + public function testTransformRequiereBancoOrdenanteNombreExt(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [11 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['requiere_banco_ordenante_nombre_ext']); + } + + public function testContainsVigenciaDesde(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertInstanceOf(DateDataField::class, $dataTable->fields()->get('vigencia_desde')); + } + + public function testContainsVigenciaHasta(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertInstanceOf(DateDataField::class, $dataTable->fields()->get('vigencia_hasta')); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/ImpuestosTest.php b/tests/Unit/Importers/Cfdi40/Injectors/ImpuestosTest.php new file mode 100644 index 0000000..2b559ec --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/ImpuestosTest.php @@ -0,0 +1,111 @@ +sourceFile = $this->utilFilePath('cfdi40/c_Impuesto.csv'); + $this->injector = new Impuestos($this->sourceFile); + } + + public function testImpuestosExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTable(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_impuestos', $dataTable->name()); + $expectedKeys = [ + 'id', + 'texto', + 'retencion', + 'traslado', + 'ambito', + 'vigencia_desde', + 'vigencia_hasta', + ]; + $this->assertSame($expectedKeys, $dataTable->fields()->keys()); + } + + /** + * @testWith ["ABCD", "ABCD"] + * ["", "000"] + * ["9", "009"] + */ + public function testTransformId(string $value, string $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [0 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['id']); + } + + public function testContainsTexto(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertInstanceOf(TextDataField::class, $dataTable->fields()->get('texto')); + } + + /** + * @testWith ["Si", true] + * ["No", false] + * ["", false] + */ + public function testTransformRetencion(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [2 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['retencion']); + } + + /** + * @testWith ["Si", true] + * ["No", false] + * ["", false] + */ + public function testTransformTraslado(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [3 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['traslado']); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/LocalidadesTest.php b/tests/Unit/Importers/Cfdi40/Injectors/LocalidadesTest.php new file mode 100644 index 0000000..797c19c --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/LocalidadesTest.php @@ -0,0 +1,71 @@ +sourceFile = $this->utilFilePath('cfdi40/C_Localidad.csv'); + $this->injector = new Localidades($this->sourceFile); + } + + public function testLocalidadesExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_localidades', $dataTable->name()); + $expectedClasses = [ + 'localidad' => PaddingDataField::class, + 'estado' => TextDataField::class, + 'texto' => TextDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + $this->assertSame(['localidad', 'estado'], $dataTable->primaryKey()); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/MesesTest.php b/tests/Unit/Importers/Cfdi40/Injectors/MesesTest.php new file mode 100644 index 0000000..7268b85 --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/MesesTest.php @@ -0,0 +1,69 @@ +sourceFile = $this->utilFilePath('cfdi40/c_Meses.csv'); + $this->injector = new Meses($this->sourceFile); + } + + public function testMesesExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_meses', $dataTable->name()); + $expectedClasses = [ + 'id' => PaddingDataField::class, + 'texto' => TextDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/MetodosDePagoTest.php b/tests/Unit/Importers/Cfdi40/Injectors/MetodosDePagoTest.php new file mode 100644 index 0000000..8d88d1f --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/MetodosDePagoTest.php @@ -0,0 +1,67 @@ +sourceFile = $this->utilFilePath('cfdi40/c_MetodoPago.csv'); + $this->injector = new MetodosDePago($this->sourceFile); + } + + public function testMetodosDePagoExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_metodos_pago', $dataTable->name()); + $expectedClasses = [ + 'id' => TextDataField::class, + 'texto' => TextDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/MonedasTest.php b/tests/Unit/Importers/Cfdi40/Injectors/MonedasTest.php new file mode 100644 index 0000000..21a06eb --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/MonedasTest.php @@ -0,0 +1,70 @@ +sourceFile = $this->utilFilePath('cfdi40/c_Moneda.csv'); + $this->injector = new Monedas($this->sourceFile); + } + + public function testMonedasExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_monedas', $dataTable->name()); + $expectedClasses = [ + 'id' => TextDataField::class, + 'texto' => TextDataField::class, + 'decimales' => IntegerDataField::class, + 'porcentaje_variacion' => IntegerDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/MunicipiosTest.php b/tests/Unit/Importers/Cfdi40/Injectors/MunicipiosTest.php new file mode 100644 index 0000000..d007502 --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/MunicipiosTest.php @@ -0,0 +1,71 @@ +sourceFile = $this->utilFilePath('cfdi40/C_Municipio.csv'); + $this->injector = new Municipios($this->sourceFile); + } + + public function testMunicipiosExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_municipios', $dataTable->name()); + $expectedClasses = [ + 'municipio' => PaddingDataField::class, + 'estado' => TextDataField::class, + 'texto' => TextDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + $this->assertSame(['municipio', 'estado'], $dataTable->primaryKey()); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/NumerosPedimentoAduanaTest.php b/tests/Unit/Importers/Cfdi40/Injectors/NumerosPedimentoAduanaTest.php new file mode 100644 index 0000000..c5ec570 --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/NumerosPedimentoAduanaTest.php @@ -0,0 +1,123 @@ +sourceFile = $this->utilFilePath('cfdi40/c_NumPedimentoAduana.csv'); + $this->injector = new NumerosPedimentoAduana($this->sourceFile); + } + + public function testNumerosPedimentoAduanaExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_numeros_pedimento_aduana', $dataTable->name()); + $expectedClasses = [ + 'aduana' => TextDataField::class, + 'patente' => TextDataField::class, + 'ejercicio' => IntegerDataField::class, + 'cantidad' => IntegerDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + $this->assertSame([], $dataTable->primaryKey()); + } + + /** + * @testWith ["AB", "AB"] + * ["", "00"] + * ["9", "09"] + */ + public function testTransformAduana(string $value, string $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [0 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['aduana']); + } + + /** + * @testWith ["ABCD", "ABCD"] + * ["", "0000"] + * ["9", "0009"] + */ + public function testTransformPatente(string $value, string $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [1 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['patente']); + } + + /** + * @testWith ["0", 0] + * ["", 0] + * ["2018", 2018] + */ + public function testTransformEjercicio(string $value, int $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [2 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['ejercicio']); + } + + /** + * @testWith ["0", 0] + * ["", 0] + * ["2018", 2018] + */ + public function testTransformCantidad(string $value, int $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [3 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['cantidad']); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/ObjetosDeImpuestoTest.php b/tests/Unit/Importers/Cfdi40/Injectors/ObjetosDeImpuestoTest.php new file mode 100644 index 0000000..6b8ee4d --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/ObjetosDeImpuestoTest.php @@ -0,0 +1,69 @@ +sourceFile = $this->utilFilePath('cfdi40/c_ObjetoImp.csv'); + $this->injector = new ObjetosDeImpuestos($this->sourceFile); + } + + public function testObjetosDeImpuestoExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_objetos_impuestos', $dataTable->name()); + $expectedClasses = [ + 'id' => PaddingDataField::class, + 'texto' => TextDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/PaisesTest.php b/tests/Unit/Importers/Cfdi40/Injectors/PaisesTest.php new file mode 100644 index 0000000..cebcc7a --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/PaisesTest.php @@ -0,0 +1,109 @@ +sourceFile = $this->utilFilePath('cfdi40/c_Pais.csv'); + $this->injector = new Paises($this->sourceFile); + } + + public function testPaisesExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_paises', $dataTable->name()); + $expectedClasses = [ + 'id' => TextDataField::class, + 'texto' => TextDataField::class, + 'patron_codigo_postal' => TextDataField::class, + 'patron_identidad_tributaria' => TextDataField::class, + 'validacion_identidad_tributaria' => TextDataField::class, + 'agrupaciones' => TextDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + } + + /** + * @testWith [""] + * ["[0-9]+"] + */ + public function testPatronCodigoPostalValido(string $value): void + { + $dataTable = $this->injector->dataTable(); + $transformed = $dataTable->fields()->transform(['foo', 'foo', $value, '', '', '']); + $this->assertSame($value, $transformed['patron_codigo_postal']); + } + + public function testPatronCodigoPostalInvalidPattern(): void + { + $dataTable = $this->injector->dataTable(); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Se ha encontrado un valor que no es un patrón'); + $dataTable->fields()->transform(['foo', 'foo', ') invalid (', '', '', '']); + } + + /** + * @testWith [""] + * ["[0-9]+"] + */ + public function testPatronIdentidadTributariaValido(string $value): void + { + $dataTable = $this->injector->dataTable(); + $transformed = $dataTable->fields()->transform(['foo', 'foo', '', $value, '', '']); + $this->assertSame($value, $transformed['patron_identidad_tributaria']); + } + + public function testPatronIdentidadTributariaInvalidPattern(): void + { + $dataTable = $this->injector->dataTable(); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Se ha encontrado un valor que no es un patrón'); + $dataTable->fields()->transform(['foo', 'foo', '', ') invalid (', '', '']); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/PatentesAduanalesTest.php b/tests/Unit/Importers/Cfdi40/Injectors/PatentesAduanalesTest.php new file mode 100644 index 0000000..ac46d4a --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/PatentesAduanalesTest.php @@ -0,0 +1,79 @@ +sourceFile = $this->utilFilePath('cfdi40/c_PatenteAduanal.csv'); + $this->injector = new PatentesAduanales($this->sourceFile); + } + + public function testPatentesAduanalesExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_patentes_aduanales', $dataTable->name()); + $expectedClasses = [ + 'id' => TextDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + } + + /** + * @testWith ["ABCDE", "ABCDE"] + * ["", "0000"] + * ["9", "0009"] + */ + public function testTransformId(string $value, string $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [0 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['id']); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/PeriodicidadesTest.php b/tests/Unit/Importers/Cfdi40/Injectors/PeriodicidadesTest.php new file mode 100644 index 0000000..77cac20 --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/PeriodicidadesTest.php @@ -0,0 +1,69 @@ +sourceFile = $this->utilFilePath('cfdi40/c_Periodicidad.csv'); + $this->injector = new Periodicidades($this->sourceFile); + } + + public function testPeriodicidadesExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_periodicidades', $dataTable->name()); + $expectedClasses = [ + 'id' => PaddingDataField::class, + 'texto' => TextDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/ProductosServiciosTest.php b/tests/Unit/Importers/Cfdi40/Injectors/ProductosServiciosTest.php new file mode 100644 index 0000000..c659bfe --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/ProductosServiciosTest.php @@ -0,0 +1,67 @@ +sourceFile = $this->utilFilePath('cfdi40/c_ClaveProdServ.csv'); + $this->injector = new ProductosServicios($this->sourceFile); + } + + public function testProductosServiciosExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTable(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_productos_servicios', $dataTable->name()); + $expectedKeys = [ + 'id', + 'texto', + 'iva_trasladado', + 'ieps_trasladado', + 'complemento', + 'vigencia_desde', + 'vigencia_hasta', + 'estimulo_frontera', + 'similares', + ]; + $this->assertSame($expectedKeys, $dataTable->fields()->keys()); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/RegimenesFiscalesTest.php b/tests/Unit/Importers/Cfdi40/Injectors/RegimenesFiscalesTest.php new file mode 100644 index 0000000..cda799f --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/RegimenesFiscalesTest.php @@ -0,0 +1,97 @@ +sourceFile = $this->utilFilePath('cfdi40/c_RegimenFiscal.csv'); + $this->injector = new RegimenesFiscales($this->sourceFile); + } + + public function testRegimenesFiscalesExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile); + $this->injector->checkHeaders($csv); + + $this->assertSame(5, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_regimenes_fiscales', $dataTable->name()); + $expectedClasses = [ + 'id' => TextDataField::class, + 'texto' => TextDataField::class, + 'aplica_fisica' => BoolDataField::class, + 'aplica_moral' => BoolDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + $this->assertSame(['id'], $dataTable->primaryKey()); + } + + /** + * @testWith ["Sí", true] + * ["No", false] + * ["", false] + */ + public function testTransformAplicaFisica(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [2 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['aplica_fisica']); + } + + /** + * @testWith ["Sí", true] + * ["No", false] + * ["", false] + */ + public function testTransformAplicaMoral(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [3 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['aplica_moral']); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/ReglasTasaCuotaTest.php b/tests/Unit/Importers/Cfdi40/Injectors/ReglasTasaCuotaTest.php new file mode 100644 index 0000000..a15dd0f --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/ReglasTasaCuotaTest.php @@ -0,0 +1,128 @@ +sourceFile = $this->utilFilePath('cfdi40/c_TasaOCuota.csv'); + $this->injector = new ReglasTasaCuota($this->sourceFile); + } + + public function testReglasTasaCuotaExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(5, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_reglas_tasa_cuota', $dataTable->name()); + $expectedClasses = [ + 'tipo' => TextDataField::class, + 'minimo' => NumberFormatDataField::class, + 'valor' => NumberFormatDataField::class, + 'impuesto' => TextDataField::class, + 'factor' => TextDataField::class, + 'traslado' => BoolDataField::class, + 'retencion' => BoolDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + $this->assertSame([], $dataTable->primaryKey()); + } + + /** + * @testWith ["0", "0.000000"] + * ["1.234", "1.234000"] + * ["", ""] + */ + public function testTransformMinimo(string $value, string $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [1 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['minimo']); + } + + /** + * @testWith ["0", "0.000000"] + * ["1.234", "1.234000"] + * ["", ""] + */ + public function testTransformValor(string $value, string $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [2 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['valor']); + } + + /** + * @testWith ["Sí", true] + * ["No", false] + * ["", false] + */ + public function testTransformTraslado(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [5 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['traslado']); + } + + /** + * @testWith ["Sí", true] + * ["No", false] + * ["", false] + */ + public function testTransformRetencion(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [6 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['retencion']); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/TiposComprobantesTest.php b/tests/Unit/Importers/Cfdi40/Injectors/TiposComprobantesTest.php new file mode 100644 index 0000000..300b80f --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/TiposComprobantesTest.php @@ -0,0 +1,70 @@ +sourceFile = $this->utilFilePath('cfdi40/c_TipoDeComprobante.csv'); + $this->injector = new TiposComprobantes($this->sourceFile); + } + + public function testTiposComprobantesExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new IgnoreColumns(new RightTrim(), 3)); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_tipos_comprobantes', $dataTable->name()); + $expectedClasses = [ + 'id' => TextDataField::class, + 'texto' => TextDataField::class, + 'valor_maximo' => TextDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/TiposFactoresTest.php b/tests/Unit/Importers/Cfdi40/Injectors/TiposFactoresTest.php new file mode 100644 index 0000000..59270dc --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/TiposFactoresTest.php @@ -0,0 +1,67 @@ +sourceFile = $this->utilFilePath('cfdi40/c_TipoFactor.csv'); + $this->injector = new TiposFactores($this->sourceFile); + } + + public function testTiposFactoresExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_tipos_factores', $dataTable->name()); + $expectedClasses = [ + 'id' => TextDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/TiposRelacionesTest.php b/tests/Unit/Importers/Cfdi40/Injectors/TiposRelacionesTest.php new file mode 100644 index 0000000..42b6c3c --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/TiposRelacionesTest.php @@ -0,0 +1,80 @@ +sourceFile = $this->utilFilePath('cfdi40/c_TipoRelacion.csv'); + $this->injector = new TiposRelaciones($this->sourceFile); + } + + public function testTiposRelacionesExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile); + $this->injector->checkHeaders($csv); + + $this->assertSame(4, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_tipos_relaciones', $dataTable->name()); + $expectedClasses = [ + 'id' => TextDataField::class, + 'texto' => TextDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + } + + /** + * @testWith ["AB", "AB"] + * ["", "00"] + * ["9", "09"] + */ + public function testTransformId(string $value, string $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [0 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['id']); + } +} diff --git a/tests/Unit/Importers/Cfdi40/Injectors/UsosCfdiTest.php b/tests/Unit/Importers/Cfdi40/Injectors/UsosCfdiTest.php new file mode 100644 index 0000000..a182b52 --- /dev/null +++ b/tests/Unit/Importers/Cfdi40/Injectors/UsosCfdiTest.php @@ -0,0 +1,98 @@ +sourceFile = $this->utilFilePath('cfdi40/c_UsoCFDI.csv'); + $this->injector = new UsosCfdi($this->sourceFile); + } + + public function testUsosCfdiExtendsAbstractCsvInjector(): void + { + $this->assertInstanceOf(AbstractCsvInjector::class, $this->injector); + $this->assertInstanceOf(InjectorInterface::class, $this->injector); + } + + public function testCheckHeadersOnValidSource(): void + { + $csv = new CsvFile($this->sourceFile, new RightTrim()); + $this->injector->checkHeaders($csv); + + $this->assertSame(5, $csv->position(), 'The csv position is on the first content line'); + } + + public function testCheckHeadersOnInvalidSource(): void + { + $csv = new CsvFile($this->utilFilePath('sample.csv')); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The headers did not match on file'); + $this->injector->checkHeaders($csv); + } + + public function testDataTableFields(): void + { + $dataTable = $this->injector->dataTable(); + $this->assertSame('cfdi_40_usos_cfdi', $dataTable->name()); + $expectedClasses = [ + 'id' => TextDataField::class, + 'texto' => TextDataField::class, + 'aplica_fisica' => BoolDataField::class, + 'aplica_moral' => BoolDataField::class, + 'vigencia_desde' => DateDataField::class, + 'vigencia_hasta' => DateDataField::class, + 'regimenes_fiscales_receptores' => TextDataField::class, + ]; + $this->assertSame(array_keys($expectedClasses), $dataTable->fields()->keys()); + foreach ($expectedClasses as $key => $classname) { + $this->assertInstanceOf($classname, $dataTable->fields()->get($key)); + } + } + + /** + * @testWith ["Sí", true] + * ["No", false] + * ["", false] + */ + public function testTransformAplicaFisica(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [2 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['aplica_fisica']); + } + + /** + * @testWith ["Sí", true] + * ["No", false] + * ["", false] + */ + public function testTransformAplicaMoral(string $value, bool $expected): void + { + $dataTable = $this->injector->dataTable(); + $input = [3 => $value]; + $transform = $dataTable->fields()->transform($input); + $this->assertSame($expected, $transform['aplica_moral']); + } +} diff --git a/tests/Unit/Importers/Cfdi40CatalogsTest.php b/tests/Unit/Importers/Cfdi40CatalogsTest.php new file mode 100644 index 0000000..14cde16 --- /dev/null +++ b/tests/Unit/Importers/Cfdi40CatalogsTest.php @@ -0,0 +1,78 @@ +createInjectors(''); + + $injectorsClasses = array_map(fn ($item) => $item::class, $cfdiInjectors->all()); + + $this->assertEquals(array_replace_recursive($injectorsClasses, $expectedInjectorsClasses), $injectorsClasses); + $this->assertCount(count($expectedInjectorsClasses), $injectorsClasses); + } +} diff --git a/tests/_files/cfdi40/C_Colonia.csv b/tests/_files/cfdi40/C_Colonia.csv new file mode 100644 index 0000000..9999830 --- /dev/null +++ b/tests/_files/cfdi40/C_Colonia.csv @@ -0,0 +1,661 @@ +Catálogo de colonias.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_Colonia,c_CodigoPostal,Nombre del asentamiento,,,,,,,,, +0001,01000,San Ángel,,,,,,,,, +0001,16514,Tetitla la Gallera,,,,,,,,, +0001,20000,Zona Centro,,,,,,,,, +0001,20339,San José (San José de los Rodríguez),,,,,,,,, +0001,20406,Rinconada de las Piedras,,,,,,,,, +0001,20656,Carboneras,,,,,,,,, +0001,20680,Las Ánimas,,,,,,,,, +0001,20700,Guadalupe,,,,,,,,, +0001,20854,Parque Industrial Calvillo,,,,,,,,, +0001,20926,Rincón del Pilar,,,,,,,,, +0001,21000,Centro Cívico,,,,,,,,, +0001,21453,Piedra Angular,,,,,,,,, +0001,22126,Cañón Palmas,,,,,,,,, +0001,22706,Colinas de Mazatlán,,,,,,,,, +0001,22785,Siena Residencial,,,,,,,,, +0001,23000,Zona Central,,,,,,,,, +0001,23462,Leonardo Gastélum Quinta Etapa,,,,,,,,, +0001,23620,Vargas,,,,,,,,, +0001,24000,San Francisco de Campeche Centro,,,,,,,,, +0001,24153,Residencial Las Palmas,,,,,,,,, +0001,24207,Cronos,,,,,,,,, +0001,24344,Tres de Mayo Tres,,,,,,,,, +0001,24353,Miguel Hidalgo (Caracol),,,,,,,,, +0001,24640,Bellavista,,,,,,,,, +0001,24933,Los Tres Reyes,,,,,,,,, +0001,25000,Saltillo Zona Centro,,,,,,,,, +0001,25352,Autopista,,,,,,,,, +0001,25743,Las Misiones,,,,,,,,, +0001,25903,Rincón del Valle,,,,,,,,, +0001,26015,Los Laureles,,,,,,,,, +0001,26174,El Manantial,,,,,,,,, +0001,26234,Veracruz,,,,,,,,, +0001,26350,Armando Guadiana Tijerina,,,,,,,,, +0001,26510,Álvaro Luna,,,,,,,,, +0001,26729,La Capilla,,,,,,,,, +0001,26820,Mina Siete,,,,,,,,, +0001,27087,Quintas los Nogales,,,,,,,,, +0001,27448,Ladrillera,,,,,,,,, +0001,27545,Chula Vista,,,,,,,,, +0001,27905,Residencial Paraíso,,,,,,,,, +0001,27987,Rogelio Montemayor,,,,,,,,, +0001,28000,Colima Centro,,,,,,,,, +0001,28134,San Ignacio,,,,,,,,, +0001,28307,Hacienda las Primaveras,,,,,,,,, +0001,28400,Valle de las Huertas,,,,,,,,, +0001,28507,Valle Real,,,,,,,,, +0001,28700,Los Gobernadores,,,,,,,,, +0001,28750,27 de Octubre,,,,,,,,, +0001,28864,Almendros Residencial II,,,,,,,,, +0001,28978,Residencial Bosque Real,,,,,,,,, +0001,29000,Tuxtla Gutiérrez Centro,,,,,,,,, +0001,29127,El Carmelo,,,,,,,,, +0001,29130,Lomas del Pedregal,,,,,,,,, +0001,29148,Salvador Urbina,,,,,,,,, +0001,29150,Nandayalu,,,,,,,,, +0001,29180,Cabeza de Agua (San Antonio),,,,,,,,, +0001,29300,Las Palmas Huitepec 3a. Sección,,,,,,,,, +0001,29326,Pajaltón Bajo,,,,,,,,, +0001,29345,Nuevo Porvenir,,,,,,,,, +0001,29369,Chiquinivalvo,,,,,,,,, +0001,29405,Laguna del Carmen,,,,,,,,, +0001,29416,Benito Juárez,,,,,,,,, +0001,29439,San Caralampio Chavín,,,,,,,,, +0001,29446,La Mendoza,,,,,,,,, +0001,29454,El Tzay,,,,,,,,, +0001,29474,San Pedro la Tejería,,,,,,,,, +0001,29489,Chuljá,,,,,,,,, +0001,29490,Xoctón (Xoctoctic),,,,,,,,, +0001,29500,Nueva Esperanza,,,,,,,,, +0001,29540,Nuevo Sunuapa,,,,,,,,, +0001,29553,Playa de Piedra 2da. Sección,,,,,,,,, +0001,29560,Rivera el Viejo Carmen,,,,,,,,, +0001,29572,Loma de Caballo 2a. Sección,,,,,,,,, +0001,29586,Álvaro Obregón,,,,,,,,, +0001,29596,Nuevo Poblado Llanos Morelos,,,,,,,,, +0001,29610,El Edén,,,,,,,,, +0001,29620,San Francisco,,,,,,,,, +0001,29660,San Juan,,,,,,,,, +0001,29670,Magdalena,,,,,,,,, +0001,29684,San José Plan Ocotal,,,,,,,,, +0001,29706,Miguel Hidalgo,,,,,,,,, +0001,29710,Arroyo Sabinal,,,,,,,,, +0001,29729,Monte Chico,,,,,,,,, +0001,29744,La Unión Nueva,,,,,,,,, +0001,29753,Santa Rita,,,,,,,,, +0001,29760,Xitoltepeque,,,,,,,,, +0001,29770,Guadalupe I,,,,,,,,, +0001,29795,San José Chacté,,,,,,,,, +0001,29816,Jesús Carranza,,,,,,,,, +0001,29840,San Isidro,,,,,,,,, +0001,29853,Jolik-alum,,,,,,,,, +0001,29863,Meonho,,,,,,,,, +0001,29876,Canolal,,,,,,,,, +0001,29884,Las Limas,,,,,,,,, +0001,29890,Don Pedro,,,,,,,,, +0001,29903,Arroyo Palenque,,,,,,,,, +0001,29917,Esperanza Ocotal,,,,,,,,, +0001,29920,Santa Bárbara,,,,,,,,, +0001,29926,San Vicente,,,,,,,,, +0001,29943,San Miguel Catarraya,,,,,,,,, +0001,29954,Ramón F. Balboa,,,,,,,,, +0001,29962,El Retiro,,,,,,,,, +0001,29974,Benito Juárez Centro,,,,,,,,, +0001,29990,Boca del Río Chico,,,,,,,,, +0001,30078,Corrala,,,,,,,,, +1798,63548,Rancho de Mariano,,,,,,,,, +1798,67182,Encino de la Silla,,,,,,,,, +1798,69780,San Juan Del Río,,,,,,,,, +1798,74684,La Victoria,,,,,,,,, +1798,76900,El Zorzal,,,,,,,,, +1798,79204,Los Pericos,,,,,,,,, +1798,81912,Tierra Blanca,,,,,,,,, +1798,84624,Tres Marías,,,,,,,,, +1798,86964,Arroyo el Triunfo 2a Sección,,,,,,,,, +1798,89670,La Azufrosa (El Higuerón),,,,,,,,, +1798,93570,Candido Aguilar,,,,,,,,, +1799,11440,Reforma Pensil,,,,,,,,, +1799,21395,Bugambilias,,,,,,,,, +1799,25084,Las Teresitas,,,,,,,,, +1799,30798,Raymundo Enríquez,,,,,,,,, +1799,33455,Potrero de los Bojórquez,,,,,,,,, +1799,35911,Salitrillo,,,,,,,,, +1799,37620,San Juan de Llanos,,,,,,,,, +1799,40040,Ejidal,,,,,,,,, +1799,52167,El Ciprés,,,,,,,,, +1799,60440,Peribán de Ramos,,,,,,,,, +1799,62755,La Esperanza-el Hospital,,,,,,,,, +1799,63534,Rancho de Petra,,,,,,,,, +1799,67186,Josefa Ortiz de Dominguez,,,,,,,,, +1799,69780,San Martin Peras,,,,,,,,, +1799,74685,El Rosario Xochitiopan,,,,,,,,, +1799,76900,El Sorgo,,,,,,,,, +1799,78620,Salinas de Hidalgo Centro,,,,,,,,, +1799,81912,Choipa,,,,,,,,, +1799,83576,Papagos,,,,,,,,, +1799,86967,Miguel Hidalgo Sacaola,,,,,,,,, +1799,92893,Casa Bella,,,,,,,,, +1799,97390,Jardines de Umán,,,,,,,,, +1800,11440,San Juanico,,,,,,,,, +1800,21395,Huertas del Sol,,,,,,,,, +1800,25069,Las Haciendas,,,,,,,,, +1800,30827,San Nicolás Lagartero,,,,,,,,, +1800,33456,Mesa Larga,,,,,,,,, +1800,35917,El Pavo (mineral El Diez),,,,,,,,, +1800,37620,Santo Domingo de Guzmán,,,,,,,,, +1800,40040,Gral. Adrián Castrejón,,,,,,,,, +1800,43688,Zapotlan de Allende,,,,,,,,, +1800,47187,La Gloria,,,,,,,,, +1800,60443,La Yerbabuena,,,,,,,,, +1800,62755,Rancho Gómez,,,,,,,,, +1800,63548,Rancho de Pánfilo,,,,,,,,, +1800,69780,Santiago Petlacala,,,,,,,,, +1800,74688,San Mateo Mimiapan,,,,,,,,, +1800,76902,Santa Lucía,,,,,,,,, +1800,78625,La Gasolinera,,,,,,,,, +1800,81912,Lomas de San Phelipe,,,,,,,,, +1800,83575,Sahop,,,,,,,,, +1800,86967,Apatzingán,,,,,,,,, +1800,89672,Las Flores 1,,,,,,,,, +1800,93604,Casa Blanca,,,,,,,,, +1800,97540,San Juan Izamal,,,,,,,,, +1801,11450,Ahuehuetes Anáhuac,,,,,,,,, +1801,21395,Valle del Colorado,,,,,,,,, +1801,25060,Acueducto,,,,,,,,, +1801,30815,Santa Rita,,,,,,,,, +1801,33460,Las Palomas,,,,,,,,, +1801,35918,Tamanica,,,,,,,,, +1801,37620,Rincón de Ortega,,,,,,,,, +1801,40040,La Raza,,,,,,,,, +1801,43689,20 de Noviembre,,,,,,,,, +1801,47187,Ojo de Agua Rincón Del Molino,,,,,,,,, +1801,52167,Villas San Gregorio,,,,,,,,, +1801,60443,Magallón,,,,,,,,, +1801,62755,El Sifón,,,,,,,,, +1801,63547,Rancho de Santos García,,,,,,,,, +1801,67186,Lucio Blanco,,,,,,,,, +1801,69787,San Miguel Peras,,,,,,,,, +1801,76900,Portal del Ángel,,,,,,,,, +1801,78626,San Pablo,,,,,,,,, +1801,81916,Bellavista,,,,,,,,, +1801,83575,Burócrata,,,,,,,,, +1801,86967,Cuyos de Caoba,,,,,,,,, +1801,89672,Morón,,,,,,,,, +1801,92895,CEAS,,,,,,,,, +1801,97370,Montecarlos,,,,,,,,, +1802,11450,Modelo Pensil,,,,,,,,, +1802,21395,Pimsa III,,,,,,,,, +1802,25197,La Esmeralda,,,,,,,,, +1802,30824,Unión Miramar,,,,,,,,, +1802,33463,El Tecuán,,,,,,,,, +1802,35920,Symon (estación Symon),,,,,,,,, +1802,37623,El Aro,,,,,,,,, +1802,43690,Ahuehuetitla,,,,,,,,, +1802,47187,El Lienzo,,,,,,,,, +1802,60443,San Francisco Peribán,,,,,,,,, +1802,62746,Agua Blanca,,,,,,,,, +1802,63535,Rancho del Bajío,,,,,,,,, +1802,67182,Morenita Guajardo,,,,,,,,, +1802,69790,Coicoyán de las Flores,,,,,,,,, +1802,74690,Tepexi de Rodríguez,,,,,,,,, +1802,76900,Rinconada de la Virgen,,,,,,,,, +1802,78625,El Mirador,,,,,,,,, +1802,81916,Ejidal,,,,,,,,, +1802,83573,La Botella,,,,,,,,, +1802,86967,Vicenta Lombardo Toledano,,,,,,,,, +1802,89673,El Carrizal (Carrera Torres),,,,,,,,, +1802,92770,Ceiba Rica,,,,,,,,, +1802,97302,Las Américas II,,,,,,,,, +1803,11450,Peralitos,,,,,,,,, +1803,21395,Hacienda del Sol,,,,,,,,, +1803,25088,Australia,,,,,,,,, +1803,33464,Ciénega Prieta,,,,,,,,, +1803,35922,Estación Rivas,,,,,,,,, +1803,37623,La Angostura,,,,,,,,, +1803,43670,Plan de Ayala,,,,,,,,, +1803,47187,La Corambre,,,,,,,,, +1803,60442,El Carrizalillo,,,,,,,,, +1803,62743,Ampliación la Biznaga,,,,,,,,, +1803,63544,Rancho Doroteo,,,,,,,,, +1803,69792,Santiago Tilapa,,,,,,,,, +1803,74691,Agua de Santa Ana,,,,,,,,, +1803,76900,Bellavista Mezquites,,,,,,,,, +1803,78625,La Joya,,,,,,,,, +1803,83573,La Presa,,,,,,,,, +1803,86967,Buena Vista 23,,,,,,,,, +1803,89673,El Carrizal Segundo,,,,,,,,, +1803,97249,Hacienda Opichen,,,,,,,,, +1804,11460,Dos Lagos,,,,,,,,, +1804,21395,Villas del Colorado,,,,,,,,, +1804,25057,La Herradura,,,,,,,,, +1804,30828,Reforma,,,,,,,,, +1804,33470,Guadalupe y Calvo Centro,,,,,,,,, +1804,35923,Guadalupito,,,,,,,,, +1804,37623,La Lagunita,,,,,,,,, +1804,40040,Patria Nueva,,,,,,,,, +1804,43670,María Isabel,,,,,,,,, +1804,47187,Los Lobos,,,,,,,,, +1804,60443,Gildardo Magaña (Los Ángeles),,,,,,,,, +1804,62743,Campo Nuevo,,,,,,,,, +1804,63536,Rancho Nuevo (Juventino),,,,,,,,, +1804,67183,Miguel de la Madrid,,,,,,,,, +1804,69799,Tierra Colorada,,,,,,,,, +1804,74692,Las Flores,,,,,,,,, +1804,76900,Los Frailes,,,,,,,,, +1804,78625,La Curva,,,,,,,,, +1804,81607,Labastida Ochoa,,,,,,,,, +1804,83573,La Copa,,,,,,,,, +1804,86966,Francisco I. Madero 1a Sección,,,,,,,,, +1804,89673,Higinio Tanguma,,,,,,,,, +1804,92123,Cerro de La Cruz,,,,,,,,, +1804,97246,Angeles II,,,,,,,,, +1805,11460,Lago Norte,,,,,,,,, +1805,21395,El Sahuaro,,,,,,,,, +1805,25060,La Central,,,,,,,,, +1805,30829,Joaquín Miguel Gutiérrez,,,,,,,,, +1805,33477,San Simón (Calabazas),,,,,,,,, +1805,35925,San Antonio de La Laguna,,,,,,,,, +1805,37624,Altos de Ibarra,,,,,,,,, +1805,40040,Rubén Jaramillo,,,,,,,,, +1805,43695,La Herradura,,,,,,,,, +1805,47196,Santa María del Valle,,,,,,,,, +1805,52168,Municipal,,,,,,,,, +1805,62743,Villareal,,,,,,,,, +1805,63538,Rancho Viejo,,,,,,,,, +1805,67186,Nuevo Almaguer,,,,,,,,, +1805,74692,Yeguas,,,,,,,,, +1805,76900,Villa Antigua,,,,,,,,, +1805,78625,San Juan,,,,,,,,, +1805,81605,Fovissste,,,,,,,,, +1805,83574,Hombres Blancos,,,,,,,,, +1805,86966,Francisco I. Madero 2a Sección,,,,,,,,, +1805,89674,Rancho de Piedra,,,,,,,,, +1805,92773,Cerro de Tumilco,,,,,,,,, +1805,97130,Cumbres de Altabrisa,,,,,,,,, +1806,11460,Lago Sur,,,,,,,,, +1806,25010,Vista Hermosa,,,,,,,,, +1806,30834,El Triunfo,,,,,,,,, +1806,33477,San Ignacio de los Sotelo,,,,,,,,, +1806,35930,Loma Alta,,,,,,,,, +1806,37624,La Ceja,,,,,,,,, +1806,40040,Santo Tomas,,,,,,,,, +1806,43696,Tollancingo,,,,,,,,, +1806,47186,El Nacimiento,,,,,,,,, +1806,60445,Parambén,,,,,,,,, +1806,62748,Vicente Guerrero,,,,,,,,, +1806,63544,Rancho Viejo,,,,,,,,, +1806,67186,San Eduardo,,,,,,,,, +1806,69806,El Ojite,,,,,,,,, +1806,74692,Zacatepec,,,,,,,,, +1806,76900,Huertas de la Virgen,,,,,,,,, +1806,78624,San Isidro,,,,,,,,, +1806,80804,Las Delicias,,,,,,,,, +1806,83342,Carnavalito,,,,,,,,, +1806,86933,Asunción,,,,,,,,, +1806,89677,Las Yucas,,,,,,,,, +1806,93330,Circulo Michoacano,,,,,,,,, +1806,97306,Los Héroes,,,,,,,,, +1807,11460,Los Manzanos,,,,,,,,, +1807,21397,Pimsa II,,,,,,,,, +1807,25057,Los Nogales II,,,,,,,,, +1807,30832,Los Leoncillos,,,,,,,,, +1807,33485,Santa Rita,,,,,,,,, +1807,35932,San Antonio del Refugio,,,,,,,,, +1807,37624,San José del Tanque,,,,,,,,, +1807,40040,3 Marías,,,,,,,,, +1807,47188,El Carrizal de Abajo,,,,,,,,, +1807,52168,Solidaridad Electricistas,,,,,,,,, +1807,60446,San José Apupátaro,,,,,,,,, +1807,62748,Vicente Guerrero 4ta Ampliación,,,,,,,,, +1807,63546,Sacaymota,,,,,,,,, +1807,67184,Condado de Santa Lucía,,,,,,,,, +1807,69806,Juan Escutia Juquila,,,,,,,,, +1807,74693,Progreso,,,,,,,,, +1807,76900,Haciendas del Pueblito,,,,,,,,, +1807,78624,La Huerta,,,,,,,,, +1807,80807,Aviación,,,,,,,,, +1807,83342,Artesanos,,,,,,,,, +1807,86974,San Marcos,,,,,,,,, +1807,89678,Nuevo Progreso (La Gaviota),,,,,,,,, +1807,97380,El Zapotal,,,,,,,,, +1808,11470,5 de Mayo,,,,,,,,, +1808,21399,Punta de Estrella,,,,,,,,, +1808,25138,Emilio Carranza,,,,,,,,, +1808,30832,Morelos,,,,,,,,, +5782,73566,Tepetitán ( Reyeshogpan ),,,,,,,,, +5782,85207,Renato Campoy,,,,,,,,, +5782,95673,Paso del Ganado (La Loma),,,,,,,,, +5783,30123,El Naranjo,,,,,,,,, +5783,33198,Laguna de Aboreachi,,,,,,,,, +5783,34593,Los Cimientos,,,,,,,,, +5783,36212,Juan Muñoz,,,,,,,,, +5783,42345,La Majada,,,,,,,,, +5783,47520,Varela,,,,,,,,, +5783,54665,La Planada,,,,,,,,, +5783,60946,El Cerro,,,,,,,,, +5783,65547,Salsipuedes,,,,,,,,, +5783,70515,La Esperanza,,,,,,,,, +5783,73563,Tepetzalan ( Tezoquita ),,,,,,,,, +5783,85206,René Esquer,,,,,,,,, +5783,95673,Monte Rosa,,,,,,,,, +5784,30780,Hierbabuena,,,,,,,,, +5784,33997,San Isidro,,,,,,,,, +5784,34585,Los Copalitos,,,,,,,,, +5784,36214,Juan Nila Ramírez,,,,,,,,, +5784,42359,La Majada Grande,,,,,,,,, +5784,47506,Villa del Carmen,,,,,,,,, +5784,54665,Santa Bárbara,,,,,,,,, +5784,60936,El Cerro Verde,,,,,,,,, +5784,65547,El Sarro,,,,,,,,, +5784,70504,La Flor,,,,,,,,, +5784,73566,Tepetzintan,,,,,,,,, +5784,85213,René Mercado,,,,,,,,, +5785,29050,Las Palomas,,,,,,,,, +5785,31610,Campo Número Ciento Nueve,,,,,,,,, +5785,34583,Los Coyotes,,,,,,,,, +5785,36215,Juan Ramírez Rangel,,,,,,,,, +5785,42343,La Mesa,,,,,,,,, +5785,47527,Villas Ecológicas los Nardos (Los Nardos),,,,,,,,, +5785,54668,Pueblo Nuevo,,,,,,,,, +5785,60944,El Changungo,,,,,,,,, +5785,65547,San Juan,,,,,,,,, +5785,70507,La Magdalena,,,,,,,,, +5785,73566,Tuzamapan (Xiloxochico),,,,,,,,, +5785,85208,Reparaciones Aéreas del Yaqui,,,,,,,,, +5785,95686,Mata de Caña,,,,,,,,, +5786,29165,Santa Ana,,,,,,,,, +5786,31605,Campo Número Treinta y Cuatro,,,,,,,,, +5786,34594,Los Cuates,,,,,,,,, +5786,36215,Juan Silva,,,,,,,,, +5786,42342,La Mesa de Camposanto del Oro,,,,,,,,, +5786,47514,Villegas,,,,,,,,, +5786,54665,Reyes,,,,,,,,, +5786,60924,El Chicharrón,,,,,,,,, +5786,65547,Arturo Quiroga,,,,,,,,, +5786,70515,Las Flores,,,,,,,,, +5786,73563,Tzojiaco,,,,,,,,, +5786,85213,Represo (El Jeroglífico),,,,,,,,, +5786,95676,La Soledad,,,,,,,,, +5787,29094,Sauce,,,,,,,,, +5787,31684,Rancho Carpio,,,,,,,,, +5787,34573,Los Desmontes,,,,,,,,, +5787,36210,Justino Gutiérrez,,,,,,,,, +5787,42344,La Milpota,,,,,,,,, +5787,47515,Zitácuaro,,,,,,,,, +5787,54665,Caltenco,,,,,,,,, +5787,60927,El Chinillo (Puerto Limón),,,,,,,,, +5787,65547,Los Martínez,,,,,,,,, +5787,70504,Llano Ocote,,,,,,,,, +5787,73566,Xalcuahuta,,,,,,,,, +5787,85209,Reproductora Pesada 2515 ó 2415,,,,,,,,, +5787,95679,La Luisa Antigua,,,,,,,,, +5788,29473,San Isidro,,,,,,,,, +5788,33274,Nuevo Palomas,,,,,,,,, +5788,34577,Los Frailes,,,,,,,,, +5788,36214,La Adriana,,,,,,,,, +5788,42344,La Rinconada,,,,,,,,, +5788,48280,Verde Vallarta,,,,,,,,, +5788,54668,San Juan,,,,,,,,, +5788,60927,El Chino,,,,,,,,, +5788,65547,El León,,,,,,,,, +5788,70503,Los Lengüitos (Rancho el Carmen),,,,,,,,, +5788,73563,Xalpantzingo,,,,,,,,, +5788,85203,Reyes Domínguez,,,,,,,,, +5788,95679,La Floreadora (La Bodega),,,,,,,,, +5789,30916,23 de Abril,,,,,,,,, +5789,33583,11 de Julio,,,,,,,,, +5789,34577,Los Frailitos,,,,,,,,, +5789,36212,La Bonita del Pochote,,,,,,,,, +5789,42345,La Ruda,,,,,,,,, +5789,47425,De la Luz,,,,,,,,, +5789,54783,La Providencia,,,,,,,,, +5789,60923,Las Palmas,,,,,,,,, +5789,65547,Doctor Ramón (Raíces),,,,,,,,, +5789,70504,Los Magueyales,,,,,,,,, +5789,73563,Xaltzinta,,,,,,,,, +5789,85203,Ricardo Hurtado,,,,,,,,, +5790,30866,Los Naranjos,,,,,,,,, +5790,33586,21 de Marzo,,,,,,,,, +5790,34596,Los Giotes,,,,,,,,, +5790,36212,La Bonita del Pochote Dos,,,,,,,,, +5790,42340,La Tinaja Durango,,,,,,,,, +5790,47490,De Padre Torres,,,,,,,,, +5790,56386,Rancho San Miguel,,,,,,,,, +5790,60926,El Cirián,,,,,,,,, +5790,65548,Picachos de los Abuelos,,,,,,,,, +5790,70507,Los Orozco,,,,,,,,, +5790,73563,Xochical,,,,,,,,, +5790,85203,Ricardo Topete,,,,,,,,, +5790,95686,Santa Rosa,,,,,,,,, +5791,30683,La Flor,,,,,,,,, +5791,33594,Alamito,,,,,,,,, +5791,34575,Los Guajolotes,,,,,,,,, +5791,36212,La Casa de Ángel,,,,,,,,, +5791,42354,La Venta de Coaxithi,,,,,,,,, +5791,47480,Del Carmen,,,,,,,,, +5791,55717,Ex-Hacienda San Felipe 2a. Sección,,,,,,,,, +5791,60923,El Cirián,,,,,,,,, +5791,65548,El Orégano,,,,,,,,, +5791,70504,Los Ranchos,,,,,,,,, +5791,72014,El Conde,,,,,,,,, +5791,85207,Rita Gómez (Bloque 1903),,,,,,,,, +5791,95264,Lomas Residencial,,,,,,,,, +5792,30907,Ranchería El Carmen,,,,,,,,, +5792,33597,Arroyo Prieto,,,,,,,,, +5792,34573,Los Inmortales,,,,,,,,, +5792,36212,La Casa de Vicente,,,,,,,,, +5792,42359,La Ventolera,,,,,,,,, +5792,47457,Los Tepetates,,,,,,,,, +5792,55717,Rancho la Palma 2a Sección,,,,,,,,, +5792,60934,El Cirul,,,,,,,,, +5792,65520,Los Reyes,,,,,,,,, +5792,70515,Oaxaca,,,,,,,,, +5792,72480,Galaxia la Laguna,,,,,,,,, +5792,85203,Roberto Encinas (Tozalcahui),,,,,,,,, +5793,30356,Nuevo Tepeyac,,,,,,,,, +5793,33593,Bajío de Enmedio,,,,,,,,, +5793,34594,Los Jacales,,,,,,,,, +5793,36210,La Casa del Alto (Miguel Hinojosa),,,,,,,,, +5793,42354,Las Pilas,,,,,,,,, +5793,47410,El Tepeyac 2a Sección,,,,,,,,, +5793,55717,Rancho la Palma 3a Sección,,,,,,,,, +5793,60926,El Cóbano,,,,,,,,, +5793,66085,Praderas de San Francisco Sector 2,,,,,,,,, +5793,70503,Ojo de Agua,,,,,,,,, +5793,75916,Tepepa de Zaragoza,,,,,,,,, +5793,85203,Roberto Flores,,,,,,,,, +5794,30504,Miguel Hidalgo 1,,,,,,,,, +5794,33590,Bloquera,,,,,,,,, +5794,34594,Los Laureles,,,,,,,,, +5794,36216,La Casa del Durazno,,,,,,,,, +5794,42345,Las Pilas,,,,,,,,, +5794,47410,Geovillas de los Lagos,,,,,,,,, +5794,60924,El Cordón Alto,,,,,,,,, +5794,64180,Privada Cumbres,,,,,,,,, +5794,70516,Ojo de Caballo,,,,,,,,, +5794,75916,Playa Vicente,,,,,,,,, +5794,85205,Roberto Rodríguez,,,,,,,,, +5795,29050,Santa Isabel,,,,,,,,, +5795,33597,Cabras,,,,,,,,, +5795,34573,Los Laureles,,,,,,,,, +5795,36210,La Caseta,,,,,,,,, +5795,42356,Las Piletas,,,,,,,,, +5795,47443,Jardines de Vista Hermosa,,,,,,,,, +5795,55738,Asociación de Comerciantes de Coacalco,,,,,,,,, +5795,60935,El Corongorito,,,,,,,,, +5795,67050,El Maestro,,,,,,,,, +5795,70506,Rancho Candelaria,,,,,,,,, +5795,75917,Esperanza,,,,,,,,, +5795,85207,Roberto Serna Yáñez,,,,,,,,, +5796,30483,Delicias del Carmen,,,,,,,,, +5796,33594,Chaveño,,,,,,,,, +5796,34584,Los Limones,,,,,,,,, +5796,36210,La Concepción de Fernández,,,,,,,,, +5796,42346,Las Vegas,,,,,,,,, +5796,47410,La Laguna,,,,,,,,, +5796,55738,Xalatlaco (Imevis),,,,,,,,, +5796,60925,El Cuchi,,,,,,,,, +5796,67050,Valle de San Felipe,,,,,,,,, +5796,70508,Rancho Río Mamey,,,,,,,,, +5796,75917,Macuilcuautitla,,,,,,,,, +5796,85218,Roberto Valencia,,,,,,,,, +5797,30835,Genaro Vázquez Rojas,,,,,,,,, +5797,33593,Chicanaya,,,,,,,,, +5797,34575,Los Limones,,,,,,,,, +5797,36213,La Cumbre,,,,,,,,, +5797,42344,Llano Blanco,,,,,,,,, +5797,47474,La Loma,,,,,,,,, +5797,55738,Hacienda Taxco Viejo,,,,,,,,, +5797,60923,El Cuirindal,,,,,,,,, +5797,70508,Río Guela,,,,,,,,, +5797,75917,Ocotempa,,,,,,,,, +5797,85203,Robolud (Carlos Lubbert),,,,,,,,, +5798,30034,27 de Junio,,,,,,,,, +5798,33596,Cinco de Mayo,,,,,,,,, +5798,34570,Los Llanitos,,,,,,,,, +5798,36216,La Efigenia (Los Ruiseñor),,,,,,,,, +5798,42342,Los Duraznos,,,,,,,,, +5798,47480,Lagos de Moreno,,,,,,,,, +5798,60926,El Cuirindal,,,,,,,,, +5798,64215,23 de Marzo,,,,,,,,, +5798,70515,Río Nopal,,,,,,,,, +5798,75915,Boca del Monte,,,,,,,,, +5798,85213,Rodolfo Monge,,,,,,,,, +5799,30883,San José Cerro del Carmen,,,,,,,,, +5799,33596,Clarines,,,,,,,,, +5799,34574,Los Llanos,,,,,,,,, +5799,36212,La Escondida,,,,,,,,, +5799,42342,Los Mármoles,,,,,,,,, +5799,47440,Las Palmas,,,,,,,,, +5799,55700,Bonito Coacalco,,,,,,,,, +5799,60935,El Descansadero,,,,,,,,, +5799,64988,La Alhambra,,,,,,,,, +5799,70503,San Antonio los Guajes,,,,,,,,, +5799,75917,Moyotepec,,,,,,,,, +5799,85209,Rodrigo Campoy,,,,,,,,, +5800,30164,San Pedro el Porvenir,,,,,,,,, +5800,33596,Cobriza,,,,,,,,, +5800,34575,Los Llanos de Tabahueto,,,,,,,,, +5800,36214,La Esmeralda,,,,,,,,, +5800,42340,Los Nogales,,,,,,,,, +5800,47457,Maravillas,,,,,,,,, +5800,55700,Hacienda Capultitla,,,,,,,,, +5800,60924,El Encino,,,,,,,,, +9886,33637,Los Ramírez,,,,,,,,, +9887,33637,Los Rey,,,,,,,,, +9888,33637,Los Rodríguez,,,,,,,,, +9889,33637,Los Rodríguez,,,,,,,,, +9890,33637,Los Salas,,,,,,,,, +9891,33637,Los Salazar,,,,,,,,, +9892,33637,Los Sepúlveda,,,,,,,,, +9893,33637,Los Sánchez,,,,,,,,, +9894,33637,Los Tarango,,,,,,,,, +9895,33633,Los Tres Sietes,,,,,,,,, +9896,33637,Lote Ciento Quince Tres (El Embudo),,,,,,,,, +9897,33637,Lote Ciento Siete Dos,,,,,,,,, +9898,33637,Luis Flores,,,,,,,,, +9899,33633,Mangas del Jagüey,,,,,,,,, +9900,33633,Margaritas,,,,,,,,, +9901,33637,Mario Reyes,,,,,,,,, +9902,33633,María,,,,,,,,, +9903,33637,María de los Ángeles Martínez,,,,,,,,, +9904,33637,María Vargas,,,,,,,,, +9905,33637,Matías Bejarano,,,,,,,,, +9906,33637,Mi Ranchito,,,,,,,,, +9907,33637,Mi Ranchito (Los Acosta),,,,,,,,, +9908,33637,Miguel Ronquillo,,,,,,,,, +9909,33645,Ninguno [Campo de Golf],,,,,,,,, +9910,33637,No Me Olvides,,,,,,,,, +9911,33633,Nogales Okinawa,,,,,,,,, +9912,33637,Nuevo Saucillo,,,,,,,,, +9913,33637,Palma Sola,,,,,,,,, +9914,33637,Palos Clavados,,,,,,,,, +9915,33637,Palos Parados,,,,,,,,, +9916,33637,Pepe Payán,,,,,,,,, +9917,33644,Picacho de Abajo (Urruteño),,,,,,,,, +9918,33637,Piedra de Lumbre,,,,,,,,, +9919,33637,Piedra de Lumbre,,,,,,,,, +9920,33633,Plan de Álamos,,,,,,,,, +9921,33637,Prospereño,,,,,,,,, +9922,33633,Pueblo Quieto,,,,,,,,, +9923,33637,Ramón Gallegos,,,,,,,,, +9924,33637,Ramón Meléndez,,,,,,,,, +9925,33633,Ranchito Don Trini González,,,,,,,,, +9926,33637,Rancho ARZ (El Acuerdo),,,,,,,,, +9927,33633,Rancho Baeza,,,,,,,,, +9928,33637,Rancho Carrasco,,,,,,,,, +9929,33633,Rancho de Carrillo,,,,,,,,, +9930,33633,Rancho de Gómez,,,,,,,,, +9931,33633,Rancho de Madero,,,,,,,,, +9932,33633,Rancho Dos Hermanos (Hermanos Cárdenas),,,,,,,,, +9933,33637,Rancho el Canal,,,,,,,,, +9934,33637,Rancho el Huevo,,,,,,,,, +9935,33637,Rancho el Socorro,,,,,,,,, +9936,33637,Rancho Grande,,,,,,,,, +9937,33637,Rancho Guerrero Hernández,,,,,,,,, +9938,33637,Rancho la Mora,,,,,,,,, +9939,33637,Rancho la Otra,,,,,,,,, +9940,33633,Rancho la Piedra,,,,,,,,, +9941,33637,Rancho la Pollera (Cuatro Hermanos),,,,,,,,, +9942,33637,Rancho la Quinta,,,,,,,,, +9943,33633,Rancho los Tres Octavios,,,,,,,,, +9944,33637,Rancho Nogales,,,,,,,,, +9945,33644,Rancho Nueve de Abril,,,,,,,,, +9946,33637,Rancho Nueve de Enero,,,,,,,,, +9947,33644,Rancho Nuevo,,,,,,,,, +9948,33637,Rancho Ramón Aragón Chávez,,,,,,,,, +9949,33637,Rancho Rocío,,,,,,,,, +9950,33637,Rancho Rubén Ontiveros,,,,,,,,, +9951,33637,Rancho Salcido,,,,,,,,, +9952,33633,Rancho San Carlos,,,,,,,,, +9953,33633,Rancho San José,,,,,,,,, +9954,33633,Rancho San Juan,,,,,,,,, +9955,33637,Rancho San Luis,,,,,,,,, +9956,33637,Rancho Santa Librada,,,,,,,,, +9957,33644,Rancho Seco,,,,,,,,, +9958,33633,Rancho Veintiuno de Marzo,,,,,,,,, +9959,33637,Rancho Zambrano,,,,,,,,, +9960,33645,René Cadena,,,,,,,,, +9961,33637,Roberto Burrola,,,,,,,,, +9962,33636,Ronquillo,,,,,,,,, +9963,33637,Rosalío Hernández,,,,,,,,, +9964,33637,Rubén López,,,,,,,,, +9965,33633,Salgadeño,,,,,,,,, +9966,33637,Salsipuedes,,,,,,,,, +9967,33637,San Andrés,,,,,,,,, +9968,33637,San Antonio,,,,,,,,, +9969,33637,San Antonio,,,,,,,,, +9970,33633,San Antonio,,,,,,,,, +9971,33637,San Bernardino [Corrales],,,,,,,,, +9972,33637,San Carlos,,,,,,,,, +9973,33637,San Carlos (Carlos Bario),,,,,,,,, +9974,33633,San Esteban,,,,,,,,, +9975,33635,San Esteban,,,,,,,,, +9976,33637,San Francisco,,,,,,,,, +9977,33637,San Ignacio [Corrales],,,,,,,,, +9978,33637,San Isidro,,,,,,,,, +9979,33637,San José,,,,,,,,, +9980,33637,San José,,,,,,,,, +9981,33637,San José,,,,,,,,, +9982,33637,San José,,,,,,,,, +9983,33636,San José,,,,,,,,, +9984,33633,San José,,,,,,,,, +9985,33636,San José (La Escondida),,,,,,,,, +9986,33635,San José de Colomo,,,,,,,,, +9987,33636,San José de los Pozos,,,,,,,,, +9988,33633,San Juanito,,,,,,,,, +9989,33637,San Judas Tadeo,,,,,,,,, +9990,33637,San Judas Tadeo (El Gringo),,,,,,,,, +9991,33637,San Lorenzo [Cocedores],,,,,,,,, +9992,33636,San Marcos,,,,,,,,, +9993,33637,San Marcos,,,,,,,,, +9994,33637,San Martín,,,,,,,,, +9995,33637,San Vicente,,,,,,,,, +9996,33637,Santa Eduviges,,,,,,,,, +9997,33637,Santa Elena,,,,,,,,, +9998,33637,Santa Elena,,,,,,,,, +9999,33635,Santa Martha,,,,,,,,, diff --git a/tests/_files/cfdi40/C_Localidad.csv b/tests/_files/cfdi40/C_Localidad.csv new file mode 100644 index 0000000..dd40f76 --- /dev/null +++ b/tests/_files/cfdi40/C_Localidad.csv @@ -0,0 +1,668 @@ +Catálogo de localidades. ,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_Localidad,c_Estado,Descripción,Fecha de inicio de vigencia,Fecha de fin de vigencia,,,,,,, +01,AGU,Aguascalientes,2022-01-01,,,,,,,, +01,BCN,Ensenada,2022-01-01,,,,,,,, +01,BCS,Ciudad Constitución,2022-01-01,,,,,,,, +01,CAM,San Francisco de Campeche,2022-01-01,,,,,,,, +01,COA,Ciudad Acuña,2022-01-01,,,,,,,, +01,COL,Colima,2022-01-01,,,,,,,, +01,CHH,Santa Rosalía de Camargo,2022-01-01,,,,,,,, +01,CHP,Comitán de Domínguez,2022-01-01,,,,,,,, +01,CMX,Ciudad de México,2022-01-01,,,,,,,, +01,DUR,Victoria de Durango,2022-01-01,,,,,,,, +01,GRO,Acapulco de Juárez,2022-01-01,,,,,,,, +01,GUA,Acámbaro,2022-01-01,,,,,,,, +01,HID,Actopan,2022-01-01,,,,,,,, +01,JAL,Ameca,2022-01-01,,,,,,,, +01,MEX,Ciudad Adolfo López Mateos,2022-01-01,,,,,,,, +01,MIC,Apatzingán de la Constitución,2022-01-01,,,,,,,, +01,MOR,Cuautla (Cuautla de Morelos),2022-01-01,,,,,,,, +01,NAY,Santiago Ixcuintla,2022-01-01,,,,,,,, +01,NLE,Ciudad Apodaca,2022-01-01,,,,,,,, +01,OAX,Juchitán (Juchitán de Zaragoza),2022-01-01,,,,,,,, +01,PUE,Atlixco,2022-01-01,,,,,,,, +01,QUE,Querétaro,2022-01-01,,,,,,,, +01,ROO,Cancún,2022-01-01,,,,,,,, +01,SIN,Los Mochis,2022-01-01,,,,,,,, +01,SLP,Ciudad Valles,2022-01-01,,,,,,,, +01,SON,San Luis Río Colorado,2022-01-01,,,,,,,, +01,TAB,Cárdenas,2022-01-01,,,,,,,, +01,TAM,Altamira,2022-01-01,,,,,,,, +01,TLA,Apizaco,2022-01-01,,,,,,,, +01,VER,Acayucan,2022-01-01,,,,,,,, +01,YUC,Mérida,2022-01-01,,,,,,,, +01,ZAC,Fresnillo,2022-01-01,,,,,,,, +02,AGU,Calvillo,2022-01-01,,,,,,,, +02,BCN,Mexicali,2022-01-01,,,,,,,, +02,BCS,La Paz,2022-01-01,,,,,,,, +02,CAM,Ciudad del Carmen,2022-01-01,,,,,,,, +02,COA,Frontera,2022-01-01,,,,,,,, +02,COL,Manzanillo,2022-01-01,,,,,,,, +02,CHH,Chihuahua,2022-01-01,,,,,,,, +02,CHP,San Cristóbal de las Casas,2022-01-01,,,,,,,, +02,CMX,Ciudad de México,2022-01-01,,,,,,,, +02,DUR,Gómez Palacio,2022-01-01,,,,,,,, +02,GRO,Chilpancingo de los Bravo,2022-01-01,,,,,,,, +02,GUA,San miguel de Allende,2022-01-01,,,,,,,, +02,HID,Apan,2022-01-01,,,,,,,, +02,JAL,Ciudad Guzmán,2022-01-01,,,,,,,, +02,MEX,Chimalhuacán,2022-01-01,,,,,,,, +02,MIC,Los Reyes de Salgado,2022-01-01,,,,,,,, +02,MOR,Cuernavaca,2022-01-01,,,,,,,, +02,NAY,Tepic,2022-01-01,,,,,,,, +02,NLE,San Pedro Garza García,2022-01-01,,,,,,,, +02,OAX,Oaxaca de Juárez,2022-01-01,,,,,,,, +02,PUE,Izúcar de Matamoros,2022-01-01,,,,,,,, +02,QUE,San Juan del Rio,2022-01-01,,,,,,,, +02,ROO,Cozumel,2022-01-01,,,,,,,, +02,SIN,Culiacán Rosales,2022-01-01,,,,,,,, +02,SLP,Ébano,2022-01-01,,,,,,,, +02,SON,Agua Prieta,2022-01-01,,,,,,,, +02,TAB,Villahermosa,2022-01-01,,,,,,,, +02,TAM,Ciudad Camargo,2022-01-01,,,,,,,, +02,TLA,Villa Vicente Guerrero,2022-01-01,,,,,,,, +02,VER,Naranjos,2022-01-01,,,,,,,, +02,YUC,Tizimín,2022-01-01,,,,,,,, +02,ZAC,Jerez de García Salinas,2022-01-01,,,,,,,, +03,AGU,San Francisco de los Romo,2022-01-01,,,,,,,, +03,BCN,Tecate,2022-01-01,,,,,,,, +03,BCS,Cabo San Lucas,2022-01-01,,,,,,,, +03,CAM,Calkiní,2022-01-01,,,,,,,, +03,COA,Matamoros,2022-01-01,,,,,,,, +03,COL,Tecoman,2022-01-01,,,,,,,, +03,CHH,Cuauhtémoc,2022-01-01,,,,,,,, +03,CHP,Tapachula de Córdova y Ordóñez,2022-01-01,,,,,,,, +03,CMX,Ciudad de México,2022-01-01,,,,,,,, +03,DUR,Ciudad Lerdo,2022-01-01,,,,,,,, +03,GRO,Iguala de la Independencia,2022-01-01,,,,,,,, +03,GUA,Celaya,2022-01-01,,,,,,,, +03,HID,Pachuca de Soto,2022-01-01,,,,,,,, +03,JAL,Guadalajara,2022-01-01,,,,,,,, +03,MEX,Coacalco de Berriozabal,2022-01-01,,,,,,,, +03,MIC,Ciudad Hidalgo,2022-01-01,,,,,,,, +03,MOR,Galeana,2022-01-01,,,,,,,, +03,NAY,Tuxpan,2022-01-01,,,,,,,, +03,NLE,Ciudad General Escobedo,2022-01-01,,,,,,,, +03,OAX,Salina Cruz,2022-01-01,,,,,,,, +03,PUE,Puebla (Heroica Puebla),2022-01-01,,,,,,,, +03,ROO,Felipe Carrillo Puerto,2022-01-01,,,,,,,, +03,SIN,Escuinapa de Hidalgo,2022-01-01,,,,,,,, +03,SLP,Matehuala,2022-01-01,,,,,,,, +03,SON,Heroica Caborca,2022-01-01,,,,,,,, +03,TAB,Comalcalco,2022-01-01,,,,,,,, +03,TAM,Ciudad Madero,2022-01-01,,,,,,,, +03,TLA,Tlaxcala (Tlaxcala de Xicotencatl),2022-01-01,,,,,,,, +03,VER,Boca del RÍo,2022-01-01,,,,,,,, +03,YUC,Ticul,2022-01-01,,,,,,,, +03,ZAC,Zacatecas,2022-01-01,,,,,,,, +04,AGU,Jesús María,2022-01-01,,,,,,,, +04,BCN,Tijuana,2022-01-01,,,,,,,, +04,BCS,San José del Cabo,2022-01-01,,,,,,,, +04,CAM,Candelaria,2022-01-01,,,,,,,, +04,COA,Monclova,2022-01-01,,,,,,,, +04,COL,Ciudad de Villa de Álvarez,2022-01-01,,,,,,,, +04,CHH,Delicias,2022-01-01,,,,,,,, +04,CHP,Tuxtla Gutiérrez,2022-01-01,,,,,,,, +04,CMX,Ciudad de México,2022-01-01,,,,,,,, +04,DUR,Santiago Papasquiaro,2022-01-01,,,,,,,, +04,GRO,Taxco de Alarcón,2022-01-01,,,,,,,, +04,GUA,Cortazar,2022-01-01,,,,,,,, +04,HID,Cd. de Fray Bernardino de Sahagún,2022-01-01,,,,,,,, +04,JAL,Lagos de Moreno,2022-01-01,,,,,,,, +04,MEX,Cuautitlán Izcalli,2022-01-01,,,,,,,, +04,MIC,Jacona de Plancarte,2022-01-01,,,,,,,, +04,MOR,Jojutla,2022-01-01,,,,,,,, +04,NAY,Acaponeta,2022-01-01,,,,,,,, +04,NLE,Guadalupe,2022-01-01,,,,,,,, +04,OAX,San Juan Bautista Tuxtepec,2022-01-01,,,,,,,, +04,PUE,San Martín Texmelucan de Labastida,2022-01-01,,,,,,,, +04,QUE,El Pueblito,2022-01-01,,,,,,,, +04,ROO,Chetumal,2022-01-01,,,,,,,, +04,SIN,Guasave,2022-01-01,,,,,,,, +04,SLP,Rioverde,2022-01-01,,,,,,,, +04,SON,Ciudad Obregón,2022-01-01,,,,,,,, +04,TAB,Emiliano Zapata,2022-01-01,,,,,,,, +04,TAM,Ciudad Mante,2022-01-01,,,,,,,, +04,TLA,Huamantla,2022-01-01,,,,,,,, +04,VER,Coatepec,2022-01-01,,,,,,,, +04,YUC,Motul de Carrillo Puerto,2022-01-01,,,,,,,, +04,ZAC,Guadalupe,2022-01-01,,,,,,,, +05,AGU,Pabellón de Arteaga,2022-01-01,,,,,,,, +05,BCN,Playas de Rosarito,2022-01-01,,,,,,,, +05,BCS,Loreto,2022-01-01,,,,,,,, +05,CAM,Escárcega,2022-01-01,,,,,,,, +05,COA,Parras de la Fuente,2022-01-01,,,,,,,, +05,COL,Ciudad de Armería,2022-01-01,,,,,,,, +05,CHH,Hidalgo del Parral,2022-01-01,,,,,,,, +05,CHP,Venustiano Carranza,2022-01-01,,,,,,,, +05,CMX,Ciudad de México,2022-01-01,,,,,,,, +05,DUR,Canatlán,2022-01-01,,,,,,,, +05,GRO,Arcelia,2022-01-01,,,,,,,, +05,GUA,Guanajuato,2022-01-01,,,,,,,, +05,HID,Tula de Allende,2022-01-01,,,,,,,, +05,JAL,Ocotlán,2022-01-01,,,,,,,, +05,MEX,Ecatepec de Morelos,2022-01-01,,,,,,,, +05,MIC,La piedad de Cabadas,2022-01-01,,,,,,,, +05,MOR,Puente de Ixtla,2022-01-01,,,,,,,, +05,NAY,Tecuala,2022-01-01,,,,,,,, +05,NLE,Linares,2022-01-01,,,,,,,, +05,OAX,Matías Romero Avendaño,2022-01-01,,,,,,,, +05,PUE,Tehuacan,2022-01-01,,,,,,,, +05,ROO,Playa del Carmen,2022-01-01,,,,,,,, +05,SIN,Mazatlán,2022-01-01,,,,,,,, +05,SLP,San Luis Potosí,2022-01-01,,,,,,,, +05,SON,Empalme,2022-01-01,,,,,,,, +05,TAB,Jalpa de Méndez,2022-01-01,,,,,,,, +05,TAM,Heroica Matamoros,2022-01-01,,,,,,,, +05,TLA,Calpulalpan,2022-01-01,,,,,,,, +05,VER,Agua dulce,2022-01-01,,,,,,,, +05,YUC,Valladolid,2022-01-01,,,,,,,, +05,ZAC,Río Grande,2022-01-01,,,,,,,, +06,AGU,Rincón de Romos,2022-01-01,,,,,,,, +06,BCN,Rodolfo Sánchez T. (Maneadero),2022-01-01,,,,,,,, +06,BCS,Puerto Adolfo López Mateos,2022-01-01,,,,,,,, +06,CAM,Sabancuy,2022-01-01,,,,,,,, +06,COA,Piedras Negras,2022-01-01,,,,,,,, +06,CHH,Juárez,2022-01-01,,,,,,,, +06,CHP,Jiquipilas,2022-01-01,,,,,,,, +06,CMX,Ciudad de México,2022-01-01,,,,,,,, +06,DUR,San Juan del Río del Centauro del Norte,2022-01-01,,,,,,,, +06,GRO,Ayutla de los Libres,2022-01-01,,,,,,,, +06,GUA,Irapuato,2022-01-01,,,,,,,, +06,HID,Tulancingo,2022-01-01,,,,,,,, +06,JAL,Puerto Vallarta,2022-01-01,,,,,,,, +06,MEX,Huixquilucan de Degollado,2022-01-01,,,,,,,, +06,MIC,Morelia,2022-01-01,,,,,,,, +06,MOR,Santa Rosa Treinta,2022-01-01,,,,,,,, +06,NAY,Compostela,2022-01-01,,,,,,,, +06,NLE,Montemorelos,2022-01-01,,,,,,,, +06,OAX,Heroica Ciudad de Huajuapan de León,2022-01-01,,,,,,,, +06,PUE,Teziutlan,2022-01-01,,,,,,,, +06,ROO,Kantunilkin,2022-01-01,,,,,,,, +06,SIN,Guamúchil,2022-01-01,,,,,,,, +06,SLP,Soledad de Graciano Sánchez,2022-01-01,,,,,,,, +06,SON,Heroica Guaymas,2022-01-01,,,,,,,, +06,TAM,Nuevo Laredo,2022-01-01,,,,,,,, +06,TLA,Chiautempan,2022-01-01,,,,,,,, +06,VER,Coatzacoalcos,2022-01-01,,,,,,,, +06,YUC,Kanasín,2022-01-01,,,,,,,, +06,ZAC,Ciudad Cuauhtémoc,2022-01-01,,,,,,,, +07,AGU,Asientos,2022-01-01,,,,,,,, +07,BCN,San Felipe,2022-01-01,,,,,,,, +07,BCS,Todos Santos,2022-01-01,,,,,,,, +07,CAM,Hopelchén,2022-01-01,,,,,,,, +07,COA,Sabinas,2022-01-01,,,,,,,, +07,CHH,Nuevo Casas Grandes,2022-01-01,,,,,,,, +07,CHP,Villaflores,2022-01-01,,,,,,,, +07,CMX,Ciudad de México,2022-01-01,,,,,,,, +07,DUR,Peñón Blanco,2022-01-01,,,,,,,, +07,GRO,Atoyac de Álvarez,2022-01-01,,,,,,,, +07,GUA,León de los Aldama,2022-01-01,,,,,,,, +07,HID,Zimapan,2022-01-01,,,,,,,, +07,JAL,San Juan de los Lagos,2022-01-01,,,,,,,, +07,MEX,Los Reyes Acaquilpan (La Paz),2022-01-01,,,,,,,, +07,MIC,Pátzcuaro,2022-01-01,,,,,,,, +07,MOR,Zacatepec de Hidalgo,2022-01-01,,,,,,,, +07,NAY,Francisco I. Madero (Puga),2022-01-01,,,,,,,, +07,NLE,Monterrey,2022-01-01,,,,,,,, +07,OAX,Loma Bonita,2022-01-01,,,,,,,, +07,PUE,San Andrés Cholula,2022-01-01,,,,,,,, +07,ROO,Isla Mujeres,2022-01-01,,,,,,,, +07,SIN,Navolato,2022-01-01,,,,,,,, +07,SLP,Charcas,2022-01-01,,,,,,,, +07,SON,Hermosillo,2022-01-01,,,,,,,, +07,TAB,Macuspana,2022-01-01,,,,,,,, +07,TAM,Reynosa,2022-01-01,,,,,,,, +07,VER,Córdoba,2022-01-01,,,,,,,, +07,ZAC,Ojocaliente,2022-01-01,,,,,,,, +08,AGU,Tepezalá,2022-01-01,,,,,,,, +08,BCS,Heroica Mulegé,2022-01-01,,,,,,,, +08,CAM,Champotón,2022-01-01,,,,,,,, +08,COA,Saltillo,2022-01-01,,,,,,,, +08,CHP,Las Margaritas,2022-01-01,,,,,,,, +08,CMX,Ciudad de México,2022-01-01,,,,,,,, +08,DUR,Francisco I. Madero,2022-01-01,,,,,,,, +08,GUA,Moroleón,2022-01-01,,,,,,,, +08,HID,Huejutla de Reyes,2022-01-01,,,,,,,, +08,JAL,Tepatitlán de Morelos,2022-01-01,,,,,,,, +08,MEX,Metepec,2022-01-01,,,,,,,, +08,MIC,Sahuayo de Morelos,2022-01-01,,,,,,,, +08,MOR,Tlaquiltenango,2022-01-01,,,,,,,, +08,NAY,Villa Hidalgo (El Nuevo),2022-01-01,,,,,,,, +08,NLE,Ciudad Sabinas Hidalgo,2022-01-01,,,,,,,, +08,OAX,Puerto Escondido,2022-01-01,,,,,,,, +08,PUE,San Pedro Cholula,2022-01-01,,,,,,,, +08,ROO,Bacalar,2022-01-01,,,,,,,, +08,SIN,Quila,2022-01-01,,,,,,,, +08,SLP,Salinas de Hidalgo,2022-01-01,,,,,,,, +08,SON,Huatabampo,2022-01-01,,,,,,,, +08,TAB,Tenosique de Pino Suárez,2022-01-01,,,,,,,, +08,TAM,Ciudad Río Bravo,2022-01-01,,,,,,,, +08,VER,Tres Valles,2022-01-01,,,,,,,, +08,ZAC,Villa Hidalgo,2022-01-01,,,,,,,, +09,AGU,Cosío,2022-01-01,,,,,,,, +09,BCS,Villa Alberto Andrés Alvarado Arámburo,2022-01-01,,,,,,,, +09,CAM,Hecelchakán,2022-01-01,,,,,,,, +09,COA,Nueva Rosita,2022-01-01,,,,,,,, +09,CHH,Madera,2022-01-01,,,,,,,, +09,CHP,Arriaga,2022-01-01,,,,,,,, +09,CMX,Ciudad de México,2022-01-01,,,,,,,, +09,DUR,Nombre de Dios,2022-01-01,,,,,,,, +09,GRO,San Jerónimo de Juárez,2022-01-01,,,,,,,, +09,GUA,Salamanca,2022-01-01,,,,,,,, +09,HID,Tlaxcoapan,2022-01-01,,,,,,,, +09,JAL,Tlaquepaque,2022-01-01,,,,,,,, +09,MEX,Naucalpan de Juárez,2022-01-01,,,,,,,, +09,MIC,Uruapan,2022-01-01,,,,,,,, +09,NAY,Ruiz,2022-01-01,,,,,,,, +09,NLE,San Nicolás de los Garza,2022-01-01,,,,,,,, +09,OAX,Río Grande o Piedra Parada,2022-01-01,,,,,,,, +09,PUE,Huauchinango,2022-01-01,,,,,,,, +09,SIN,Ahome,2022-01-01,,,,,,,, +09,SLP,Cárdenas,2022-01-01,,,,,,,, +09,SON,Navojoa,2022-01-01,,,,,,,, +09,TAB,Teapa,2022-01-01,,,,,,,, +09,TAM,San Fernando,2022-01-01,,,,,,,, +09,VER,Jáltipan de Morelos,2022-01-01,,,,,,,, +09,ZAC,Villanueva,2022-01-01,,,,,,,, +10,BCS,San Ignacio,2022-01-01,,,,,,,, +10,COA,San Pedro,2022-01-01,,,,,,,, +10,CHH,Colonia Anáhuac,2022-01-01,,,,,,,, +10,CHP,Palenque,2022-01-01,,,,,,,, +10,CMX,Ciudad de México,2022-01-01,,,,,,,, +10,DUR,Vicente Guerrero,2022-01-01,,,,,,,, +10,GRO,Ciudad Apaxtla de Castrejón,2022-01-01,,,,,,,, +10,GUA,San Francisco del Rincón,2022-01-01,,,,,,,, +10,HID,Tizayuca,2022-01-01,,,,,,,, +10,JAL,Zapopan,2022-01-01,,,,,,,, +10,MEX,Ciudad Nezahualcoyotl,2022-01-01,,,,,,,, +10,MIC,Zacapu,2022-01-01,,,,,,,, +10,NAY,San Blas,2022-01-01,,,,,,,, +10,NLE,Ciudad Santa Catarina,2022-01-01,,,,,,,, +10,PUE,Acatlán de Osorio,2022-01-01,,,,,,,, +10,SIN,Higuera de Zaragoza,2022-01-01,,,,,,,, +10,SLP,Cerritos,2022-01-01,,,,,,,, +10,SON,Heroica Nogales,2022-01-01,,,,,,,, +10,TAB,Paraíso,2022-01-01,,,,,,,, +10,TAM,Tampico,2022-01-01,,,,,,,, +10,VER,Xalapa-Enríquez,2022-01-01,,,,,,,, +10,ZAC,Villa de Cos,2022-01-01,,,,,,,, +11,BCS,Guerrero Negro,2022-01-01,,,,,,,, +11,CAM,Pomuch,2022-01-01,,,,,,,, +11,COA,Torreón,2022-01-01,,,,,,,, +11,CHH,Juan Aldama,2022-01-01,,,,,,,, +11,CHP,Ocosingo,2022-01-01,,,,,,,, +11,CMX,Ciudad de México,2022-01-01,,,,,,,, +11,DUR,El Salto,2022-01-01,,,,,,,, +11,GRO,Ciudad Altamirano,2022-01-01,,,,,,,, +11,GUA,Silao,2022-01-01,,,,,,,, +11,HID,Santiago Tulantepec,2022-01-01,,,,,,,, +11,JAL,Tlajomulco de Zúñiga,2022-01-01,,,,,,,, +11,MEX,Villa Nicolás Romero,2022-01-01,,,,,,,, +11,MIC,Zamora de Hidalgo,2022-01-01,,,,,,,, +11,NAY,Ixtlán del Río,2022-01-01,,,,,,,, +11,NLE,Doctor Arroyo,2022-01-01,,,,,,,, +11,OAX,Santiago Suchilquitongo,2022-01-01,,,,,,,, +11,PUE,Cuautlancingo,2022-01-01,,,,,,,, +11,SIN,Choix,2022-01-01,,,,,,,, +11,SLP,Tamuín,2022-01-01,,,,,,,, +11,SON,Puerto Peñasco,2022-01-01,,,,,,,, +11,TAB,Frontera,2022-01-01,,,,,,,, +11,TAM,Ciudad Victoria,2022-01-01,,,,,,,, +11,VER,Minatitlán,2022-01-01,,,,,,,, +11,ZAC,Nochistlán de Mejía,2022-01-01,,,,,,,, +12,BCS,Santa Rosalía,2022-01-01,,,,,,,, +12,COA,Castaños,2022-01-01,,,,,,,, +12,CHH,José Mariano Jiménez,2022-01-01,,,,,,,, +12,CHP,Tonalá,2022-01-01,,,,,,,, +12,CMX,Ciudad de México,2022-01-01,,,,,,,, +12,DUR,Santa María del Oro,2022-01-01,,,,,,,, +12,GRO,Buenavista de Cuellar,2022-01-01,,,,,,,, +12,GUA,Jerécuaro,2022-01-01,,,,,,,, +12,HID,Ixmiquilpan,2022-01-01,,,,,,,, +12,JAL,Tonalá,2022-01-01,,,,,,,, +12,MEX,Tecamac de Felipe Villanueva,2022-01-01,,,,,,,, +12,MIC,Heroica Zitácuaro,2022-01-01,,,,,,,, +12,NAY,Bucerías,2022-01-01,,,,,,,, +12,NLE,Ciénega de Flores,2022-01-01,,,,,,,, +12,OAX,San Felipe Jalapa de Díaz,2022-01-01,,,,,,,, +12,PUE,Tepeaca,2022-01-01,,,,,,,, +12,SIN,Villa Unión,2022-01-01,,,,,,,, +12,SLP,Tamasopo,2022-01-01,,,,,,,, +12,SON,Heroica Ciudad de Cananea,2022-01-01,,,,,,,, +12,TAB,Cunduacán,2022-01-01,,,,,,,, +12,TAM,González,2022-01-01,,,,,,,, +12,VER,Orizaba,2022-01-01,,,,,,,, +12,ZAC,Víctor Rosales,2022-01-01,,,,,,,, +13,COA,Francisco I. Madero (Chávez),2022-01-01,,,,,,,, +13,CHH,Manuel Ojinaga,2022-01-01,,,,,,,, +13,CHP,Mapastepec,2022-01-01,,,,,,,, +13,CMX,Ciudad de México,2022-01-01,,,,,,,, +13,GRO,Cutzamala de Pinzón,2022-01-01,,,,,,,, +13,GUA,Santiago Maravatío,2022-01-01,,,,,,,, +13,HID,Tepeji del Rio,2022-01-01,,,,,,,, +13,JAL,Tuxpan,2022-01-01,,,,,,,, +13,MEX,Tepotzotlán,2022-01-01,,,,,,,, +13,MIC,Paracho de Verduzco,2022-01-01,,,,,,,, +13,NAY,Las Varas,2022-01-01,,,,,,,, +13,NLE,Hualahuises,2022-01-01,,,,,,,, +13,OAX,Bahias de Huatulco,2022-01-01,,,,,,,, +13,PUE,Tecamachalco,2022-01-01,,,,,,,, +13,SIN,Sinaloa de Leyva,2022-01-01,,,,,,,, +13,SLP,Ciudad del Maíz,2022-01-01,,,,,,,, +13,SON,Sonoita,2022-01-01,,,,,,,, +13,TAB,Huimanguillo,2022-01-01,,,,,,,, +13,TAM,Jaumave,2022-01-01,,,,,,,, +13,VER,Papantla de Olarte,2022-01-01,,,,,,,, +13,ZAC,Valparaíso,2022-01-01,,,,,,,, +14,COA,Cuatro Ciénegas de Carranza,2022-01-01,,,,,,,, +14,CHH,Bachíniva,2022-01-01,,,,,,,, +14,CHP,Las Rosas,2022-01-01,,,,,,,, +14,CMX,Ciudad de México,2022-01-01,,,,,,,, +14,GRO,Coyuca de Catalán,2022-01-01,,,,,,,, +14,GUA,Romita,2022-01-01,,,,,,,, +14,HID,Cruz Azul,2022-01-01,,,,,,,, +14,JAL,Tototlán,2022-01-01,,,,,,,, +14,MEX,Tlalnepantla de Baz,2022-01-01,,,,,,,, +14,MIC,Tangancícuaro de Arista,2022-01-01,,,,,,,, +14,NAY,Xalisco,2022-01-01,,,,,,,, +14,OAX,Putla Villa de Guerrero,2022-01-01,,,,,,,, +14,PUE,Zacatlán,2022-01-01,,,,,,,, +14,SIN,Mocorito,2022-01-01,,,,,,,, +14,SLP,Cedral,2022-01-01,,,,,,,, +14,SON,Magdalena de Kino,2022-01-01,,,,,,,, +14,TAM,Ciudad Gustavo Díaz Ordaz,2022-01-01,,,,,,,, +14,VER,Poza Rica de Hidalgo,2022-01-01,,,,,,,, +14,ZAC,Luis Moya,2022-01-01,,,,,,,, +15,COA,Nadadores,2022-01-01,,,,,,,, +15,CHH,Saucillo,2022-01-01,,,,,,,, +15,CHP,Chiapa de Corzo,2022-01-01,,,,,,,, +15,CMX,Ciudad de México,2022-01-01,,,,,,,, +15,GRO,Tierra Colorada,2022-01-01,,,,,,,, +15,GUA,Tarandacuao,2022-01-01,,,,,,,, +15,HID,Tepeapulco,2022-01-01,,,,,,,, +15,JAL,San Diego de Alejandría,2022-01-01,,,,,,,, +15,MEX,Santa Maria Tultepec,2022-01-01,,,,,,,, +15,MIC,Maravatío de Ocampo,2022-01-01,,,,,,,, +15,NAY,San pedro Lagunillas,2022-01-01,,,,,,,, +15,NLE,Cadereyta Jiménez,2022-01-01,,,,,,,, +15,OAX,Cosolapa,2022-01-01,,,,,,,, +15,PUE,Xicotepec,2022-01-01,,,,,,,, +15,SIN,Angostura,2022-01-01,,,,,,,, +15,SLP,Tierra Nueva,2022-01-01,,,,,,,, +15,TAM,Estación Manuel (Úrsulo Galván),2022-01-01,,,,,,,, +15,VER,San Andrés Tuxtla,2022-01-01,,,,,,,, +15,ZAC,Moyahua de Estrada,2022-01-01,,,,,,,, +16,COA,Ramos Arizpe,2022-01-01,,,,,,,, +16,CHP,Cacahoatán,2022-01-01,,,,,,,, +16,CMX,Ciudad de México,2022-01-01,,,,,,,, +16,GRO,Coyuca de Benítez,2022-01-01,,,,,,,, +16,GUA,Huanímaro,2022-01-01,,,,,,,, +16,JAL,La Resolana,2022-01-01,,,,,,,, +16,MEX,Tultitlán de Mariano Escobedo,2022-01-01,,,,,,,, +16,MIC,Zinapécuaro de Figueroa,2022-01-01,,,,,,,, +16,NAY,La peñita de Jaltemba,2022-01-01,,,,,,,, +16,OAX,Tlacolula de Matamoros,2022-01-01,,,,,,,, +16,PUE,Ciudad Serdán,2022-01-01,,,,,,,, +16,SIN,San Blas,2022-01-01,,,,,,,, +16,SLP,Villa de Reyes,2022-01-01,,,,,,,, +16,TAM,Xicoténcatl,2022-01-01,,,,,,,, +16,VER,Túxpam de Rodríguez Cano,2022-01-01,,,,,,,, +16,ZAC,Sombrerete,2022-01-01,,,,,,,, +17,COA,Nava,2022-01-01,,,,,,,, +17,CHP,Ocozocoautla de Espinosa,2022-01-01,,,,,,,, +17,GRO,Olinalá,2022-01-01,,,,,,,, +17,GUA,Comonfort,2022-01-01,,,,,,,, +17,JAL,Atotonilco el Alto,2022-01-01,,,,,,,, +17,MEX,Cuautitlán,2022-01-01,,,,,,,, +17,MIC,Puruándiro,2022-01-01,,,,,,,, +17,NAY,Jala,2022-01-01,,,,,,,, +17,NLE,Santiago,2022-01-01,,,,,,,, +17,OAX,San Pablo Villa de Mitla,2022-01-01,,,,,,,, +17,PUE,Amozoc,2022-01-01,,,,,,,, +17,SIN,La Cruz,2022-01-01,,,,,,,, +17,SLP,Fracción el Refugio,2022-01-01,,,,,,,, +17,TAM,Ciudad Miguel Alemán,2022-01-01,,,,,,,, +17,VER,Veracruz,2022-01-01,,,,,,,, +17,ZAC,Jalpa,2022-01-01,,,,,,,, +18,COA,Zaragoza,2022-01-01,,,,,,,, +18,CHP,Cintalapa de Figueroa,2022-01-01,,,,,,,, +18,GRO,Marquelia,2022-01-01,,,,,,,, +18,GUA,Uriangato,2022-01-01,,,,,,,, +18,JAL,Jalostotitlán,2022-01-01,,,,,,,, +18,MEX,Ixtapaluca,2022-01-01,,,,,,,, +18,MIC,Yurécuaro,2022-01-01,,,,,,,, +18,NAY,Ahuacatlán,2022-01-01,,,,,,,, +18,NLE,El cercado,2022-01-01,,,,,,,, +18,OAX,Natividad,2022-01-01,,,,,,,, +18,SIN,El rosario,2022-01-01,,,,,,,, +18,SLP,Tamazunchale,2022-01-01,,,,,,,, +18,TAM,Soto la Marina,2022-01-01,,,,,,,, +18,VER,Tierra Blanca,2022-01-01,,,,,,,, +18,ZAC,Loreto,2022-01-01,,,,,,,, +19,COA,San Buenaventura,2022-01-01,,,,,,,, +19,CHP,Pichucalco,2022-01-01,,,,,,,, +19,GRO,Zumpango del Río,2022-01-01,,,,,,,, +19,GUA,Pénjamo,2022-01-01,,,,,,,, +19,JAL,Poncitlán,2022-01-01,,,,,,,, +19,MEX,Texcoco de Mora,2022-01-01,,,,,,,, +19,MIC,Huetamo de Núñez,2022-01-01,,,,,,,, +19,OAX,Teotitlán de Flores Magón,2022-01-01,,,,,,,, +19,SIN,Estación Naranjo,2022-01-01,,,,,,,, +19,SLP,Santa María del Río,2022-01-01,,,,,,,, +19,TAM,Ciudad Tula,2022-01-01,,,,,,,, +19,VER,Cosamaloapan,2022-01-01,,,,,,,, +19,ZAC,Juan Aldama,2022-01-01,,,,,,,, +20,COA,Ciudad Melchor Múzquiz,2022-01-01,,,,,,,, +20,CHP,Puerto Madero (San Benito),2022-01-01,,,,,,,, +20,GRO,San Luis de la Loma,2022-01-01,,,,,,,, +20,GUA,Cuerámaro,2022-01-01,,,,,,,, +20,JAL,Arandas,2022-01-01,,,,,,,, +20,MEX,Toluca de Lerdo,2022-01-01,,,,,,,, +20,MIC,Tacámbaro de Codallos,2022-01-01,,,,,,,, +20,NLE,Anáhuac,2022-01-01,,,,,,,, +20,OAX,Santa María Huatulco,2022-01-01,,,,,,,, +20,SIN,Aguaruto,2022-01-01,,,,,,,, +20,SLP,El Naranjo,2022-01-01,,,,,,,, +20,TAM,Nueva Ciudad Guerrero,2022-01-01,,,,,,,, +20,VER,Carlos A. Carrillo,2022-01-01,,,,,,,, +21,COA,Viesca,2022-01-01,,,,,,,, +21,CHP,Pijijiapan,2022-01-01,,,,,,,, +21,GRO,Petatlán,2022-01-01,,,,,,,, +21,GUA,Empalme Escobedo (Escobedo),2022-01-01,,,,,,,, +21,JAL,Talpa de Allende,2022-01-01,,,,,,,, +21,MEX,Valle de Chalco Solidaridad,2022-01-01,,,,,,,, +21,MIC,Ciudad Lázaro Cárdenas,2022-01-01,,,,,,,, +21,NLE,García,2022-01-01,,,,,,,, +21,OAX,San Juan Bautista Cuicatlán,2022-01-01,,,,,,,, +21,SIN,Cosalá,2022-01-01,,,,,,,, +21,TAM,Valle Hermoso,2022-01-01,,,,,,,, +21,VER,Pánuco,2022-01-01,,,,,,,, +22,COA,Morelos,2022-01-01,,,,,,,, +22,CHP,Reforma,2022-01-01,,,,,,,, +22,GRO,La Unión,2022-01-01,,,,,,,, +22,GUA,San Luis de la Paz,2022-01-01,,,,,,,, +22,JAL,Etzatlán,2022-01-01,,,,,,,, +22,MEX,Tejupilco de Hidalgo,2022-01-01,,,,,,,, +22,MIC,Las Guacamayas,2022-01-01,,,,,,,, +22,NLE,Ciudad Benito Juárez,2022-01-01,,,,,,,, +22,OAX,Villa Sola de Vega,2022-01-01,,,,,,,, +22,SIN,San Ignacio,2022-01-01,,,,,,,, +22,VER,Tampico Alto,2022-01-01,,,,,,,, +23,COA,Arteaga,2022-01-01,,,,,,,, +23,CHP,Huixtla,2022-01-01,,,,,,,, +23,GRO,San Luis San Pedro,2022-01-01,,,,,,,, +23,GUA,Valle de Santiago,2022-01-01,,,,,,,, +23,JAL,Sayula,2022-01-01,,,,,,,, +23,MEX,Chalco de Díaz Covarrubias,2022-01-01,,,,,,,, +23,MIC,Jiquilpan de Juárez,2022-01-01,,,,,,,, +23,OAX,Ocotlán de Morelos,2022-01-01,,,,,,,, +23,SIN,Topolobampo,2022-01-01,,,,,,,, +23,VER,Tempoal de Sánchez,2022-01-01,,,,,,,, +24,COA,Allende,2022-01-01,,,,,,,, +24,CHP,Motozintla de Mendoza,2022-01-01,,,,,,,, +24,GRO,Teloloapan,2022-01-01,,,,,,,, +24,GUA,Abasolo,2022-01-01,,,,,,,, +24,JAL,Ahualulco de Mercado,2022-01-01,,,,,,,, +24,MEX,Amatepec,2022-01-01,,,,,,,, +24,MIC,Tuxpan,2022-01-01,,,,,,,, +24,OAX,Villa de Zaachila,2022-01-01,,,,,,,, +24,SIN,Lic. Benito Juárez (Campo Gobierno),2022-01-01,,,,,,,, +24,VER,Tantoyuca,2022-01-01,,,,,,,, +25,CHP,Acala,2022-01-01,,,,,,,, +25,GRO,Técpan de Galeana,2022-01-01,,,,,,,, +25,GUA,Rincón de Tamayo,2022-01-01,,,,,,,, +25,JAL,Autlán de Navarro,2022-01-01,,,,,,,, +25,MIC,Cotija de la Paz,2022-01-01,,,,,,,, +25,OAX,Miahuatlán de Porfirio Díaz,2022-01-01,,,,,,,, +25,VER,Gutiérrez Zamora,2022-01-01,,,,,,,, +26,GRO,Huitzuco,2022-01-01,,,,,,,, +26,GUA,Villagrán,2022-01-01,,,,,,,, +26,JAL,Magdalena,2022-01-01,,,,,,,, +26,MEX,Melchor Ocampo,2022-01-01,,,,,,,, +26,MIC,Nueva Italia de Ruiz,2022-01-01,,,,,,,, +26,OAX,Unión Hidalgo,2022-01-01,,,,,,,, +26,VER,Platón Sánchez,2022-01-01,,,,,,,, +27,GRO,Tixtla de Guerrero,2022-01-01,,,,,,,, +27,GUA,Yuriria,2022-01-01,,,,,,,, +27,JAL,San Julián,2022-01-01,,,,,,,, +27,MEX,San Vicente Chicoloapan de Juárez,2022-01-01,,,,,,,, +27,MIC,Cuitzeo del Porvenir,2022-01-01,,,,,,,, +27,OAX,El Camarón,2022-01-01,,,,,,,, +27,VER,Juan Rodríguez Clara,2022-01-01,,,,,,,, +28,GRO,Tepecoacuilco de Trujano,2022-01-01,,,,,,,, +28,GUA,Apaseo el Grande,2022-01-01,,,,,,,, +28,JAL,Cocula,2022-01-01,,,,,,,, +28,MEX,Capulhuac,2022-01-01,,,,,,,, +28,OAX,San Pedro Mixtepec -Dto. 22-,2022-01-01,,,,,,,, +28,VER,Huatusco de Chicuellar,2022-01-01,,,,,,,, +29,GRO,San Marcos,2022-01-01,,,,,,,, +29,GUA,Purísima de Bustos,2022-01-01,,,,,,,, +29,JAL,El Grullo,2022-01-01,,,,,,,, +29,MEX,Juchitepec de Mariano Riva Palacio,2022-01-01,,,,,,,, +29,OAX,Santa Cruz Itundujia,2022-01-01,,,,,,,, +29,VER,Ixtaczoquitlán,2022-01-01,,,,,,,, +30,GRO,Azoyú,2022-01-01,,,,,,,, +30,GUA,Salvatierra,2022-01-01,,,,,,,, +30,JAL,San Miguel el Alto,2022-01-01,,,,,,,, +30,MEX,Tequixquiac,2022-01-01,,,,,,,, +30,OAX,Chahuites,2022-01-01,,,,,,,, +30,VER,Río Blanco,2022-01-01,,,,,,,, +31,GRO,Tlapehuala,2022-01-01,,,,,,,, +31,GUA,Marfil,2022-01-01,,,,,,,, +31,JAL,Tala,2022-01-01,,,,,,,, +31,MEX,Xonacatlán,2022-01-01,,,,,,,, +31,OAX,Heroica Ciudad de Ejutla de Crespo,2022-01-01,,,,,,,, +31,VER,Isla,2022-01-01,,,,,,,, +32,GRO,San Luis Acatlán,2022-01-01,,,,,,,, +32,GUA,San José Iturbide,2022-01-01,,,,,,,, +32,JAL,La Barca,2022-01-01,,,,,,,, +32,MEX,San Mateo Atenco,2022-01-01,,,,,,,, +32,OAX,San Pedro Tapanatepec,2022-01-01,,,,,,,, +32,VER,Cuitláhuac,2022-01-01,,,,,,,, +33,GRO,Chilapa de Álvarez,2022-01-01,,,,,,,, +33,GUA,Apaseo el Alto,2022-01-01,,,,,,,, +33,JAL,Jamay,2022-01-01,,,,,,,, +33,OAX,Vicente Camalote,2022-01-01,,,,,,,, +33,VER,Fortín de las Flores,2022-01-01,,,,,,,, +34,GRO,Tlapa de Comonfort,2022-01-01,,,,,,,, +34,GUA,Ciudad Manuel Doblado,2022-01-01,,,,,,,, +34,JAL,Yahualica de González Gallo,2022-01-01,,,,,,,, +34,OAX,Villa de Tamazulápam del Progreso,2022-01-01,,,,,,,, +34,VER,Alvarado,2022-01-01,,,,,,,, +35,GRO,Tlalixtaquilla,2022-01-01,,,,,,,, +35,GUA,Jaral del Progreso,2022-01-01,,,,,,,, +35,JAL,Colotlán,2022-01-01,,,,,,,, +35,OAX,San Juan Bautista lo de Soto,2022-01-01,,,,,,,, +35,VER,José Cardel,2022-01-01,,,,,,,, +36,GRO,Cuajinicuilapa,2022-01-01,,,,,,,, +36,GUA,San Diego de la Unión,2022-01-01,,,,,,,, +36,JAL,Cihuatlán,2022-01-01,,,,,,,, +36,MEX,Chiconcuac,2022-01-01,,,,,,,, +36,OAX,San Juan Cacahuatepec,2022-01-01,,,,,,,, +36,VER,Banderilla,2022-01-01,,,,,,,, +37,GRO,Huamuxtitlán,2022-01-01,,,,,,,, +37,GUA,Santa Cruz Juventino Rosas,2022-01-01,,,,,,,, +37,JAL,Zapotiltic,2022-01-01,,,,,,,, +37,OAX,San Pedro Totolapa,2022-01-01,,,,,,,, +37,VER,Paraje Nuevo,2022-01-01,,,,,,,, +38,GRO,Cruz Grande,2022-01-01,,,,,,,, +38,GUA,Doctor Mora,2022-01-01,,,,,,,, +38,JAL,Villa Corona,2022-01-01,,,,,,,, +38,OAX,San Miguel el Grande,2022-01-01,,,,,,,, +38,VER,Playa Vicente,2022-01-01,,,,,,,, +39,GRO,Ocotito,2022-01-01,,,,,,,, +39,GUA,Dolores Hgo. Cuna de la Indep. Nal.,2022-01-01,,,,,,,, +39,JAL,Teocaltiche,2022-01-01,,,,,,,, +39,MEX,Almoloya de Juárez,2022-01-01,,,,,,,, +39,OAX,Zimatlán de Álvarez,2022-01-01,,,,,,,, +39,VER,Altotonga,2022-01-01,,,,,,,, +40,GRO,Copala,2022-01-01,,,,,,,, +40,MEX,Ocoyoacac,2022-01-01,,,,,,,, +40,OAX,San Pablo Huitzo,2022-01-01,,,,,,,, +40,VER,Juan Díaz Covarrubias,2022-01-01,,,,,,,, +41,GRO,Zihuatanejo,2022-01-01,,,,,,,, +41,JAL,Tequila,2022-01-01,,,,,,,, +41,MEX,Zumpango,2022-01-01,,,,,,,, +41,OAX,San Francisco Telixtlahuaca,2022-01-01,,,,,,,, +41,VER,Cuichapa,2022-01-01,,,,,,,, +42,JAL,El Quince (San José el Quince),2022-01-01,,,,,,,, +42,OAX,Mariscala de Juárez,2022-01-01,,,,,,,, +42,VER,Santiago Tuxtla,2022-01-01,,,,,,,, +43,JAL,San José el Verde (El Verde),2022-01-01,,,,,,,, +43,OAX,Santiago Pinotepa Nacional,2022-01-01,,,,,,,, +43,VER,Huayacocotla,2022-01-01,,,,,,,, +44,JAL,Jocotepec,2022-01-01,,,,,,,, +44,OAX,Santiago Jamiltepec,2022-01-01,,,,,,,, +44,VER,Paso de Ovejas,2022-01-01,,,,,,,, +45,JAL,Tecalitlán,2022-01-01,,,,,,,, +45,OAX,San Pedro Pochutla,2022-01-01,,,,,,,, +45,VER,Catemaco,2022-01-01,,,,,,,, +46,JAL,Chapala,2022-01-01,,,,,,,, +46,OAX,Heroica Ciudad de Tlaxiaco,2022-01-01,,,,,,,, +46,VER,Nogales,2022-01-01,,,,,,,, +47,JAL,Ajijic,2022-01-01,,,,,,,, +47,OAX,San Juan Bautista Valle Nacional,2022-01-01,,,,,,,, +47,VER,Las Choapas,2022-01-01,,,,,,,, +48,JAL,San Ignacio Cerro Gordo,2022-01-01,,,,,,,, +48,OAX,Lagunas,2022-01-01,,,,,,,, +48,VER,General Miguel Alemán (Potrero Nuevo),2022-01-01,,,,,,,, +49,JAL,Zacoalco de Torres,2022-01-01,,,,,,,, +49,OAX,Ciudad Ixtepec,2022-01-01,,,,,,,, +49,VER,Coatzintla,2022-01-01,,,,,,,, +50,JAL,Huejuquilla el Alto,2022-01-01,,,,,,,, +50,OAX,Santiago Juxtlahuaca,2022-01-01,,,,,,,, +50,VER,Ángel R. Cabada,2022-01-01,,,,,,,, +51,JAL,Villa Hidalgo,2022-01-01,,,,,,,, +51,OAX,San Sebastián Tecomaxtlahuaca,2022-01-01,,,,,,,, +51,VER,San Rafael,2022-01-01,,,,,,,, +52,JAL,Unión de San Antonio,2022-01-01,,,,,,,, +52,OAX,Asunción Nochixtlán,2022-01-01,,,,,,,, +52,VER,Tlacojalpan,2022-01-01,,,,,,,, +53,JAL,Las Pintitas,2022-01-01,,,,,,,, +53,OAX,San Francisco Ixhuatán,2022-01-01,,,,,,,, +53,VER,Cosoleacaque,2022-01-01,,,,,,,, +54,JAL,Tamazula de Gordiano,2022-01-01,,,,,,,, +54,OAX,San Blas Atempa,2022-01-01,,,,,,,, +54,VER,Lerdo de Tejada,2022-01-01,,,,,,,, +55,JAL,Acatlán de Juárez,2022-01-01,,,,,,,, +55,OAX,Santo Domingo Tehuantepec,2022-01-01,,,,,,,, +55,VER,Tihuatlán,2022-01-01,,,,,,,, +56,JAL,Valle de Guadalupe,2022-01-01,,,,,,,, +56,OAX,Cuilápam de Guerrero,2022-01-01,,,,,,,, +56,VER,Atoyac,2022-01-01,,,,,,,, +57,OAX,El Rosario,2022-01-01,,,,,,,, +57,VER,Huiloapan de Cuauhtémoc,2022-01-01,,,,,,,, +58,OAX,Santa Lucia del Camino,2022-01-01,,,,,,,, +58,VER,Cazones de Herrera,2022-01-01,,,,,,,, +59,OAX,San Antonio de la Cal,2022-01-01,,,,,,,, +59,VER,Yecuatla,2022-01-01,,,,,,,, +60,VER,Soledad de Doblado,2022-01-01,,,,,,,, +61,VER,Cerro Azul,2022-01-01,,,,,,,, +62,VER,Tezonapa,2022-01-01,,,,,,,, +66,VER,Sihuapan,2022-01-01,,,,,,,, +67,VER,El Higo,2022-01-01,,,,,,,, +68,VER,Paso del Macho,2022-01-01,,,,,,,, +69,VER,Tlapacoyan,2022-01-01,,,,,,,, diff --git a/tests/_files/cfdi40/C_Municipio.csv b/tests/_files/cfdi40/C_Municipio.csv new file mode 100644 index 0000000..687c6e4 --- /dev/null +++ b/tests/_files/cfdi40/C_Municipio.csv @@ -0,0 +1,223 @@ +Catálogo de municipios.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_Municipio,c_Estado,Descripción,Fecha de inicio de vigencia,Fecha de fin de vigencia,,,,,,, +001,AGU,Aguascalientes,2022-01-01,,,,,,,, +001,BCN,Ensenada,2022-01-01,,,,,,,, +001,BCS,Comondú,2022-01-01,,,,,,,, +001,CAM,Calkiní,2022-01-01,,,,,,,, +001,COA,Abasolo,2022-01-01,,,,,,,, +001,COL,Armería,2022-01-01,,,,,,,, +001,CHH,Ahumada,2022-01-01,,,,,,,, +001,CHP,Acacoyagua,2022-01-01,,,,,,,, +001,DUR,Canatlán,2022-01-01,,,,,,,, +001,GRO,Acapulco de Juárez,2022-01-01,,,,,,,, +001,GUA,Abasolo,2022-01-01,,,,,,,, +001,HID,Acatlán,2022-01-01,,,,,,,, +001,JAL,Acatic,2022-01-01,,,,,,,, +001,MEX,Acambay de Ruíz Castañeda,2022-01-01,,,,,,,, +001,MIC,Acuitzio,2022-01-01,,,,,,,, +001,MOR,Amacuzac,2022-01-01,,,,,,,, +001,NAY,Acaponeta,2022-01-01,,,,,,,, +001,NLE,Abasolo,2022-01-01,,,,,,,, +001,OAX,Abejones,2022-01-01,,,,,,,, +001,PUE,Acajete,2022-01-01,,,,,,,, +001,QUE,Amealco de Bonfil,2022-01-01,,,,,,,, +001,ROO,Cozumel,2022-01-01,,,,,,,, +001,SIN,Ahome,2022-01-01,,,,,,,, +001,SLP,Ahualulco,2022-01-01,,,,,,,, +001,SON,Aconchi,2022-01-01,,,,,,,, +001,TAB,Balancán,2022-01-01,,,,,,,, +001,TAM,Abasolo,2022-01-01,,,,,,,, +001,TLA,Amaxac de Guerrero,2022-01-01,,,,,,,, +001,VER,Acajete,2022-01-01,,,,,,,, +001,YUC,Abalá,2022-01-01,,,,,,,, +001,ZAC,Apozol,2022-01-01,,,,,,,, +002,AGU,Asientos,2022-01-01,,,,,,,, +002,BCN,Mexicali,2022-01-01,,,,,,,, +002,BCS,Mulegé,2022-01-01,,,,,,,, +002,CAM,Campeche,2022-01-01,,,,,,,, +002,COA,Acuña,2022-01-01,,,,,,,, +002,COL,Colima,2022-01-01,,,,,,,, +002,CHH,Aldama,2022-01-01,,,,,,,, +002,CHP,Acala,2022-01-01,,,,,,,, +002,CMX,Azcapotzalco,2022-01-01,,,,,,,, +002,DUR,Canelas,2022-01-01,,,,,,,, +002,GRO,Ahuacuotzingo,2022-01-01,,,,,,,, +002,GUA,Acámbaro,2022-01-01,,,,,,,, +002,HID,Acaxochitlán,2022-01-01,,,,,,,, +002,JAL,Acatlán de Juárez,2022-01-01,,,,,,,, +002,MEX,Acolman,2022-01-01,,,,,,,, +002,MIC,Aguililla,2022-01-01,,,,,,,, +002,MOR,Atlatlahucan,2022-01-01,,,,,,,, +002,NAY,Ahuacatlán,2022-01-01,,,,,,,, +002,NLE,Agualeguas,2022-01-01,,,,,,,, +002,OAX,Acatlán de Pérez Figueroa,2022-01-01,,,,,,,, +002,PUE,Acateno,2022-01-01,,,,,,,, +002,QUE,Pinal de Amoles,2022-01-01,,,,,,,, +002,ROO,Felipe Carrillo Puerto,2022-01-01,,,,,,,, +002,SIN,Angostura,2022-01-01,,,,,,,, +002,SLP,Alaquines,2022-01-01,,,,,,,, +002,SON,Agua Prieta,2022-01-01,,,,,,,, +002,TAB,Cárdenas,2022-01-01,,,,,,,, +002,TAM,Aldama,2022-01-01,,,,,,,, +002,TLA,Apetatitlán de Antonio Carvajal,2022-01-01,,,,,,,, +002,VER,Acatlán,2022-01-01,,,,,,,, +002,YUC,Acanceh,2022-01-01,,,,,,,, +002,ZAC,Apulco,2022-01-01,,,,,,,, +003,AGU,Calvillo,2022-01-01,,,,,,,, +003,BCN,Tecate,2022-01-01,,,,,,,, +003,BCS,La Paz,2022-01-01,,,,,,,, +003,CAM,Carmen,2022-01-01,,,,,,,, +003,COA,Allende,2022-01-01,,,,,,,, +003,COL,Comala,2022-01-01,,,,,,,, +003,CHH,Allende,2022-01-01,,,,,,,, +003,CHP,Acapetahua,2022-01-01,,,,,,,, +003,CMX,Coyoacán,2022-01-01,,,,,,,, +003,DUR,Coneto de Comonfort,2022-01-01,,,,,,,, +003,GRO,Ajuchitlán del Progreso,2022-01-01,,,,,,,, +003,GUA,San Miguel de Allende,2022-01-01,,,,,,,, +003,HID,Actopan,2022-01-01,,,,,,,, +003,JAL,Ahualulco de Mercado,2022-01-01,,,,,,,, +003,MEX,Aculco,2022-01-01,,,,,,,, +003,MIC,Álvaro Obregón,2022-01-01,,,,,,,, +003,MOR,Axochiapan,2022-01-01,,,,,,,, +003,NAY,Amatlán de Cañas,2022-01-01,,,,,,,, +003,NLE,Los Aldamas,2022-01-01,,,,,,,, +003,OAX,Asunción Cacalotepec,2022-01-01,,,,,,,, +003,PUE,Acatlán,2022-01-01,,,,,,,, +003,QUE,Arroyo Seco,2022-01-01,,,,,,,, +003,ROO,Isla Mujeres,2022-01-01,,,,,,,, +003,SIN,Badiraguato,2022-01-01,,,,,,,, +003,SLP,Aquismón,2022-01-01,,,,,,,, +003,SON,Alamos,2022-01-01,,,,,,,, +003,TAB,Centla,2022-01-01,,,,,,,, +003,TAM,Altamira,2022-01-01,,,,,,,, +003,TLA,Atlangatepec,2022-01-01,,,,,,,, +003,VER,Acayucan,2022-01-01,,,,,,,, +003,YUC,Akil,2022-01-01,,,,,,,, +003,ZAC,Atolinga,2022-01-01,,,,,,,, +004,AGU,Cosío,2022-01-01,,,,,,,, +004,BCN,Tijuana,2022-01-01,,,,,,,, +004,CAM,Champotón,2022-01-01,,,,,,,, +004,COA,Arteaga,2022-01-01,,,,,,,, +004,COL,Coquimatlán,2022-01-01,,,,,,,, +004,CHH,Aquiles Serdán,2022-01-01,,,,,,,, +004,CHP,Altamirano,2022-01-01,,,,,,,, +004,CMX,Cuajimalpa de Morelos,2022-01-01,,,,,,,, +004,DUR,Cuencamé,2022-01-01,,,,,,,, +004,GRO,Alcozauca de Guerrero,2022-01-01,,,,,,,, +457,OAX,Santiago Camotlán,2022-01-01,,,,,,,, +458,OAX,Santiago Comaltepec,2022-01-01,,,,,,,, +459,OAX,Santiago Chazumba,2022-01-01,,,,,,,, +460,OAX,Santiago Choápam,2022-01-01,,,,,,,, +461,OAX,Santiago del Río,2022-01-01,,,,,,,, +462,OAX,Santiago Huajolotitlán,2022-01-01,,,,,,,, +463,OAX,Santiago Huauclilla,2022-01-01,,,,,,,, +464,OAX,Santiago Ihuitlán Plumas,2022-01-01,,,,,,,, +465,OAX,Santiago Ixcuintepec,2022-01-01,,,,,,,, +466,OAX,Santiago Ixtayutla,2022-01-01,,,,,,,, +467,OAX,Santiago Jamiltepec,2022-01-01,,,,,,,, +468,OAX,Santiago Jocotepec,2022-01-01,,,,,,,, +469,OAX,Santiago Juxtlahuaca,2022-01-01,,,,,,,, +470,OAX,Santiago Lachiguiri,2022-01-01,,,,,,,, +471,OAX,Santiago Lalopa,2022-01-01,,,,,,,, +472,OAX,Santiago Laollaga,2022-01-01,,,,,,,, +473,OAX,Santiago Laxopa,2022-01-01,,,,,,,, +474,OAX,Santiago Llano Grande,2022-01-01,,,,,,,, +475,OAX,Santiago Matatlán,2022-01-01,,,,,,,, +476,OAX,Santiago Miltepec,2022-01-01,,,,,,,, +477,OAX,Santiago Minas,2022-01-01,,,,,,,, +478,OAX,Santiago Nacaltepec,2022-01-01,,,,,,,, +479,OAX,Santiago Nejapilla,2022-01-01,,,,,,,, +480,OAX,Santiago Nundiche,2022-01-01,,,,,,,, +481,OAX,Santiago Nuyoó,2022-01-01,,,,,,,, +482,OAX,Santiago Pinotepa Nacional,2022-01-01,,,,,,,, +483,OAX,Santiago Suchilquitongo,2022-01-01,,,,,,,, +484,OAX,Santiago Tamazola,2022-01-01,,,,,,,, +485,OAX,Santiago Tapextla,2022-01-01,,,,,,,, +486,OAX,Villa Tejúpam de la Unión,2022-01-01,,,,,,,, +487,OAX,Santiago Tenango,2022-01-01,,,,,,,, +488,OAX,Santiago Tepetlapa,2022-01-01,,,,,,,, +489,OAX,Santiago Tetepec,2022-01-01,,,,,,,, +490,OAX,Santiago Texcalcingo,2022-01-01,,,,,,,, +491,OAX,Santiago Textitlán,2022-01-01,,,,,,,, +492,OAX,Santiago Tilantongo,2022-01-01,,,,,,,, +493,OAX,Santiago Tillo,2022-01-01,,,,,,,, +494,OAX,Santiago Tlazoyaltepec,2022-01-01,,,,,,,, +495,OAX,Santiago Xanica,2022-01-01,,,,,,,, +496,OAX,Santiago Xiacuí,2022-01-01,,,,,,,, +497,OAX,Santiago Yaitepec,2022-01-01,,,,,,,, +498,OAX,Santiago Yaveo,2022-01-01,,,,,,,, +499,OAX,Santiago Yolomécatl,2022-01-01,,,,,,,, +500,OAX,Santiago Yosondúa,2022-01-01,,,,,,,, +501,OAX,Santiago Yucuyachi,2022-01-01,,,,,,,, +502,OAX,Santiago Zacatepec,2022-01-01,,,,,,,, +503,OAX,Santiago Zoochila,2022-01-01,,,,,,,, +504,OAX,Nuevo Zoquiápam,2022-01-01,,,,,,,, +505,OAX,Santo Domingo Ingenio,2022-01-01,,,,,,,, +506,OAX,Santo Domingo Albarradas,2022-01-01,,,,,,,, +507,OAX,Santo Domingo Armenta,2022-01-01,,,,,,,, +508,OAX,Santo Domingo Chihuitán,2022-01-01,,,,,,,, +509,OAX,Santo Domingo de Morelos,2022-01-01,,,,,,,, +510,OAX,Santo Domingo Ixcatlán,2022-01-01,,,,,,,, +511,OAX,Santo Domingo Nuxaá,2022-01-01,,,,,,,, +512,OAX,Santo Domingo Ozolotepec,2022-01-01,,,,,,,, +513,OAX,Santo Domingo Petapa,2022-01-01,,,,,,,, +514,OAX,Santo Domingo Roayaga,2022-01-01,,,,,,,, +515,OAX,Santo Domingo Tehuantepec,2022-01-01,,,,,,,, +516,OAX,Santo Domingo Teojomulco,2022-01-01,,,,,,,, +517,OAX,Santo Domingo Tepuxtepec,2022-01-01,,,,,,,, +518,OAX,Santo Domingo Tlatayápam,2022-01-01,,,,,,,, +519,OAX,Santo Domingo Tomaltepec,2022-01-01,,,,,,,, +520,OAX,Santo Domingo Tonalá,2022-01-01,,,,,,,, +521,OAX,Santo Domingo Tonaltepec,2022-01-01,,,,,,,, +522,OAX,Santo Domingo Xagacía,2022-01-01,,,,,,,, +523,OAX,Santo Domingo Yanhuitlán,2022-01-01,,,,,,,, +524,OAX,Santo Domingo Yodohino,2022-01-01,,,,,,,, +525,OAX,Santo Domingo Zanatepec,2022-01-01,,,,,,,, +526,OAX,Santos Reyes Nopala,2022-01-01,,,,,,,, +527,OAX,Santos Reyes Pápalo,2022-01-01,,,,,,,, +528,OAX,Santos Reyes Tepejillo,2022-01-01,,,,,,,, +529,OAX,Santos Reyes Yucuná,2022-01-01,,,,,,,, +530,OAX,Santo Tomás Jalieza,2022-01-01,,,,,,,, +531,OAX,Santo Tomás Mazaltepec,2022-01-01,,,,,,,, +532,OAX,Santo Tomás Ocotepec,2022-01-01,,,,,,,, +533,OAX,Santo Tomás Tamazulapan,2022-01-01,,,,,,,, +534,OAX,San Vicente Coatlán,2022-01-01,,,,,,,, +535,OAX,San Vicente Lachixío,2022-01-01,,,,,,,, +536,OAX,San Vicente Nuñú,2022-01-01,,,,,,,, +537,OAX,Silacayoápam,2022-01-01,,,,,,,, +538,OAX,Sitio de Xitlapehua,2022-01-01,,,,,,,, +539,OAX,Soledad Etla,2022-01-01,,,,,,,, +540,OAX,Villa de Tamazulápam del Progreso,2022-01-01,,,,,,,, +541,OAX,Tanetze de Zaragoza,2022-01-01,,,,,,,, +542,OAX,Taniche,2022-01-01,,,,,,,, +543,OAX,Tataltepec de Valdés,2022-01-01,,,,,,,, +544,OAX,Teococuilco de Marcos Pérez,2022-01-01,,,,,,,, +545,OAX,Teotitlán de Flores Magón,2022-01-01,,,,,,,, +546,OAX,Teotitlán del Valle,2022-01-01,,,,,,,, +547,OAX,Teotongo,2022-01-01,,,,,,,, +548,OAX,Tepelmeme Villa de Morelos,2022-01-01,,,,,,,, +549,OAX,Tezoatlán de Segura y Luna,2022-01-01,,,,,,,, +550,OAX,San Jerónimo Tlacochahuaya,2022-01-01,,,,,,,, +551,OAX,Tlacolula de Matamoros,2022-01-01,,,,,,,, +552,OAX,Tlacotepec Plumas,2022-01-01,,,,,,,, +553,OAX,Tlalixtac de Cabrera,2022-01-01,,,,,,,, +554,OAX,Totontepec Villa de Morelos,2022-01-01,,,,,,,, +555,OAX,Trinidad Zaachila,2022-01-01,,,,,,,, +556,OAX,La Trinidad Vista Hermosa,2022-01-01,,,,,,,, +557,OAX,Unión Hidalgo,2022-01-01,,,,,,,, +558,OAX,Valerio Trujano,2022-01-01,,,,,,,, +559,OAX,San Juan Bautista Valle Nacional,2022-01-01,,,,,,,, +560,OAX,Villa Díaz Ordaz,2022-01-01,,,,,,,, +561,OAX,Yaxe,2022-01-01,,,,,,,, +562,OAX,Magdalena Yodocono de Porfirio Díaz,2022-01-01,,,,,,,, +563,OAX,Yogana,2022-01-01,,,,,,,, +564,OAX,Yutanduchi de Guerrero,2022-01-01,,,,,,,, +565,OAX,Villa de Zaachila,2022-01-01,,,,,,,, +566,OAX,San Mateo Yucutindoo,2022-01-01,,,,,,,, +567,OAX,Zapotitlán Lagunas,2022-01-01,,,,,,,, +568,OAX,Zapotitlán Palmas,2022-01-01,,,,,,,, +569,OAX,Santa Inés de Zaragoza,2022-01-01,,,,,,,, +570,OAX,Zimatlán de Álvarez,2022-01-01,,,,,,,, diff --git a/tests/_files/cfdi40/c_Aduana.csv b/tests/_files/cfdi40/c_Aduana.csv new file mode 100644 index 0000000..1319d35 --- /dev/null +++ b/tests/_files/cfdi40/c_Aduana.csv @@ -0,0 +1,53 @@ +"Catálogo de aduanas (tomado del anexo 22, apéndice I de la RGCE 2017).",,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_Aduana,Descripción,Fecha inicio de vigencia,Fecha fin de vigencia,,,,,,,, +1,"ACAPULCO, ACAPULCO DE JUAREZ, GUERRERO.",2022-01-01,,,,,,,,, +2,"AGUA PRIETA, AGUA PRIETA, SONORA.",2022-01-01,,,,,,,,, +5,"SUBTENIENTE LOPEZ, SUBTENIENTE LOPEZ, QUINTANA ROO.",2022-01-01,,,,,,,,, +6,"CIUDAD DEL CARMEN, CIUDAD DEL CARMEN, CAMPECHE.",2022-01-01,,,,,,,,, +7,"CIUDAD JUAREZ, CIUDAD JUAREZ, CHIHUAHUA.",2022-01-01,,,,,,,,, +8,"COATZACOALCOS, COATZACOALCOS, VERACRUZ.",2022-01-01,,,,,,,,, +11,"ENSENADA, ENSENADA, BAJA CALIFORNIA.",2022-01-01,,,,,,,,, +12,"GUAYMAS, GUAYMAS, SONORA.",2022-01-01,,,,,,,,, +14,"LA PAZ, LA PAZ, BAJA CALIFORNIA SUR.",2022-01-01,,,,,,,,, +16,"MANZANILLO, MANZANILLO, COLIMA.",2022-01-01,,,,,,,,, +17,"MATAMOROS, MATAMOROS, TAMAULIPAS.",2022-01-01,,,,,,,,, +18,"MAZATLAN, MAZATLAN, SINALOA.",2022-01-01,,,,,,,,, +19,"MEXICALI, MEXICALI, BAJA CALIFORNIA.",2022-01-01,,,,,,,,, +20,"MEXICO, DISTRITO FEDERAL.",2022-01-01,,,,,,,,, +22,"NACO, NACO, SONORA.",2022-01-01,,,,,,,,, +23,"NOGALES, NOGALES, SONORA.",2022-01-01,,,,,,,,, +24,"NUEVO LAREDO, NUEVO LAREDO, TAMAULIPAS.",2022-01-01,,,,,,,,, +25,"OJINAGA, OJINAGA, CHIHUAHUA.",2022-01-01,,,,,,,,, +26,"PUERTO PALOMAS, PUERTO PALOMAS, CHIHUAHUA.",2022-01-01,,,,,,,,, +27,"PIEDRAS NEGRAS, PIEDRAS NEGRAS, COAHUILA.",2022-01-01,,,,,,,,, +28,"PROGRESO, PROGRESO, YUCATAN.",2022-01-01,,,,,,,,, +30,"CIUDAD REYNOSA, CIUDAD REYNOSA, TAMAULIPAS.",2022-01-01,,,,,,,,, +31,"SALINA CRUZ, SALINA CRUZ, OAXACA.",2022-01-01,,,,,,,,, +33,"SAN LUIS RIO COLORADO, SAN LUIS RIO COLORADO, SONORA.",2022-01-01,,,,,,,,, +34,"CIUDAD MIGUEL ALEMAN, CIUDAD MIGUEL ALEMAN, TAMAULIPAS.",2022-01-01,,,,,,,,, +37,"CIUDAD HIDALGO, CIUDAD HIDALGO, CHIAPAS.",2022-01-01,,,,,,,,, +38,"TAMPICO, TAMPICO, TAMAULIPAS.",2022-01-01,,,,,,,,, +39,"TECATE, TECATE, BAJA CALIFORNIA.",2022-01-01,,,,,,,,, +40,"TIJUANA, TIJUANA, BAJA CALIFORNIA.",2022-01-01,,,,,,,,, +42,"TUXPAN, TUXPAN DE RODRIGUEZ CANO, VERACRUZ.",2022-01-01,,,,,,,,, +43,"VERACRUZ, VERACRUZ, VERACRUZ.",2022-01-01,,,,,,,,, +44,"CIUDAD ACUÑA, CIUDAD ACUÑA, COAHUILA.",2022-01-01,,,,,,,,, +46,"TORREON, TORREON, COAHUILA.",2022-01-01,,,,,,,,, +47,"AEROPUERTO INTERNACIONAL DE LA CIUDAD DE MEXICO,",2022-01-01,,,,,,,,, +48,"GUADALAJARA, TLACOMULCO DE ZUÑIGA, JALISCO.",2022-01-01,,,,,,,,, +50,"SONOYTA, SONOYTA, SONORA.",2022-01-01,,,,,,,,, +51,"LAZARO CARDENAS, LAZARO CARDENAS, MICHOACAN.",2022-01-01,,,,,,,,, +52,"MONTERREY, GENERAL MARIANO ESCOBEDO, NUEVO LEON.",2022-01-01,,,,,,,,, +53,"CANCUN, CANCUN, QUINTANA ROO.",2022-01-01,,,,,,,,, +64,"QUERÉTARO, EL MARQUÉS Y COLON, QUERÉTARO.",2022-01-01,,,,,,,,, +65,"TOLUCA, TOLUCA, ESTADO DE MEXICO.",2022-01-01,,,,,,,,, +67,"CHIHUAHUA, CHIHUAHUA, CHIHUAHUA.",2022-01-01,,,,,,,,, +73,"AGUASCALIENTES, AGUASCALIENTES, AGUASCALIENTES.",2022-01-01,,,,,,,,, +75,"PUEBLA, HEROICA PUEBLA DE ZARAGOZA, PUEBLA.",2022-01-01,,,,,,,,, +80,"COLOMBIA, COLOMBIA, NUEVO LEON.",2022-01-01,,,,,,,,, +81,"ALTAMIRA, ALTAMIRA, TAMAULIPAS.",2022-01-01,,,,,,,,, +82,"CIUDAD CAMARGO, CIUDAD CAMARGO, TAMAULIPAS.",2022-01-01,,,,,,,,, +83,"DOS BOCAS, PARAISO, TABASCO.",2022-01-01,,,,,,,,, +84,"GUANAJUATO, SILAO, GUANAJUATO.",2022-01-01,,,,,,,,, diff --git a/tests/_files/cfdi40/c_ClaveProdServ.csv b/tests/_files/cfdi40/c_ClaveProdServ.csv new file mode 100644 index 0000000..48f57dd --- /dev/null +++ b/tests/_files/cfdi40/c_ClaveProdServ.csv @@ -0,0 +1,223 @@ +Catálogo de Claves de Productos y Servicios.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_ClaveProdServ,Descripción,Incluir IVA trasladado,Incluir IEPS trasladado,Complemento que debe incluir,FechaInicioVigencia,FechaFinVigencia,Estímulo Franja Fronteriza,Palabras similares,,, +01010101,No existe en el catálogo,Opcional,Opcional,,2022-01-01,,0,Público en general,,, +10101500,Animales vivos de granja,Opcional,Opcional,,2022-01-01,,1,,,, +10101501,Gatos vivos,Opcional,Opcional,,2022-01-01,,1,,,, +10101502,Perros,Opcional,Opcional,,2022-01-01,,1,,,, +10101504,Visón,Opcional,Opcional,,2022-01-01,,1,,,, +10101505,Ratas,Opcional,Opcional,,2022-01-01,,1,,,, +10101506,Caballos,Opcional,Opcional,,2022-01-01,,1,"Equinos, Potrancas, Potras, Potrillos, Potros, Yeguas",,, +10101507,Ovejas,Opcional,Opcional,,2022-01-01,,1,"Borregos, Carneros",,, +10101508,Cabras,Opcional,Opcional,,2022-01-01,,1,"Borregos cimarrones, Cabritos, Cabros, Carnero de las Rocosas, Chivas, Chivatos, Chivos, Irascos, Machos cabríos, Chivos",,, +10101509,Asnos,Opcional,Opcional,,2022-01-01,,1,"Borricos, Burros",,, +10101510,Ratones,Opcional,Opcional,,2022-01-01,,1,,,, +10101511,Cerdos,Opcional,Opcional,,2022-01-01,,1,"Cerdo montés, Chanchos, Chanchos almizcleros, Chanchos de monte, Cochinillos, Cochinos, Cochinos de monte, Cuche, Cuinos, Gorrinos, Jabalíes americanos, Lechones, Cochinos de monte, Pecaríes, Porcinos, Puercos, Puercos de monte, Tayatos",,, +10101512,Conejos,Opcional,Opcional,,2022-01-01,,1,Liebres,,, +10101513,Cobayas o conejillos de indias,Opcional,Opcional,,2022-01-01,,1,"Chanchito de Indias, Cobayos, Cuilo, Cuyo",,, +10101514,Primates,Opcional,Opcional,,2022-01-01,,1,"Changos, Chimpancés, Gorilas, Lémures, Macacos, Micos, Monos, Orangutanes, Simios, Monos",,, +10101515,Armadillos,Opcional,Opcional,,2022-01-01,,1,Toches,,, +10101516,Ganado vacuno,Opcional,Opcional,,2022-01-01,,1,"Bueyes, Búfalos, Cebús, Otros vacunos o bovinos, Toros, Vacas",,, +10101517,Camellos,Opcional,Opcional,,2022-01-01,,1,Dromedarios,,, +10101600,Pájaros y aves de corral vivos,Opcional,Opcional,,2022-01-01,,1,,,, +10101601,Pollos vivos,Opcional,Opcional,,2022-01-01,,1,"Gallinas, Gallinas de guinea, Gallos, Pintadas, Pollitos",,, +10101602,Patos vivos,Opcional,Opcional,,2022-01-01,,1,,,, +10101603,Pavos vivos,Opcional,Opcional,,2022-01-01,,1,"Gallipavos, Guajolotes, Pavos salvajes",,, +10101604,Gansos vivos,Opcional,Opcional,,2022-01-01,,1,,,, +10101605,Faisanes vivos,Opcional,Opcional,,2022-01-01,,1,,,, +10101700,Peces vivos,Opcional,Opcional,,2022-01-01,,1,,,, +10101701,Salmones vivos,Opcional,Opcional,,2022-01-01,,1,,,, +10101702,Trucha viva,Opcional,Opcional,,2022-01-01,,1,,,, +10101703,Tilapia viva,Opcional,Opcional,,2022-01-01,,1,Mojarra,,, +10101704,Carpa viva,Opcional,Opcional,,2022-01-01,,1,,,, +10101705,Anguilas vivas,Opcional,Opcional,,2022-01-01,,1,,,, +10101800,Mariscos e invertebrados acuáticos vivos,Opcional,Opcional,,2022-01-01,,1,,,, +10101801,Camarón vivo,Opcional,Opcional,,2022-01-01,,1,Esquilas,,, +10101802,Almejas vivas,Opcional,Opcional,,2022-01-01,,1,,,, +10101803,Mejillones vivos,Opcional,Opcional,,2022-01-01,,1,,,, +10101804,Ostras vivas,Opcional,Opcional,,2022-01-01,,1,,,, +10101805,Cangrejos vivos,Opcional,Opcional,,2022-01-01,,1,,,, +10101806,Abulones vivos,Opcional,Opcional,,2022-01-01,,1,Orejas de mar,,, +10101807,Pulpo vivo,Opcional,Opcional,,2022-01-01,,1,Octópodo,,, +10101808,Calamar vivo,Opcional,Opcional,,2022-01-01,,1,,,, +10101809,Sanguijuelas,Opcional,Opcional,,2022-01-01,,1,"Hirudineas, Hirudos, Hirudíneo",,, +10101900,Insectos vivos,Opcional,Opcional,,2022-01-01,,1,,,, +10101901,Mariposas,Opcional,Opcional,,2022-01-01,,1,,,, +10101902,Escarabajos,Opcional,Opcional,,2022-01-01,,1,"Mariquitas, Sanjuaneros",,, +10101903,Abejas,Opcional,Opcional,,2022-01-01,,1,,,, +10101904,Gusanos de seda,Opcional,Opcional,,2022-01-01,,1,"Crisálida, Larva, Oruga",,, +10102000,Animales salvajes vivos,Opcional,Opcional,,2022-01-01,,1,,,, +10102001,Elefantes,Opcional,Opcional,,2022-01-01,,1,Paquidermos,,, +10102002,Zorros vivos,Opcional,Opcional,,2022-01-01,,1,Zorras,,, +10102100,Huevos de aves para incubar,Opcional,Opcional,,2022-01-01,,1,,,, +10111300,"Accesorios, equipo y tratamientos para los animales domésticos",Opcional,Opcional,,2022-01-01,,1,"Accesorios, equipo y medicamentos para animales domésticos",,, +10111301,Juguetes para mascotas,Opcional,Opcional,,2022-01-01,,1,,,, +10111302,Productos para el aseo y cuidado de mascotas,Opcional,Opcional,,2022-01-01,,1,,,, +10111303,Equipo para el manejo de desperdicios de las mascotas,Opcional,Opcional,,2022-01-01,,1,,,, +10111304,Tazones o equipo para alimentación de mascotas,Opcional,Opcional,,2022-01-01,,1,,,, +10111305,Tratamientos medicados para mascotas,Opcional,Opcional,,2022-01-01,,1,Tratamientos medicinales para mascotas,,, +10111306,Kits para el entrenamiento de mascotas domésticas,Opcional,Opcional,,2022-01-01,,1,,,, +10111307,Cobijas para mascotas,Opcional,Opcional,,2022-01-01,,1,"Mantas para mascotas, Sábanas para mascotas",,, +10121500,Pienso para ganado,Opcional,Opcional,,2022-01-01,,1,Alimento para ganado,,, +10121501,Salvado de trigo puro,Opcional,Opcional,,2022-01-01,,1,,,, +10121502,Avena para forraje,Opcional,Opcional,,2022-01-01,,1,,,, +10121503,Maíz para forraje,Opcional,Opcional,,2022-01-01,,1,,,, +10121504,Sorgo para forraje,Opcional,Opcional,,2022-01-01,,1,,,, +10121505,Heno,Opcional,Opcional,,2022-01-01,,1,,,, +10121506,Tortas oleaginosas,Opcional,Opcional,,2022-01-01,,1,Torta de aceite para ganado,,, +10121507,Forraje compuesto,Opcional,Opcional,,2022-01-01,,1,,,, +10121600,Alimento para pájaros y aves de corral,Opcional,Opcional,,2022-01-01,,1,,,, +10121601,Alimento vivo para aves,Opcional,Opcional,,2022-01-01,,1,,,, +10121602,Alpiste,Opcional,Opcional,,2022-01-01,,1,,,, +10121603,Botanas o comida recreacional para aves,Opcional,Opcional,,2022-01-01,,1,,,, +10121604,Alimento avícola,Opcional,Opcional,,2022-01-01,,1,,,, +10121700,Alimento para peces,Opcional,Opcional,,2022-01-01,,1,,,, +10121701,Salmuera fresca o congelada,Opcional,Opcional,,2022-01-01,,1,,,, +10121702,Alimento granulado para peces,Opcional,Opcional,,2022-01-01,,1,,,, +10121703,Alimento en hojuelas para peces,Opcional,Opcional,,2022-01-01,,1,,,, +10121800,Alimento para perros y gatos,Opcional,Opcional,,2022-01-01,,1,,,, +10121801,Comida seca para perros,Opcional,Opcional,,2022-01-01,,1,,,, +10121802,Comida húmeda para perros,Opcional,Opcional,,2022-01-01,,1,,,, +10121803,Leche para perros o gatos,Opcional,Opcional,,2022-01-01,,1,,,, +10121804,Comida seca para gatos,Opcional,Opcional,,2022-01-01,,1,,,, +10121805,Comida húmeda para gatos,Opcional,Opcional,,2022-01-01,,1,,,, +10121806,Botanas o comida recreacional para gatos o perros,Opcional,Opcional,,2022-01-01,,1,,,, +10121900,Alimento para roedores,Opcional,Opcional,,2022-01-01,,1,,,, +10121901,Comida granulada para roedores,Opcional,Opcional,,2022-01-01,,1,,,, +10122000,Alimento para reptiles,Opcional,Opcional,,2022-01-01,,1,,,, +10122001,Comida granulada para reptiles,Opcional,Opcional,,2022-01-01,,1,,,, +10122002,Comida húmeda para reptiles,Opcional,Opcional,,2022-01-01,,1,,,, +10122003,Comida viva para reptiles,Opcional,Opcional,,2022-01-01,,1,,,, +10122100,Comida para animales variados,Opcional,Opcional,,2022-01-01,,1,Comida para diversos animales,,, +10122101,Comida para cerdos,Opcional,Opcional,,2022-01-01,,1,"Comida para chanchos, Comida para cochinillos, Comida para cochinos, Comida para cuche, Comida para cuinos, Comida para gorrinos, Comida para lechones, Comida para marranos, Comida para porcinos, Comida para puercos, Comida para lechones",,, +10122102,Comida para visones,Opcional,Opcional,,2022-01-01,,1,,,, +10122103,Comida para monos,Opcional,Opcional,,2022-01-01,,1,,,, +10122104,Comida para conejos,Opcional,Opcional,,2022-01-01,,1,,,, +10131500,Cobertizos para animales,Opcional,Opcional,,2022-01-01,,1,,,, +10131506,Establos para ganado,Opcional,Opcional,,2022-01-01,,1,,,, +10131507,Casas para mascotas domesticadas,Opcional,Opcional,,2022-01-01,,1,,,, +10131508,Camas para mascotas,Opcional,Opcional,,2022-01-01,,1,,,, +10131600,Recipientes para animales,Opcional,Opcional,,2022-01-01,,1,Contenedores de comida para animales,,, +10131601,Jaulas o sus accesorios,Opcional,Opcional,,2022-01-01,,1,,,, +10131602,Perreras,Opcional,Opcional,,2022-01-01,,1,,,, +10131603,Equipaje para el transporte de animales,Opcional,Opcional,,2022-01-01,,1,,,, +10131604,Correas para perros,Opcional,Opcional,,2022-01-01,,1,,,, +10131700,Hábitat para animales,Opcional,Opcional,,2022-01-01,,1,Ambientes para animales,,, +10131701,Terrarios,Opcional,Opcional,,2022-01-01,,1,,,, +10131702,Acuarios,Opcional,Opcional,,2022-01-01,,1,,,, +10141500,Talabartería,Opcional,Opcional,,2022-01-01,,1,Guarniciones para caballerías,,, +95121646,Estructura para parqueo de bicicletas,Opcional,Opcional,,2022-01-01,,1,Estructura de estacionamiento para bicicletas,,, +95121700,Edificios y estructuras públicos,Opcional,Opcional,,2022-01-01,,0,,,, +95121701,Oficina postal,Opcional,Opcional,,2022-01-01,,0,,,, +95121702,Estación de policía,Opcional,Opcional,,2022-01-01,,0,,,, +95121703,Edificio de juzgados,Opcional,Opcional,,2022-01-01,,0,,,, +95121704,Edificio de prisión,Opcional,Opcional,,2022-01-01,,0,,,, +95121705,Estación de bomberos,Opcional,Opcional,,2022-01-01,,0,,,, +95121706,Estación de ambulancias,Opcional,Opcional,,2022-01-01,,0,,,, +95121707,Edificio de rescate de montaña,Opcional,Opcional,,2022-01-01,,0,,,, +95121708,Estación de botes salvavidas,Opcional,Opcional,,2022-01-01,,0,,,, +95121709,Edificio de guardacostas,Opcional,Opcional,,2022-01-01,,0,,,, +95121710,Estación de servicio de rescate,Opcional,Opcional,,2022-01-01,,0,,,, +95121711,Centro cívico,Opcional,Opcional,,2022-01-01,,0,,,, +95121712,Galería de arte,Opcional,Opcional,,2022-01-01,,0,,,, +95121800,Edificios y estructuras utilitarios,Opcional,Opcional,,2022-01-01,,0,,,, +95121801,Estación de radares,Opcional,Opcional,,2022-01-01,,0,,,, +95121802,Subestación,Opcional,Opcional,,2022-01-01,,0,,,, +95121804,Torre de agua,Opcional,Opcional,,2022-01-01,,0,,,, +95121805,Pozo,Opcional,Opcional,,2022-01-01,,0,,,, +95121806,Estación base para telefonía móvil,Opcional,Opcional,,2022-01-01,,0,,,, +95121808,Plataforma de gas o petróleo,Opcional,Opcional,,2022-01-01,,0,,,, +95121900,Edificios y estructuras educacionales y de administración,Opcional,Opcional,,2022-01-01,,0,,,, +95121901,Escuela politécnica,Opcional,Opcional,,2022-01-01,,0,,,, +95121902,Centro de formación tecnológica,Opcional,Opcional,,2022-01-01,,0,,,, +95121903,Aula,Opcional,Opcional,,2022-01-01,,0,,,, +95121904,Biblioteca,Opcional,Opcional,,2022-01-01,,0,,,, +95121905,Laboratorio de idiomas,Opcional,Opcional,,2022-01-01,,0,,,, +95121906,Edificio de laboratorio,Opcional,Opcional,,2022-01-01,,0,,,, +95121907,Estación meteorológica,Opcional,Opcional,,2022-01-01,,0,,,, +95121908,Instalación para investigación o prueba,Opcional,Opcional,,2022-01-01,,0,,,, +95121909,Escuela primaria,Opcional,Opcional,,2022-01-01,,0,,,, +95121910,Escuela de bachillerato clásico,Opcional,Opcional,,2022-01-01,,0,,,, +95121911,Escuela de bachillerato,Opcional,Opcional,,2022-01-01,,0,,,, +95121913,Universidad,Opcional,Opcional,,2022-01-01,,0,,,, +95122000,Edificios y estructuras hospitalarias,Opcional,Opcional,,2022-01-01,,0,,,, +95122001,Clínica,Opcional,Opcional,,2022-01-01,,0,,,, +95122002,Hogar de convalecencia,Opcional,Opcional,,2022-01-01,,0,,,, +95122003,Sala de operaciones o quirófano,Opcional,Opcional,,2022-01-01,,0,,,, +95122004,Unidad de cuidados intensivos,Opcional,Opcional,,2022-01-01,,0,,,, +95122005,Sala de detección y diagnóstico,Opcional,Opcional,,2022-01-01,,0,,,, +95122006,Sala de fluoroscopio,Opcional,Opcional,,2022-01-01,,0,,,, +95122007,Sala o laboratorio de patología,Opcional,Opcional,,2022-01-01,,0,,,, +95122008,Sala de cateterismo,Opcional,Opcional,,2022-01-01,,0,,,, +95122100,Edificios y estructuras de acomodaciones,Opcional,Opcional,,2022-01-01,,0,,,, +95122101,Casa residencial,Opcional,Opcional,,2022-01-01,,0,,,, +95122102,Apartamento o piso,Opcional,Opcional,,2022-01-01,,0,,,, +95122103,Asilo de niños,Opcional,Opcional,,2022-01-01,,0,,,, +95122104,Guardería de niños,Opcional,Opcional,,2022-01-01,,0,,,, +95122105,Hogar de ancianos,Opcional,Opcional,,2022-01-01,,0,,,, +95122106,Hostal,Opcional,Opcional,,2022-01-01,,0,,,, +95122300,Edificios y estructuras de salud y deportivas,Opcional,Opcional,,2022-01-01,,0,,,, +95122301,Estadio,Opcional,Opcional,,2022-01-01,,0,,,, +95122302,Campo deportivo,Opcional,Opcional,,2022-01-01,,0,,,, +95122303,Pista de carreras,Opcional,Opcional,,2022-01-01,,0,,,, +95122304,Polideportivo,Opcional,Opcional,,2022-01-01,,0,,,, +95122305,Spa,Opcional,Opcional,,2022-01-01,,0,,,, +95122306,Gimnasio,Opcional,Opcional,,2022-01-01,,0,,,, +95122307,Piscina,Opcional,Opcional,,2022-01-01,,0,,,, +95122308,Instalación para deportes acuáticos,Opcional,Opcional,,2022-01-01,,0,,,, +95122400,Edificios y estructuras industriales,Opcional,Opcional,,2022-01-01,,0,,,, +95122401,Taller,Opcional,Opcional,,2022-01-01,,0,,,, +95122402,Instalación para conservación en cámaras frigoríficas,Opcional,Opcional,,2022-01-01,,0,,,, +95122403,Tienda de descuentos,Opcional,Opcional,,2022-01-01,,0,,,, +95122500,Edificios y estructuras agrícolas y de cultivos y pesca,Opcional,Opcional,,2022-01-01,,0,,,, +95122501,Granero,Opcional,Opcional,,2022-01-01,,0,,,, +95122502,Establo,Opcional,Opcional,,2022-01-01,,0,,,, +95122503,Canal de riego,Opcional,Opcional,,2022-01-01,,0,,,, +95122600,Edificios y estructuras religiosas,Opcional,Opcional,,2022-01-01,,0,,,, +95122700,Edificios y estructuras de defensa,Opcional,Opcional,,2022-01-01,,0,,,, +95131500,Tarimas y graderías,Opcional,Opcional,,2022-01-01,,1,,,, +95131501,Graderías plegables,Opcional,Opcional,,2022-01-01,,1,,,, +95131502,Graderías móviles,Opcional,Opcional,,2022-01-01,,1,,,, +95131503,Graderías portátiles,Opcional,Opcional,,2022-01-01,,1,,,, +95131600,Edificios y estructuras comerciales e industriales portátiles,Opcional,Opcional,,2022-01-01,,1,,,, +95131601,Taquillas portátiles,Opcional,Opcional,,2022-01-01,,1,,,, +95131602,Cuarto de baño portátil,Opcional,Opcional,,2022-01-01,,1,"Servicios en baños portátiles, Servicios en baños públicos",,, +95131603,Oficina en el emplazamiento,Opcional,Opcional,,2022-01-01,,1,,,, +95131604,Unidad de cocina portátil,Opcional,Opcional,,2022-01-01,,1,,,, +95131605,Casa contenedor,Opcional,Opcional,,2022-01-01,,1,,,, +95131606,Cabina de ventas portátil,Opcional,Opcional,,2022-01-01,,1,,,, +95131700,Tiendas carpas y estructuras de membrana,Opcional,Opcional,,2022-01-01,,1,,,, +95131701,Estructura textil tipo armazón,Opcional,Opcional,,2022-01-01,,1,,,, +95131702,Carpa de poste o de tensión,Opcional,Opcional,,2022-01-01,,1,,,, +95141500,Edificios y estructuras prefabricados para fincas,Opcional,Opcional,,2022-01-01,,0,,,, +95141501,Silo,Opcional,Opcional,,2022-01-01,,0,Depósitos para granos,,, +95141502,Invernadero,Opcional,Opcional,,2022-01-01,,0,,,, +95141600,Edificios y estructuras prefabricados residenciales,Opcional,Opcional,,2022-01-01,,1,,,, +95141601,Casa,Opcional,Opcional,,2022-01-01,,0,,,, +95141602,Casa móvil,Opcional,Opcional,,2022-01-01,,1,,,, +95141603,Cabaña,Opcional,Opcional,,2022-01-01,,0,,,, +95141604,Garaje,Opcional,Opcional,,2022-01-01,,0,,,, +95141605,Gazebo,Opcional,Opcional,,2022-01-01,,1,"Kiosco, Pabellón",,, +95141606,Cocina para casa,Opcional,Opcional,,2022-01-01,,1,,,, +95141700,Edificios y estructuras prefabricados comerciales e industriales,Opcional,Opcional,,2022-01-01,,0,,,, +95141701,Oficina en la planta,Opcional,Opcional,,2022-01-01,,0,,,, +95141702,Cabina de pintura,Opcional,Opcional,,2022-01-01,,0,,,, +95141703,Galpón de almacenaje,Opcional,Opcional,,2022-01-01,,0,Almacén,,, +95141704,Sala blanca,Opcional,Opcional,,2022-01-01,,0,,,, +95141705,Casa de guardias,Opcional,Opcional,,2022-01-01,,0,,,, +95141706,Bodega,Opcional,Opcional,,2022-01-01,,0,,,, +95141707,Auditorio,Opcional,Opcional,,2022-01-01,,0,,,, +95141708,Cocina para oficina,Opcional,Opcional,,2022-01-01,,1,,,, +95141709,Conservatorio,Opcional,Opcional,,2022-01-01,,0,,,, +95141710,Cabina telefónica,Opcional,Opcional,,2022-01-01,,1,,,, +95141711,Cabina de peaje,Opcional,Opcional,,2022-01-01,,1,,,, +95141800,Edificios y estructuras prefabricados de emergencia y alivio,Opcional,Opcional,,2022-01-01,,0,,,, +95141801,Albergue,Opcional,Opcional,,2022-01-01,,0,,,, +95141802,Carpa o salón de emergencia,Opcional,Opcional,,2022-01-01,,1,,,, +95141803,Unidad de contenedor,Opcional,Opcional,,2022-01-01,,1,,,, +95141900,Edificios y estructuras prefabricados médicos,Opcional,Opcional,,2022-01-01,,0,,,, +95141901,Unidad médica,Opcional,Opcional,,2022-01-01,,0,,,, +95141902,Unidad de laboratorio,Opcional,Opcional,,2022-01-01,,0,,,, +95141903,Unidad odontológica,Opcional,Opcional,,2022-01-01,,0,,,, +95141904,Unidades quirúrgicas,Opcional,Opcional,,2022-01-01,,0,,,, diff --git a/tests/_files/cfdi40/c_ClaveUnidad.csv b/tests/_files/cfdi40/c_ClaveUnidad.csv new file mode 100644 index 0000000..bb67a9f --- /dev/null +++ b/tests/_files/cfdi40/c_ClaveUnidad.csv @@ -0,0 +1,79 @@ +Catálogo de unidades de medida para los conceptos en el CFDI.,,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,,, +c_ClaveUnidad,Nombre,Descripción,Nota,Fecha de inicio de vigencia,Fecha de fin de vigencia,Símbolo,,,,,, +18,Tambor de cincuenta y cinco galones (EUA),,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +19,Camión cisterna,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +26,Tonelada real,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +29,Libra por mil pies cuadrados,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,Lb / kft²,,,,,, +30,Día de potencia de caballos por tonelada métrica de aire seco,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +31,Pescar,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +32,Kilogramo por tonelada métrica seca del aire,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +36,Pie cúbico por minuto por pie cuadrado,Se requiere factor de conversión,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,Ft³ / (min / ft²),,,,,, +44,Bolsa a granel de quinientos kilos,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +45,Bolsa a granel de trescientos kilos,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +46,Bolsa a granel de cincuenta libras,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +47,Bolso de cincuenta libras,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +48,Carga masiva,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +53,Kilogramo teórico,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +54,Tonelada teórica (UK),,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +62,Por ciento por 1000 horas,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +63,Tasa de fracaso en el tiempo,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +64,"Libra por pulgada cuadrada, calibre",,Unidades no recomendadas para su uso por la Oficina Internacional de Pesos y Medidas (BIPM) con sede en Francia.,2022-01-01,,,,,,,, +66,Oersted,,Unidades no recomendadas para su uso por la Oficina Internacional de Pesos y Medidas (BIPM) con sede en Francia.,2022-01-01,,Oe,,,,,, +69,Escala específica de prueba,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +71,Voltios amperios por libra,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +72,Vatio por libra,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +73,Amperios por centímetro,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +76,Gauss,,Unidades no recomendadas para su uso por la Oficina Internacional de Pesos y Medidas (BIPM) con sede en Francia.,2022-01-01,,Gs,,,,,, +78,Kilogauss,,Unidades no recomendadas para su uso por la Oficina Internacional de Pesos y Medidas (BIPM) con sede en Francia.,2022-01-01,,Ks,,,,,, +84,Kilopound-force por pulgada cuadrada,Unidad de presión que define el número de kilopounds fuerza por pulgada cuadrada. \n\nUtilice kip por pulgada cuadrada (código común N20).,Unidades no recomendadas para su uso por la Oficina Internacional de Pesos y Medidas (BIPM) con sede en Francia.,2022-01-01,,Klbf / in²,,,,,, +90,Saybold segundo universal,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +92,Calorías por centímetro cúbico,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +93,Calorías por gramo,Utilice calorías de la tabla internacional (IT) por gramo (código común D75).,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,Cal / g,,,,,, +XYM,"Empaque compuesto, recipiente de plástico en caja de plástico sólido",,,2022-01-01,,,,,,,, +XYN,"Empaque compuesto, receptáculo de vidrio en tambor de acero",,,2022-01-01,,,,,,,, +XYP,"Empaque compuesto, receptáculo de vidrio en caja de cajas de acero",,,2022-01-01,,,,,,,, +XYQ,"Empaque compuesto, recipiente de vidrio en tambor de aluminio",,,2022-01-01,,,,,,,, +XYR,"Empaque compuesto, receptáculo de vidrio en caja de aluminio",,,2022-01-01,,,,,,,, +XYS,"Empaque compuesto, recipiente de vidrio en caja de madera",,,2022-01-01,,,,,,,, +XYT,"Empaque compuesto, recipiente de vidrio en tambor de madera contrachapada",,,2022-01-01,,,,,,,, +Xyv,"Empaque compuesto, recipiente de vidrio en el cesto de mimbre",,,2022-01-01,,,,,,,, +XYW,"Empaque compuesto, recipiente de vidrio en tambor de fibra",,,2022-01-01,,,,,,,, +XYX,"Empaque compuesto, recipiente de vidrio en caja de cartón",,,2022-01-01,,,,,,,, +XYY,"Empaque compuesto, recipiente de vidrio en paquete de plástico expandible",,,2022-01-01,,,,,,,, +XYZ,"Empaque compuesto, recipiente de vidrio en paquete de plástico sólido",,,2022-01-01,,,,,,,, +XZA,"Contenedor de granel intermedio, papel, multi-pared",,,2022-01-01,,,,,,,, +XZB,Bolsa grande,,,2022-01-01,,,,,,,, +XZC,"Contenedor intermedio para gráneles de papel, multi-pared y resistente al agua",,,2022-01-01,,,,,,,, +XZD,"Contenedor intermedio para gráneles de plástico rígido, con equipo estructural para sólidos",,,2022-01-01,,,,,,,, +XZF,"Contenedor intermedio para gráneles de plástico rígido, autoportante para sólidos",,,2022-01-01,,,,,,,, +XZG,"Contenedor intermedio para gráneles de plástico rígido, con equipo estructural, presurizado",,,2022-01-01,,,,,,,, +XZH,"Contenedor intermedio para gráneles de plástico rígido, autoportante y presurizado",,,2022-01-01,,,,,,,, +XZJ,"Contenedor intermedio para gráneles de plástico rígido, con equipo estructural para líquidos",,,2022-01-01,,,,,,,, +XZK,"Contenedor intermedio para gráneles de plástico rígido, autoportante, líquidos",,,2022-01-01,,,,,,,, +XZL,"Contenedor intermedio para gráneles, compuesto y de plástico rígido, sólidos",,,2022-01-01,,,,,,,, +XZM,"Contenedor intermedio para gráneles, compuesto y de plástico flexible, sólidos",,,2022-01-01,,,,,,,, +XZN,"Contenedor intermedio para gráneles, compuesto y de plástico rígido, presurizado",,,2022-01-01,,,,,,,, +XZP,"Contenedor intermedio para gráneles, compuesto y de plástico flexible, presurizado",,,2022-01-01,,,,,,,, +XZQ,"Contenedor intermedio para gráneles, compuesto y de plástico rígido, líquidos",,,2022-01-01,,,,,,,, +XZR,"Contenedor intermedio para gráneles, compuesto y de plástico flexible para líquidos",,,2022-01-01,,,,,,,, +XZS,"Contenedor intermedio para gráneles, compuesto",,,2022-01-01,,,,,,,, +XZT,Contenedor intermedio para gráneles con tablero de fibras,,,2022-01-01,,,,,,,, +XZU,Contenedor intermedio para gráneles flexible,,,2022-01-01,,,,,,,, +XZV,"Contenedor intermedio para gráneles de metal, distinto del acero",,,2022-01-01,,,,,,,, +XZW,"Contenedor intermedio para gráneles, de madera natural",,,2022-01-01,,,,,,,, +XZX,"Contenedor intermedio para gráneles, de contrachapado",,,2022-01-01,,,,,,,, +XZY,"Contenedor intermedio para gráneles, de madera reconstituida",,,2022-01-01,,,,,,,, +YDK,Yarda cuadrada,Es una unidad anglosajona de superficie de una yarda de lado. ,,2022-01-01,,yd²,,,,,, +YDQ,Yarda cúbica,,,2022-01-01,,yd³,,,,,, +YL,Cien yardas lineales,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +YRD,Yarda,"Es la unidad de longitud básica en los sistemas de medida utilizados en Estados Unidos, Panamá y Reino Unido.\nEquivale a 91.4 centímetros.",,2022-01-01,,yd,,,,,, +YT,Diez yardas,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +Z1,Furgoneta,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +Z11,Contenedor colgante ,Unidad de conteo que define el número de contenedores colgantes.,,2022-01-01,,,,,,,, +Z5,Arrastre,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +Z6,Punto de conferencia,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +Z8,Página de noticias,,"Las unidades marcadas como borradas en el catálogo internacional de UNECE, serán retenidas indefinidamente en las listas de códigos. En su caso, estas unidades podrán ser reinstalado a través del proceso de mantenimiento.",2022-01-01,,,,,,,, +ZP,Páginas,Unidad de conteo que define el número de páginas,,2022-01-01,,,,,,,, +ZZ,Mutuamente definido,Unidad de medida acordada en común entre dos o más partes,,2022-01-01,,,,,,,, diff --git a/tests/_files/cfdi40/c_CodigoPostal.csv b/tests/_files/cfdi40/c_CodigoPostal.csv new file mode 100644 index 0000000..b400fcc --- /dev/null +++ b/tests/_files/cfdi40/c_CodigoPostal.csv @@ -0,0 +1,458 @@ +Catálogo de códigos postales.,,,,,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,,,,,,,,,,, +4.0,1.0,1,2022-02-08,2022-01-01,,,,,,,,,,, +c_CodigoPostal,c_Estado,c_Municipio,c_Localidad,Estímulo Franja Fronteriza,Fecha inicio de vigencia ,Fecha fin de vigencia ,Referencias del Huso Horario,,,,,,,, +,,,,,,,Descripción del Huso Horario,Mes_Inicio_Horario_Verano,Día_Inicio_Horario_Verano,Día_Inicio_Horario_Verano,Diferencia_Horaria_Verano,Mes_Inicio_Horario_Invierno,Día_Inicio_Horario_Invierno,Día_Inicio_Horario_Invierno,Diferencia_Horaria_Invierno +20000,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20001,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20002,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20003,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20004,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20005,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20006,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20007,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20008,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20009,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20010,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20011,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20012,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20013,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20014,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20015,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20016,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20017,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20018,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20019,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20020,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20021,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20022,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20023,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20024,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20025,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20026,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20027,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20028,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20029,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20030,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20031,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20032,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20033,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20034,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20035,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20036,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20037,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20038,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20039,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20040,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20041,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20042,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20043,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20044,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20045,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20046,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20047,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20048,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20049,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20050,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20051,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20052,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20053,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20054,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20055,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20056,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20057,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20058,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20059,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20060,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20061,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20062,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20063,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20064,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20065,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20066,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20067,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20068,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20069,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20070,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20071,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20072,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20073,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20074,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20075,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20076,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20077,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20078,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20079,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20080,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20081,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20082,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20083,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20084,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20085,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20086,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20087,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20088,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20089,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20090,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20091,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20092,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20093,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20094,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20095,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20096,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20097,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20098,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20099,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20100,AGU,001,01,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20101,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20102,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20103,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20104,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20105,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +20106,AGU,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64161,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64162,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64163,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64164,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64165,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64166,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64167,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64168,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64169,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64170,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64171,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64172,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64173,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64174,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64175,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64176,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64177,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64178,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64179,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64180,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64181,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64182,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64183,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64184,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64185,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64186,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64187,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64188,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64189,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64190,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64191,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64192,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64193,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64194,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64195,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64196,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64197,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64198,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64199,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64200,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64201,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64202,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64203,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64204,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64205,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64206,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64207,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64208,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64209,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64210,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64211,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64212,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64213,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64214,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64215,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64216,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64217,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64218,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64219,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64220,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64221,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64222,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64223,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64224,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64225,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64226,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64227,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64228,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64229,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64230,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64231,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64232,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64233,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64234,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64235,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64236,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64237,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64238,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64239,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64240,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64241,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64242,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64243,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64244,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64245,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64246,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64247,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64248,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64249,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64250,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64251,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64252,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64253,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64254,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64255,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64256,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64257,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64258,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64259,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64260,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64261,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64262,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64263,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64264,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64265,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64266,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64267,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64268,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64269,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64270,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64271,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64272,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64273,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64274,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64275,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64276,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64277,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64278,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64279,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64280,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64281,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64282,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64283,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64284,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64285,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64286,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64287,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64288,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64289,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64290,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64291,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64292,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64293,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64294,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64295,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64296,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64297,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64298,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64299,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64300,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64301,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64302,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64303,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64304,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64305,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64306,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64307,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64308,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64309,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64310,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64311,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64312,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64313,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64314,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64315,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64316,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64317,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64318,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64319,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64320,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64321,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64322,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64323,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64324,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64325,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64326,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64327,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64328,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64329,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64330,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64331,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64332,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64333,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64334,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64335,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64336,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64337,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64338,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64339,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64340,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64341,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64342,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64343,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64344,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64345,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64346,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64347,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64348,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64349,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64350,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64351,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64352,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64353,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64354,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64355,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64356,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64357,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64358,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64359,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64360,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64361,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64362,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64363,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64364,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64365,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64366,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64367,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64368,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64369,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64370,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64371,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64372,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64373,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64374,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64375,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64376,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64377,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64378,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64379,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64380,NLE,039,07,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64381,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64382,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64383,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64384,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64385,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +64386,NLE,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99880,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99881,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99882,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99883,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99884,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99885,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99886,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99887,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99888,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99889,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99890,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99891,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99892,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99893,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99894,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99895,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99896,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99897,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99898,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99899,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99900,ZAC,034,11,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99901,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99902,ZAC,034,11,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99903,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99904,ZAC,034,11,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99905,ZAC,034,11,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99906,ZAC,034,11,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99907,ZAC,034,11,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99908,ZAC,034,11,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99909,ZAC,034,11,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99910,ZAC,034,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99911,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99912,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99913,ZAC,034,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99914,ZAC,034,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99915,ZAC,034,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99916,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99917,ZAC,034,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99918,ZAC,034,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99919,ZAC,034,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99920,ZAC,002,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99921,ZAC,002,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99922,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99923,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99924,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99925,ZAC,002,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99926,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99927,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99928,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99929,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99930,ZAC,002,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99931,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99932,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99933,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99934,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99935,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99936,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99937,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99938,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99939,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99940,ZAC,001,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99941,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99942,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99943,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99944,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99945,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99946,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99947,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99948,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99949,ZAC,001,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99950,ZAC,001,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99951,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99952,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99953,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99954,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99955,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99956,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99957,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99958,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99959,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99960,ZAC,023,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99961,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99962,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99963,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99964,ZAC,023,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99965,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99966,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99967,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99968,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99969,ZAC,023,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99970,ZAC,023,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99971,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99972,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99973,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99974,ZAC,023,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99975,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99976,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99977,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99978,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99979,ZAC,023,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99980,ZAC,033,15,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99981,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99982,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99983,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99984,ZAC,033,15,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99985,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99986,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99987,ZAC,033,15,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99988,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99989,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99990,ZAC,033,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99991,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99992,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99993,ZAC,033,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99994,ZAC,033,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99995,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99996,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99997,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99998,ZAC,033,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 +99999,ZAC,,,0,2022-01-01,,Tiempo del Centro,Abril,Primer domingo,02:00,-5,Octubre,Último domingo,02:00,-6 diff --git a/tests/_files/cfdi40/c_Estado.csv b/tests/_files/cfdi40/c_Estado.csv new file mode 100644 index 0000000..bd35a79 --- /dev/null +++ b/tests/_files/cfdi40/c_Estado.csv @@ -0,0 +1,99 @@ +Catálogo de estados. ,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo +4.0,1.0,0,0,2022-01-01, +c_Estado,c_Pais,Nombre del estado,Fecha inicio de vigencia,Fecha fin de vigencia, +AGU,MEX,Aguascalientes,2022-01-01,, +BCN,MEX,Baja California,2022-01-01,, +BCS,MEX,Baja California Sur,2022-01-01,, +CAM,MEX,Campeche,2022-01-01,, +CHP,MEX,Chiapas,2022-01-01,, +CHH,MEX,Chihuahua,2022-01-01,, +COA,MEX,Coahuila,2022-01-01,, +COL,MEX,Colima,2022-01-01,, +CMX,MEX,Ciudad de México,2022-01-01,, +DUR,MEX,Durango,2022-01-01,, +GUA,MEX,Guanajuato,2022-01-01,, +GRO,MEX,Guerrero,2022-01-01,, +HID,MEX,Hidalgo,2022-01-01,, +JAL,MEX,Jalisco,2022-01-01,, +MEX,MEX,Estado de México,2022-01-01,, +MIC,MEX,Michoacán,2022-01-01,, +MOR,MEX,Morelos,2022-01-01,, +NAY,MEX,Nayarit,2022-01-01,, +NLE,MEX,Nuevo León,2022-01-01,, +OAX,MEX,Oaxaca,2022-01-01,, +PUE,MEX,Puebla,2022-01-01,, +QUE,MEX,Querétaro,2022-01-01,, +ROO,MEX,Quintana Roo,2022-01-01,, +SLP,MEX,San Luis Potosí,2022-01-01,, +SIN,MEX,Sinaloa,2022-01-01,, +SON,MEX,Sonora,2022-01-01,, +TAB,MEX,Tabasco,2022-01-01,, +TAM,MEX,Tamaulipas,2022-01-01,, +TLA,MEX,Tlaxcala,2022-01-01,, +VER,MEX,Veracruz,2022-01-01,, +YUC,MEX,Yucatán,2022-01-01,, +ZAC,MEX,Zacatecas,2022-01-01,, +AL,USA,Alabama,2022-01-01,, +AK,USA,Alaska,2022-01-01,, +AZ,USA,Arizona,2022-01-01,, +AR,USA,Arkansas,2022-01-01,, +CA,USA,California,2022-01-01,, +NC,USA,Carolina del Norte,2022-01-01,, +SC,USA,Carolina del Sur,2022-01-01,, +CO,USA,Colorado,2022-01-01,, +CT,USA,Connecticut,2022-01-01,, +ND,USA,Dakota del Norte,2022-01-01,, +SD,USA,Dakota del Sur,2022-01-01,, +DE,USA,Delaware,2022-01-01,, +FL,USA,Florida,2022-01-01,, +GA,USA,Georgia,2022-01-01,, +HI,USA,Hawái,2022-01-01,, +ID,USA,Idaho,2022-01-01,, +IL,USA,Illinois,2022-01-01,, +IN,USA,Indiana,2022-01-01,, +IA,USA,Iowa,2022-01-01,, +KS,USA,Kansas,2022-01-01,, +KY,USA,Kentucky,2022-01-01,, +LA,USA,Luisiana,2022-01-01,, +ME,USA,Maine,2022-01-01,, +MD,USA,Maryland,2022-01-01,, +MA,USA,Massachusetts,2022-01-01,, +MI,USA,Míchigan,2022-01-01,, +MN,USA,Minnesota,2022-01-01,, +MS,USA,Misisipi,2022-01-01,, +MO,USA,Misuri,2022-01-01,, +MT,USA,Montana,2022-01-01,, +NE,USA,Nebraska,2022-01-01,, +NV,USA,Nevada,2022-01-01,, +NJ,USA,Nueva Jersey,2022-01-01,, +NY,USA,Nueva York,2022-01-01,, +NH,USA,Nuevo Hampshire,2022-01-01,, +NM,USA,Nuevo México,2022-01-01,, +OH,USA,Ohio,2022-01-01,, +OK,USA,Oklahoma,2022-01-01,, +OR,USA,Oregón,2022-01-01,, +PA,USA,Pensilvania,2022-01-01,, +RI,USA,Rhode Island,2022-01-01,, +TN,USA,Tennessee,2022-01-01,, +TX,USA,Texas,2022-01-01,, +UT,USA,Utah,2022-01-01,, +VT,USA,Vermont,2022-01-01,, +VA,USA,Virginia,2022-01-01,, +WV,USA,Virginia Occidental,2022-01-01,, +WA,USA,Washington,2022-01-01,, +WI,USA,Wisconsin,2022-01-01,, +WY,USA,Wyoming,2022-01-01,, +ON,CAN,Ontario ,2022-01-01,, +QC,CAN, Quebec ,2022-01-01,, +NS,CAN, Nueva Escocia,2022-01-01,, +NB,CAN,Nuevo Brunswick ,2022-01-01,, +MB,CAN, Manitoba,2022-01-01,, +BC,CAN, Columbia Británica,2022-01-01,, +PE,CAN, Isla del Príncipe Eduardo,2022-01-01,, +SK,CAN, Saskatchewan,2022-01-01,, +AB,CAN, Alberta,2022-01-01,, +NL,CAN, Terranova y Labrador,2022-01-01,, +NT,CAN, Territorios del Noroeste,2022-01-01,, +YT,CAN, Yukón,2022-01-01,, +UN,CAN, Nunavut,2022-01-01,, diff --git a/tests/_files/cfdi40/c_Exportacion.csv b/tests/_files/cfdi40/c_Exportacion.csv new file mode 100644 index 0000000..0d059bb --- /dev/null +++ b/tests/_files/cfdi40/c_Exportacion.csv @@ -0,0 +1,8 @@ +Catálogo exportación.,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,,,,,, +4.0,2.0,1,2022-02-24,2022-01-01,,,,,, +c_Exportacion,Descripción,Fecha inicio de vigencia,Fecha fin de vigencia,,,,,,, +01,No aplica,2022-01-01,,,,,,,, +02,Definitiva con clave A1,2022-01-01,,,,,,,, +03,Temporal,2022-01-01,,,,,,,, +04,Definitiva con clave distinta a A1 o cuando no existe enajenación en términos del CFF,2022-02-25,,,,,,,, diff --git a/tests/_files/cfdi40/c_FormaPago.csv b/tests/_files/cfdi40/c_FormaPago.csv new file mode 100644 index 0000000..d6b9b8a --- /dev/null +++ b/tests/_files/cfdi40/c_FormaPago.csv @@ -0,0 +1,26 @@ +Catálogo de formas de pago.,,,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,,,, +c_FormaPago,Descripción,Bancarizado,Número de operación,RFC del Emisor de la cuenta ordenante,Cuenta Ordenante,Patrón para cuenta ordenante,RFC del Emisor Cuenta de Beneficiario,Cuenta de Benenficiario,Patrón para cuenta Beneficiaria,Tipo Cadena Pago,Nombre del Banco emisor de la cuenta ordenante en caso de extranjero,Fecha inicio de vigencia,Fecha fin de vigencia +1,Efectivo,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +2,Cheque nominativo,Sí,Opcional,Opcional,Opcional,[0-9]{11}|[0-9]{18},Opcional,Opcional,"[0-9]{10,11}|[0-9]{15,16}|[0-9]{18}|[A-Z0-9_]{10,50}",No,"Si el RFC del emisor de la cuenta ordenante es XEXX010101000, este campo es obligatorio.",2022-01-01, +3,Transferencia electrónica de fondos,Sí,Opcional,Opcional,Opcional,[0-9]{10}|[0-9]{16}|[0-9]{18},Opcional,Opcional,[0-9]{10}|[0-9]{18},Opcional,"Si el RFC del emisor de la cuenta ordenante es XEXX010101000, este campo es obligatorio.",2022-01-01, +4,Tarjeta de crédito,Sí,Opcional,Opcional,Opcional,[0-9]{16},Opcional,Opcional,"[0-9]{10,11}|[0-9]{15,16}|[0-9]{18}|[A-Z0-9_]{10,50}",No,"Si el RFC del emisor de la cuenta ordenante es XEXX010101000, este campo es obligatorio.",2022-01-01, +5,Monedero electrónico,Sí,Opcional,Opcional,Opcional,"[0-9]{10,11}|[0-9]{15,16}|[0-9]{18}|[A-Z0-9_]{10,50}",Opcional,Opcional,"[0-9]{10,11}|[0-9]{15,16}|[0-9]{18}|[A-Z0-9_]{10,50}",No,No,2022-01-01, +6,Dinero electrónico,Sí,Opcional,Opcional,Opcional,[0-9]{10},No,No,No,No,No,2022-01-01, +8,Vales de despensa,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +12,Dación en pago,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +13,Pago por subrogación,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +14,Pago por consignación,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +15,Condonación,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +17,Compensación,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +23,Novación,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +24,Confusión,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +25,Remisión de deuda,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +26,Prescripción o caducidad,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +27,A satisfacción del acreedor,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +28,Tarjeta de débito,Sí,Opcional,Opcional,Opcional,[0-9]{16},Opcional,Opcional,"[0-9]{10,11}|[0-9]{15,16}|[0-9]{18}|[A-Z0-9_]{10,50}",No,"Si el RFC del emisor de la cuenta ordenante es XEXX010101000, este campo es obligatorio.",2022-01-01, +29,Tarjeta de servicios,Sí,Opcional,Opcional,Opcional,"[0-9]{15,16}",Opcional,Opcional,"[0-9]{10,11}|[0-9]{15,16}|[0-9]{18}|[A-Z0-9_]{10,50}",No,"Si el RFC del emisor de la cuenta ordenante es XEXX010101000, este campo es obligatorio.",2022-01-01, +30,Aplicación de anticipos,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +31,Intermediario pagos,No,Opcional,No,No,No,No,No,No,No,No,2022-01-01, +99,Por definir,Opcional,Opcional,Opcional,Opcional,Opcional,Opcional,Opcional,Opcional,Opcional,Opcional,2022-01-01, diff --git a/tests/_files/cfdi40/c_Impuesto.csv b/tests/_files/cfdi40/c_Impuesto.csv new file mode 100644 index 0000000..1a99b2a --- /dev/null +++ b/tests/_files/cfdi40/c_Impuesto.csv @@ -0,0 +1,7 @@ +Catálogo de impuestos.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_Impuesto,Descripción,Retención,Traslado,Local o federal,Fecha inicio de vigencia,Fecha fin de vigencia,,,,, +1,ISR,Si,No,Federal,2022-01-01,,,,,, +2,IVA,Si,Si,Federal,2022-01-01,,,,,, +3,IEPS,Si,Si,Federal,2022-01-01,,,,,, diff --git a/tests/_files/cfdi40/c_Meses.csv b/tests/_files/cfdi40/c_Meses.csv new file mode 100644 index 0000000..cbf0bff --- /dev/null +++ b/tests/_files/cfdi40/c_Meses.csv @@ -0,0 +1,22 @@ +Catálogo meses.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_Meses,Descripción,Fecha inicio de vigencia,Fecha fin de vigencia,,,,,,,, +01,Enero,2022-01-01,,,,,,,,, +02,Febrero,2022-01-01,,,,,,,,, +03,Marzo,2022-01-01,,,,,,,,, +04,Abril,2022-01-01,,,,,,,,, +05,Mayo,2022-01-01,,,,,,,,, +06,Junio,2022-01-01,,,,,,,,, +07,Julio,2022-01-01,,,,,,,,, +08,Agosto,2022-01-01,,,,,,,,, +09,Septiembre,2022-01-01,,,,,,,,, +10,Octubre,2022-01-01,,,,,,,,, +11,Noviembre,2022-01-01,,,,,,,,, +12,Diciembre,2022-01-01,,,,,,,,, +13,Enero-Febrero,2022-01-01,,,,,,,,, +14,Marzo-Abril,2022-01-01,,,,,,,,, +15,Mayo-Junio,2022-01-01,,,,,,,,, +16,Julio-Agosto,2022-01-01,,,,,,,,, +17,Septiembre-Octubre,2022-01-01,,,,,,,,, +18,Noviembre-Diciembre,2022-01-01,,,,,,,,, diff --git a/tests/_files/cfdi40/c_MetodoPago.csv b/tests/_files/cfdi40/c_MetodoPago.csv new file mode 100644 index 0000000..7b3e939 --- /dev/null +++ b/tests/_files/cfdi40/c_MetodoPago.csv @@ -0,0 +1,6 @@ +Catálogo de Método de Pago.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_MetodoPago,Descripción,Fecha inicio de vigencia,Fecha fin de vigencia,,,,,,,, +PUE,Pago en una sola exhibición,2022-01-01,,,,,,,,, +PPD,Pago en parcialidades o diferido,2022-01-01,,,,,,,,, diff --git a/tests/_files/cfdi40/c_Moneda.csv b/tests/_files/cfdi40/c_Moneda.csv new file mode 100644 index 0000000..ecb559d --- /dev/null +++ b/tests/_files/cfdi40/c_Moneda.csv @@ -0,0 +1,182 @@ +Catálogo de moneda. ,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_Moneda,Descripción,Decimales,Porcentaje variación,Fecha inicio de vigencia,Fecha fin de vigencia,,,,,, +AED,Dirham de EAU,2,5,2022-01-01,,,,,,, +AFN,Afghani,2,5,2022-01-01,,,,,,, +ALL,Lek,2,5,2022-01-01,,,,,,, +AMD,Dram armenio,2,5,2022-01-01,,,,,,, +ANG,Florín antillano neerlandés,2,5,2022-01-01,,,,,,, +AOA,Kwanza,2,5,2022-01-01,,,,,,, +ARS,Peso Argentino,2,5,2022-01-01,,,,,,, +AUD,Dólar Australiano,2,5,2022-01-01,,,,,,, +AWG,Aruba Florin,2,5,2022-01-01,,,,,,, +AZN,Azerbaijanian Manat,2,5,2022-01-01,,,,,,, +BAM,Convertibles marca,2,5,2022-01-01,,,,,,, +BBD,Dólar de Barbados,2,5,2022-01-01,,,,,,, +BDT,Taka,2,5,2022-01-01,,,,,,, +BGN,Lev búlgaro,2,5,2022-01-01,,,,,,, +BHD,Dinar de Bahrein,3,5,2022-01-01,,,,,,, +BIF,Burundi Franc,0,5,2022-01-01,,,,,,, +BMD,Dólar de Bermudas,2,5,2022-01-01,,,,,,, +BND,Dólar de Brunei,2,5,2022-01-01,,,,,,, +BOB,Boliviano,2,5,2022-01-01,,,,,,, +BOV,Mvdol,2,5,2022-01-01,,,,,,, +BRL,Real brasileño,2,5,2022-01-01,,,,,,, +BSD,Dólar de las Bahamas,2,5,2022-01-01,,,,,,, +BTN,Ngultrum,2,5,2022-01-01,,,,,,, +BWP,Pula,2,5,2022-01-01,,,,,,, +BYR,Rublo bielorruso,0,5,2022-01-01,,,,,,, +BZD,Dólar de Belice,2,5,2022-01-01,,,,,,, +CAD,Dólar Canadiense,2,5,2022-01-01,,,,,,, +CDF,Franco congoleño,2,5,2022-01-01,,,,,,, +CHE,WIR Euro,2,5,2022-01-01,,,,,,, +CHF,Franco Suizo,2,5,2022-01-01,,,,,,, +CHW,Franc WIR,2,5,2022-01-01,,,,,,, +CLF,Unidad de Fomento,4,5,2022-01-01,,,,,,, +CLP,Peso chileno,0,5,2022-01-01,,,,,,, +CNY,Yuan Renminbi,2,5,2022-01-01,,,,,,, +COP,Peso Colombiano,2,5,2022-01-01,,,,,,, +COU,Unidad de Valor real,2,5,2022-01-01,,,,,,, +CRC,Colón costarricense,2,5,2022-01-01,,,,,,, +CUC,Peso Convertible,2,5,2022-01-01,,,,,,, +CUP,Peso Cubano,2,5,2022-01-01,,,,,,, +CVE,Cabo Verde Escudo,2,5,2022-01-01,,,,,,, +CZK,Corona checa,2,5,2022-01-01,,,,,,, +DJF,Franco de Djibouti,0,5,2022-01-01,,,,,,, +DKK,Corona danesa,2,5,2022-01-01,,,,,,, +DOP,Peso Dominicano,2,5,2022-01-01,,,,,,, +DZD,Dinar argelino,2,5,2022-01-01,,,,,,, +EGP,Libra egipcia,2,5,2022-01-01,,,,,,, +ERN,Nakfa,2,5,2022-01-01,,,,,,, +ETB,Birr etíope,2,5,2022-01-01,,,,,,, +EUR,Euro,2,5,2022-01-01,,,,,,, +FJD,Dólar de Fiji,2,5,2022-01-01,,,,,,, +FKP,Libra malvinense,2,5,2022-01-01,,,,,,, +GBP,Libra Esterlina,2,5,2022-01-01,,,,,,, +GEL,Lari,2,5,2022-01-01,,,,,,, +GHS,Cedi de Ghana,2,5,2022-01-01,,,,,,, +GIP,Libra de Gibraltar,2,5,2022-01-01,,,,,,, +GMD,Dalasi,2,5,2022-01-01,,,,,,, +GNF,Franco guineano,0,5,2022-01-01,,,,,,, +GTQ,Quetzal,2,5,2022-01-01,,,,,,, +GYD,Dólar guyanés,2,5,2022-01-01,,,,,,, +HKD,Dólar De Hong Kong,2,5,2022-01-01,,,,,,, +HNL,Lempira,2,5,2022-01-01,,,,,,, +HRK,Kuna,2,5,2022-01-01,,,,,,, +HTG,Gourde,2,5,2022-01-01,,,,,,, +HUF,Florín,2,5,2022-01-01,,,,,,, +IDR,Rupia,2,5,2022-01-01,,,,,,, +ILS,Nuevo Shekel Israelí,2,5,2022-01-01,,,,,,, +INR,Rupia india,2,5,2022-01-01,,,,,,, +IQD,Dinar iraquí,3,5,2022-01-01,,,,,,, +IRR,Rial iraní,2,5,2022-01-01,,,,,,, +ISK,Corona islandesa,0,5,2022-01-01,,,,,,, +JMD,Dólar Jamaiquino,2,5,2022-01-01,,,,,,, +JOD,Dinar jordano,3,5,2022-01-01,,,,,,, +JPY,Yen,0,5,2022-01-01,,,,,,, +KES,Chelín keniano,2,5,2022-01-01,,,,,,, +KGS,Som,2,5,2022-01-01,,,,,,, +KHR,Riel,2,5,2022-01-01,,,,,,, +KMF,Franco Comoro,0,5,2022-01-01,,,,,,, +KPW,Corea del Norte ganó,2,5,2022-01-01,,,,,,, +KRW,Won,0,5,2022-01-01,,,,,,, +KWD,Dinar kuwaití,3,5,2022-01-01,,,,,,, +KYD,Dólar de las Islas Caimán,2,5,2022-01-01,,,,,,, +KZT,Tenge,2,5,2022-01-01,,,,,,, +LAK,Kip,2,5,2022-01-01,,,,,,, +LBP,Libra libanesa,2,5,2022-01-01,,,,,,, +LKR,Rupia de Sri Lanka,2,5,2022-01-01,,,,,,, +LRD,Dólar liberiano,2,5,2022-01-01,,,,,,, +LSL,Loti,2,5,2022-01-01,,,,,,, +LYD,Dinar libio,3,5,2022-01-01,,,,,,, +MAD,Dirham marroquí,2,5,2022-01-01,,,,,,, +MDL,Leu moldavo,2,5,2022-01-01,,,,,,, +MGA,Ariary malgache,2,5,2022-01-01,,,,,,, +MKD,Denar,2,5,2022-01-01,,,,,,, +MMK,Kyat,2,5,2022-01-01,,,,,,, +MNT,Tugrik,2,5,2022-01-01,,,,,,, +MOP,Pataca,2,5,2022-01-01,,,,,,, +MRO,Ouguiya,2,5,2022-01-01,,,,,,, +MUR,Rupia de Mauricio,2,5,2022-01-01,,,,,,, +MVR,Rupia,2,5,2022-01-01,,,,,,, +MWK,Kwacha,2,5,2022-01-01,,,,,,, +MXN,Peso Mexicano,2,5,2022-01-01,,,,,,, +MXV,México Unidad de Inversión (UDI),2,5,2022-01-01,,,,,,, +MYR,Ringgit malayo,2,5,2022-01-01,,,,,,, +MZN,Mozambique Metical,2,5,2022-01-01,,,,,,, +NAD,Dólar de Namibia,2,5,2022-01-01,,,,,,, +NGN,Naira,2,5,2022-01-01,,,,,,, +NIO,Córdoba Oro,2,5,2022-01-01,,,,,,, +NOK,Corona noruega,2,5,2022-01-01,,,,,,, +NPR,Rupia nepalí,2,5,2022-01-01,,,,,,, +NZD,Dólar de Nueva Zelanda,2,5,2022-01-01,,,,,,, +OMR,Rial omaní,3,5,2022-01-01,,,,,,, +PAB,Balboa,2,5,2022-01-01,,,,,,, +PEN,Nuevo Sol,2,5,2022-01-01,,,,,,, +PGK,Kina,2,5,2022-01-01,,,,,,, +PHP,Peso filipino,2,5,2022-01-01,,,,,,, +PKR,Rupia de Pakistán,2,5,2022-01-01,,,,,,, +PLN,Zloty,2,5,2022-01-01,,,,,,, +PYG,Guaraní,0,5,2022-01-01,,,,,,, +QAR,Qatar Rial,2,5,2022-01-01,,,,,,, +RON,Leu rumano,2,5,2022-01-01,,,,,,, +RSD,Dinar serbio,2,5,2022-01-01,,,,,,, +RUB,Rublo ruso,2,5,2022-01-01,,,,,,, +RWF,Franco ruandés,0,5,2022-01-01,,,,,,, +SAR,Riyal saudí,2,5,2022-01-01,,,,,,, +SBD,Dólar de las Islas Salomón,2,5,2022-01-01,,,,,,, +SCR,Rupia de Seychelles,2,5,2022-01-01,,,,,,, +SDG,Libra sudanesa,2,5,2022-01-01,,,,,,, +SEK,Corona sueca,2,5,2022-01-01,,,,,,, +SGD,Dólar De Singapur,2,5,2022-01-01,,,,,,, +SHP,Libra de Santa Helena,2,5,2022-01-01,,,,,,, +SLL,Leona,2,5,2022-01-01,,,,,,, +SOS,Chelín somalí,2,5,2022-01-01,,,,,,, +SRD,Dólar de Suriname,2,5,2022-01-01,,,,,,, +SSP,Libra sudanesa Sur,2,5,2022-01-01,,,,,,, +STD,Dobra,2,5,2022-01-01,,,,,,, +SVC,Colon El Salvador,2,5,2022-01-01,,,,,,, +SYP,Libra Siria,2,5,2022-01-01,,,,,,, +SZL,Lilangeni,2,5,2022-01-01,,,,,,, +THB,Baht,2,5,2022-01-01,,,,,,, +TJS,Somoni,2,5,2022-01-01,,,,,,, +TMT,Turkmenistán nuevo manat,2,5,2022-01-01,,,,,,, +TND,Dinar tunecino,3,5,2022-01-01,,,,,,, +TOP,Pa'anga,2,5,2022-01-01,,,,,,, +TRY,Lira turca,2,5,2022-01-01,,,,,,, +TTD,Dólar de Trinidad y Tobago,2,5,2022-01-01,,,,,,, +TWD,Nuevo dólar de Taiwán,2,5,2022-01-01,,,,,,, +TZS,Shilling tanzano,2,5,2022-01-01,,,,,,, +UAH,Hryvnia,2,5,2022-01-01,,,,,,, +UGX,Shilling de Uganda,0,5,2022-01-01,,,,,,, +USD,Dólar americano,2,5,2022-01-01,,,,,,, +USN,Dólar estadounidense (día siguiente),2,5,2022-01-01,,,,,,, +UYI,Peso Uruguay en Unidades Indexadas (URUIURUI),0,5,2022-01-01,,,,,,, +UYU,Peso Uruguayo,2,5,2022-01-01,,,,,,, +UZS,Uzbekistán Sum,2,5,2022-01-01,,,,,,, +VEF,Bolívar,2,5,2022-01-01,,,,,,, +VND,Dong,0,5,2022-01-01,,,,,,, +VUV,Vatu,0,5,2022-01-01,,,,,,, +WST,Tala,2,5,2022-01-01,,,,,,, +XAF,Franco CFA BEAC,0,5,2022-01-01,,,,,,, +XAG,Plata,0,5,2022-01-01,,,,,,, +XAU,Oro,0,5,2022-01-01,,,,,,, +XBA,Unidad de Mercados de Bonos Unidad Europea Composite (EURCO),0,5,2022-01-01,,,,,,, +XBB,Unidad Monetaria de Bonos de Mercados Unidad Europea (UEM-6),0,5,2022-01-01,,,,,,, +XBC,Mercados de Bonos Unidad Europea unidad de cuenta a 9 (UCE-9),0,5,2022-01-01,,,,,,, +XBD,Mercados de Bonos Unidad Europea unidad de cuenta a 17 (UCE-17),0,5,2022-01-01,,,,,,, +XCD,Dólar del Caribe Oriental,2,5,2022-01-01,,,,,,, +XDR,DEG (Derechos Especiales de Giro),0,5,2022-01-01,,,,,,, +XOF,Franco CFA BCEAO,0,5,2022-01-01,,,,,,, +XPD,Paladio,0,5,2022-01-01,,,,,,, +XPF,Franco CFP,0,5,2022-01-01,,,,,,, +XPT,Platino,0,5,2022-01-01,,,,,,, +XSU,Sucre,0,5,2022-01-01,,,,,,, +XTS,Códigos reservados específicamente para propósitos de prueba,0,,2022-01-01,,,,,,, +XUA,Unidad ADB de Cuenta,0,5,2022-01-01,,,,,,, +XXX,Los códigos asignados para las transacciones en que intervenga ninguna moneda,0,,2022-01-01,,,,,,, +YER,Rial yemení,2,5,2022-01-01,,,,,,, +ZAR,Rand,2,5,2022-01-01,,,,,,, +ZMW,Kwacha zambiano,2,5,2022-01-01,,,,,,, +ZWL,Zimbabwe Dólar,2,5,2022-01-01,,,,,,, diff --git a/tests/_files/cfdi40/c_NumPedimentoAduana.csv b/tests/_files/cfdi40/c_NumPedimentoAduana.csv new file mode 100644 index 0000000..095e44e --- /dev/null +++ b/tests/_files/cfdi40/c_NumPedimentoAduana.csv @@ -0,0 +1,223 @@ +Catálogo de números de pedimento operados por aduana y ejercicio.,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo, +4.0,7.0,0,2022-03-02,2022-01-01, +c_Aduana,Patente,Ejercicio,Cantidad,Fecha inicio de vigencia,Fecha fin de vigencia +01,3173,2007,999999,2017-01-01, +01,3173,2008,999999,2017-01-01, +01,3173,2009,999999,2017-01-01, +01,3173,2010,999999,2017-01-01, +01,3173,2011,999999,2017-01-01, +01,3173,2012,999999,2017-01-01, +01,3173,2013,999999,2017-01-01, +01,3173,2014,999999,2017-01-01, +01,3173,2015,999999,2017-01-01, +01,3173,2016,999999,2017-01-01, +01,3173,2017,999999,2017-04-28, +01,3173,2018,999999,2018-01-03, +01,3173,2019,999999,2019-01-01, +01,3173,2020,999999,2020-01-01, +01,3173,2021,999999,2021-01-01, +01,3173,2022,999999,2022-01-03, +01,4004,2007,999999,2017-01-01, +01,4004,2008,999999,2017-01-01, +01,4004,2009,999999,2017-01-01, +01,4004,2010,999999,2017-01-01, +01,4004,2011,999999,2017-01-01, +01,4004,2012,999999,2017-01-01, +01,4004,2013,999999,2017-01-01, +01,4004,2014,999999,2017-01-01, +01,4004,2015,999999,2017-01-01, +01,4004,2016,999999,2017-01-01, +01,4004,2017,999999,2017-04-28, +01,4004,2018,999999,2018-01-03, +01,4004,2019,999999,2019-01-01, +01,4004,2020,999999,2020-01-01, +01,4004,2021,999999,2021-01-01, +01,4004,2022,999999,2022-01-05, +01,4024,2007,999999,2017-01-01, +01,4024,2008,999999,2017-01-01, +01,4024,2009,999999,2017-01-01, +01,4024,2010,999999,2017-01-01, +01,4024,2011,999999,2017-01-01, +01,4024,2012,999999,2017-01-01, +01,4024,2013,999999,2017-01-01, +01,4024,2016,999999,2017-01-01, +01,4024,2017,999999,2017-04-28, +01,4024,2018,999999,2018-01-03, +01,4024,2019,999999,2019-01-01, +01,4024,2020,999999,2020-01-01, +01,4024,2021,999999,2021-01-01, +01,4024,2022,999999,2022-01-05, +01,4030,2007,999999,2017-01-01, +01,4030,2008,999999,2017-01-01, +01,4030,2009,999999,2017-01-01, +01,4030,2010,999999,2017-01-01, +01,4030,2011,999999,2017-01-01, +01,4030,2012,999999,2017-01-01, +01,4032,2007,999999,2017-01-01, +01,4032,2008,999999,2017-01-01, +01,4032,2009,999999,2017-01-01, +01,4032,2010,999999,2017-01-01, +01,4032,2011,999999,2017-01-01, +01,4032,2012,999999,2017-01-01, +01,4032,2013,999999,2017-01-01, +01,4032,2014,999999,2017-01-01, +01,4032,2015,999999,2017-01-01, +01,4032,2016,999999,2017-01-01, +01,6025,2007,999999,2017-01-01, +01,6025,2008,999999,2017-01-01, +01,6025,2010,999999,2017-01-01, +01,6025,2017,999999,2017-11-10, +01,6025,2018,999999,2018-01-03, +01,6025,2019,999999,2019-01-01, +01,6025,2020,999999,2020-01-01, +01,6025,2021,999999,2021-01-01, +01,6025,2022,999999,2022-01-05, +01,6120,2021,999999,2021-04-16, +01,6120,2022,999999,2022-01-05, +02,1623,2016,999999,2017-01-01, +02,1623,2017,999999,2017-04-28, +02,1623,2018,999999,2018-01-03, +02,1623,2019,999999,2019-01-01, +02,1623,2020,999999,2020-01-01, +02,1623,2021,999999,2021-01-01, +02,1623,2022,999999,2022-01-05, +02,1656,2018,999999,2018-08-22, +02,1656,2019,999999,2019-01-01, +02,1656,2020,999999,2020-01-01, +02,1656,2021,999999,2021-01-01, +02,1656,2022,999999,2022-01-05, +02,1746,2017,999999,2017-04-28, +02,1746,2018,999999,2018-01-03, +02,1746,2019,999999,2019-01-01, +02,1746,2020,999999,2020-01-01, +02,1746,2021,999999,2021-01-01, +02,1746,2022,999999,2022-01-05, +02,3186,2007,999999,2017-01-01, +02,3186,2008,999999,2017-01-01, +02,3186,2009,999999,2017-01-01, +02,3186,2010,999999,2017-01-01, +02,3186,2011,999999,2017-01-01, +02,3186,2012,999999,2017-01-01, +02,3186,2013,999999,2017-01-01, +02,3186,2014,999999,2017-01-01, +02,3186,2015,999999,2017-01-01, +02,3186,2016,999999,2017-01-01, +02,3186,2017,999999,2017-04-28, +02,3186,2018,999999,2018-01-03, +02,3186,2019,999999,2019-01-01, +02,3186,2020,999999,2020-01-01, +84,4024,2011,999999,2017-01-01, +84,4024,2012,999999,2017-01-01, +84,4024,2013,999999,2017-01-01, +84,4024,2014,999999,2017-01-01, +84,4024,2015,999999,2017-01-01, +84,4024,2016,999999,2017-01-01, +84,4024,2017,999999,2017-04-28, +84,4024,2018,999999,2018-01-03, +84,4024,2019,999999,2019-01-01, +84,4024,2020,999999,2020-01-01, +84,4024,2021,999999,2021-01-01, +84,4024,2022,999999,2022-01-05, +84,4091,2007,999999,2017-01-01, +84,4091,2008,999999,2017-01-01, +84,4091,2009,999999,2017-01-01, +84,4091,2010,999999,2017-01-01, +84,4091,2011,999999,2017-01-01, +84,4091,2012,999999,2017-01-01, +84,4091,2013,999999,2017-01-01, +84,4091,2014,999999,2017-01-01, +84,4092,2007,999999,2017-01-01, +84,4092,2008,999999,2017-01-01, +84,4092,2009,999999,2017-01-01, +84,4092,2010,999999,2017-01-01, +84,4092,2011,999999,2017-01-01, +84,4092,2012,999999,2017-01-01, +84,6001,2010,999999,2017-01-01, +84,6001,2011,999999,2017-01-01, +84,6001,2012,999999,2017-01-01, +84,6001,2013,999999,2017-01-01, +84,6001,2014,999999,2017-01-01, +84,6001,2015,999999,2017-01-01, +84,6001,2016,999999,2017-01-01, +84,6001,2017,999999,2017-04-28, +84,6001,2018,999999,2018-01-03, +84,6001,2019,999999,2019-01-01, +84,6001,2020,999999,2020-01-01, +84,6001,2021,999999,2021-01-01, +84,6001,2022,999999,2022-01-05, +84,9001,2007,999999,2017-01-01, +84,9001,2008,999999,2017-01-01, +84,9001,2009,999999,2017-01-01, +84,9001,2010,999999,2017-01-01, +84,9001,2011,999999,2017-01-01, +84,9001,2012,999999,2017-01-01, +84,9001,2013,999999,2017-01-01, +84,9001,2014,999999,2017-01-01, +84,9001,2015,999999,2017-01-01, +84,9001,2016,999999,2017-01-01, +84,9001,2017,999999,2017-04-28, +84,9001,2018,999999,2018-01-03, +84,9001,2019,999999,2019-01-01, +84,9001,2020,999999,2020-01-01, +84,9001,2021,999999,2021-01-01, +84,9001,2022,999999,2022-01-05, +84,9005,2011,999999,2017-01-01, +84,9005,2012,999999,2017-01-01, +84,9005,2013,999999,2017-01-01, +84,9005,2014,999999,2017-01-01, +84,9005,2015,999999,2017-01-01, +84,9005,2016,999999,2017-01-01, +84,9005,2017,999999,2017-04-28, +84,9005,2018,999999,2018-01-03, +84,9005,2019,999999,2019-01-01, +84,9005,2020,999999,2020-01-01, +84,9005,2021,999999,2021-01-01, +84,9005,2022,999999,2022-01-05, +84,9015,2007,999999,2017-01-01, +84,9015,2008,999999,2017-01-01, +84,9015,2009,999999,2017-01-01, +84,9015,2010,999999,2017-01-01, +84,9015,2011,999999,2017-01-01, +84,9015,2012,999999,2017-01-01, +84,9015,2013,999999,2017-01-01, +84,9015,2014,999999,2017-01-01, +84,9015,2015,999999,2017-01-01, +84,9015,2016,999999,2017-01-01, +84,9015,2017,999999,2017-04-28, +84,9015,2018,999999,2018-01-03, +84,9015,2019,999999,2019-01-01, +84,9015,2020,999999,2020-01-01, +84,9015,2021,999999,2021-01-01, +84,9015,2022,999999,2022-01-03, +84,9020,2018,999999,2018-01-22, +84,9020,2019,999999,2019-01-01, +84,9020,2020,999999,2020-01-01, +84,9020,2021,999999,2021-01-01, +84,9020,2022,999999,2022-01-05, +84,9022,2007,999999,2017-01-01, +84,9022,2008,999999,2017-01-01, +84,9022,2009,999999,2017-01-01, +84,9022,2010,999999,2017-01-01, +84,9022,2011,999999,2017-01-01, +84,9022,2012,999999,2017-01-01, +84,9022,2013,999999,2017-01-01, +84,9022,2014,999999,2017-01-01, +84,9022,2015,999999,2017-01-01, +84,9022,2016,999999,2017-01-01, +84,9024,2007,999999,2017-01-01, +84,9024,2008,999999,2017-01-01, +84,9024,2009,999999,2017-01-01, +84,9024,2010,999999,2017-01-01, +84,9037,2013,999999,2017-01-01, +84,9037,2014,999999,2017-01-01, +84,9037,2015,999999,2017-01-01, +84,9037,2016,999999,2017-01-01, +84,9037,2017,999999,2017-04-28, +84,9037,2018,999999,2018-01-03, +84,9037,2019,999999,2019-01-01, +84,9037,2020,999999,2020-01-01, +84,9037,2021,999999,2021-01-01, +84,9037,2022,999999,2022-01-05, +84,9044,2021,999999,2021-06-11, +84,9044,2022,999999,2022-01-05, diff --git a/tests/_files/cfdi40/c_ObjetoImp.csv b/tests/_files/cfdi40/c_ObjetoImp.csv new file mode 100644 index 0000000..8822c9a --- /dev/null +++ b/tests/_files/cfdi40/c_ObjetoImp.csv @@ -0,0 +1,7 @@ +Catálogo Objeto impuesto.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_ObjetoImp,Descripción,Fecha inicio de vigencia,Fecha fin de vigencia,,,,,,,, +01,No objeto de impuesto.,2022-01-01,,,,,,,,, +02,Sí objeto de impuesto.,2022-01-01,,,,,,,,, +03,Sí objeto del impuesto y no obligado al desglose.,2022-01-01,,,,,,,,, diff --git a/tests/_files/cfdi40/c_Pais.csv b/tests/_files/cfdi40/c_Pais.csv new file mode 100644 index 0000000..45f6f71 --- /dev/null +++ b/tests/_files/cfdi40/c_Pais.csv @@ -0,0 +1,254 @@ +Catálogo de países.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_Pais,Descripción,Formato de código postal,Formato de Registro de Identidad Tributaria,Validación del Registro de Identidad Tributaria,Agrupaciones,,,,,, +AFG,Afganistán,,,,,,,,,, +ALA,Islas Åland,,,,,,,,,, +ALB,Albania,,,,,,,,,, +DEU,Alemania,,,,Unión Europea,,,,,, +AND,Andorra,,,,,,,,,, +AGO,Angola,,,,,,,,,, +AIA,Anguila,,,,,,,,,, +ATA,Antártida,,,,,,,,,, +ATG,Antigua y Barbuda,,,,,,,,,, +SAU,Arabia Saudita,,,,,,,,,, +DZA,Argelia,,,,,,,,,, +ARG,Argentina,,,,,,,,,, +ARM,Armenia,,,,,,,,,, +ABW,Aruba,,,,,,,,,, +AUS,Australia,,,,,,,,,, +AUT,Austria,,,,Unión Europea,,,,,, +AZE,Azerbaiyán,,,,,,,,,, +BHS,Bahamas (las),,,,,,,,,, +BGD,Bangladés,,,,,,,,,, +BRB,Barbados,,,,,,,,,, +BHR,Baréin,,,,,,,,,, +BEL,Bélgica,,,,Unión Europea,,,,,, +BLZ,Belice,,,,,,,,,, +BEN,Benín,,,,,,,,,, +BMU,Bermudas,,,,,,,,,, +BLR,Bielorrusia,,,,,,,,,, +MMR,Myanmar,,,,,,,,,, +BOL,"Bolivia, Estado Plurinacional de",,,,,,,,,, +BIH,Bosnia y Herzegovina,,,,,,,,,, +BWA,Botsuana,,,,,,,,,, +BRA,Brasil,,,,,,,,,, +BRN,Brunéi Darussalam,,,,,,,,,, +BGR,Bulgaria,,,,Unión Europea,,,,,, +BFA,Burkina Faso,,,,,,,,,, +BDI,Burundi,,,,,,,,,, +BTN,Bután,,,,,,,,,, +CPV,Cabo Verde,,,,,,,,,, +KHM,Camboya,,,,,,,,,, +CMR,Camerún,,,,,,,,,, +CAN,Canadá,[A-Z][0-9][A-Z] [0-9][A-Z][0-9],[0-9]{9},,TLCAN,,,,,, +QAT,Catar,,,,,,,,,, +BES,"Bonaire, San Eustaquio y Saba",,,,,,,,,, +TCD,Chad,,,,,,,,,, +CHL,Chile,,,,,,,,,, +CHN,China,,,,,,,,,, +CYP,Chipre,,,,Unión Europea,,,,,, +COL,Colombia,,,,,,,,,, +COM,Comoras,,,,,,,,,, +PRK,Corea (la República Democrática Popular de),,,,,,,,,, +KOR,Corea (la República de),,,,,,,,,, +CIV,Côte d'Ivoire,,,,,,,,,, +CRI,Costa Rica,,,,,,,,,, +HRV,Croacia,,,,Unión Europea,,,,,, +CUB,Cuba,,,,,,,,,, +CUW,Curaçao,,,,,,,,,, +DNK,Dinamarca,,,,Unión Europea,,,,,, +DMA,Dominica,,,,,,,,,, +ECU,Ecuador,,,,,,,,,, +EGY,Egipto,,,,,,,,,, +SLV,El Salvador,,,,,,,,,, +ARE,Emiratos Árabes Unidos (Los),,,,,,,,,, +ERI,Eritrea,,,,,,,,,, +SVK,Eslovaquia,,,,Unión Europea,,,,,, +SVN,Eslovenia,,,,Unión Europea,,,,,, +ESP,España,,,,Unión Europea,,,,,, +USA,Estados Unidos (los),[0-9]{5}(-[0-9]{4})?,[0-9]{9},,TLCAN,,,,,, +EST,Estonia,,,,Unión Europea,,,,,, +ETH,Etiopía,,,,,,,,,, +PHL,Filipinas (las),,,,,,,,,, +FIN,Finlandia,,,,Unión Europea,,,,,, +FJI,Fiyi,,,,,,,,,, +FRA,Francia,,,,Unión Europea,,,,,, +GAB,Gabón,,,,,,,,,, +GMB,Gambia (La),,,,,,,,,, +GEO,Georgia,,,,,,,,,, +GHA,Ghana,,,,,,,,,, +GIB,Gibraltar,,,,,,,,,, +GRD,Granada,,,,,,,,,, +GRC,Grecia,,,,Unión Europea,,,,,, +GRL,Groenlandia,,,,,,,,,, +GLP,Guadalupe,,,,,,,,,, +GUM,Guam,,,,,,,,,, +GTM,Guatemala,,,,,,,,,, +GUF,Guayana Francesa,,,,,,,,,, +GGY,Guernsey,,,,,,,,,, +GIN,Guinea,,,,,,,,,, +GNB,Guinea-Bisáu,,,,,,,,,, +GNQ,Guinea Ecuatorial,,,,,,,,,, +GUY,Guyana,,,,,,,,,, +HTI,Haití,,,,,,,,,, +HND,Honduras,,,,,,,,,, +HKG,Hong Kong,,,,,,,,,, +HUN,Hungría,,,,Unión Europea,,,,,, +IND,India,,,,,,,,,, +IDN,Indonesia,,,,,,,,,, +IRQ,Irak,,,,,,,,,, +IRN,Irán (la República Islámica de),,,,,,,,,, +IRL,Irlanda,,,,Unión Europea,,,,,, +BVT,Isla Bouvet,,,,,,,,,, +IMN,Isla de Man,,,,,,,,,, +CXR,Isla de Navidad,,,,,,,,,, +NFK,Isla Norfolk,,,,,,,,,, +ISL,Islandia,,,,,,,,,, +CYM,Islas Caimán (las),,,,,,,,,, +CCK,Islas Cocos (Keeling),,,,,,,,,, +COK,Islas Cook (las),,,,,,,,,, +FRO,Islas Feroe (las),,,,,,,,,, +SGS,Georgia del sur y las islas sandwich del sur,,,,,,,,,, +HMD,Isla Heard e Islas McDonald,,,,,,,,,, +FLK,Islas Malvinas [Falkland] (las),,,,,,,,,, +MNP,Islas Marianas del Norte (las),,,,,,,,,, +MHL,Islas Marshall (las),,,,,,,,,, +PCN,Pitcairn,,,,,,,,,, +SLB,Islas Salomón (las),,,,,,,,,, +TCA,Islas Turcas y Caicos (las),,,,,,,,,, +UMI,Islas de Ultramar Menores de Estados Unidos (las),,,,,,,,,, +VGB,Islas Vírgenes (Británicas),,,,,,,,,, +VIR,Islas Vírgenes (EE.UU.),,,,,,,,,, +ISR,Israel,,,,,,,,,, +ITA,Italia,,,,Unión Europea,,,,,, +JAM,Jamaica,,,,,,,,,, +JPN,Japón,,,,,,,,,, +JEY,Jersey,,,,,,,,,, +JOR,Jordania,,,,,,,,,, +KAZ,Kazajistán,,,,,,,,,, +KEN,Kenia,,,,,,,,,, +KGZ,Kirguistán,,,,,,,,,, +KIR,Kiribati,,,,,,,,,, +KWT,Kuwait,,,,,,,,,, +LAO,"Lao, (la) República Democrática Popular",,,,,,,,,, +LSO,Lesoto,,,,,,,,,, +LVA,Letonia,,,,Unión Europea,,,,,, +LBN,Líbano,,,,,,,,,, +LBR,Liberia,,,,,,,,,, +LBY,Libia,,,,,,,,,, +LIE,Liechtenstein,,,,,,,,,, +LTU,Lituania,,,,Unión Europea,,,,,, +LUX,Luxemburgo,,,,Unión Europea,,,,,, +MAC,Macao,,,,,,,,,, +MDG,Madagascar,,,,,,,,,, +MYS,Malasia,,,,,,,,,, +MWI,Malaui,,,,,,,,,, +MDV,Maldivas,,,,,,,,,, +MLI,Malí,,,,,,,,,, +MLT,Malta,,,,Unión Europea,,,,,, +MAR,Marruecos,,,,,,,,,, +MTQ,Martinica,,,,,,,,,, +MUS,Mauricio,,,,,,,,,, +MRT,Mauritania,,,,,,,,,, +MYT,Mayotte,,,,,,,,,, +MEX,México,[0-9]{5},"[A-Z&Ñ]{3,4}[0-9]{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])[A-Z0-9]{2}[0\n-9A]",Lista del SAT,TLCAN,,,,,, +FSM,Micronesia (los Estados Federados de),,,,,,,,,, +MDA,Moldavia (la República de),,,,,,,,,, +MCO,Mónaco,,,,,,,,,, +MNG,Mongolia,,,,,,,,,, +MNE,Montenegro,,,,,,,,,, +MSR,Montserrat,,,,,,,,,, +MOZ,Mozambique,,,,,,,,,, +NAM,Namibia,,,,,,,,,, +NRU,Nauru,,,,,,,,,, +NPL,Nepal,,,,,,,,,, +NIC,Nicaragua,,,,,,,,,, +NER,Níger (el),,,,,,,,,, +NGA,Nigeria,,,,,,,,,, +NIU,Niue,,,,,,,,,, +NOR,Noruega,,,,,,,,,, +NCL,Nueva Caledonia,,,,,,,,,, +NZL,Nueva Zelanda,,,,,,,,,, +OMN,Omán,,,,,,,,,, +NLD,Países Bajos (los),,,,Unión Europea,,,,,, +PAK,Pakistán,,,,,,,,,, +PLW,Palaos,,,,,,,,,, +PSE,"Palestina, Estado de",,,,,,,,,, +PAN,Panamá,,,,,,,,,, +PNG,Papúa Nueva Guinea,,,,,,,,,, +PRY,Paraguay,,,,,,,,,, +PER,Perú,,,,,,,,,, +PYF,Polinesia Francesa,,,,,,,,,, +POL,Polonia,,,,Unión Europea,,,,,, +PRT,Portugal,,,,Unión Europea,,,,,, +PRI,Puerto Rico,,,,,,,,,, +GBR,Reino Unido (el),,,,Unión Europea,,,,,, +CAF,República Centroafricana (la),,,,,,,,,, +CZE,República Checa (la),,,,Unión Europea,,,,,, +MKD,Macedonia (la antigua República Yugoslava de),,,,,,,,,, +COG,Congo,,,,,,,,,, +COD,Congo (la República Democrática del),,,,,,,,,, +DOM,República Dominicana (la),,,,,,,,,, +REU,Reunión,,,,,,,,,, +RWA,Ruanda,,,,,,,,,, +ROU,Rumania,,,,Unión Europea,,,,,, +RUS,"Rusia, (la) Federación de",,,,,,,,,, +ESH,Sahara Occidental,,,,,,,,,, +WSM,Samoa,,,,,,,,,, +ASM,Samoa Americana,,,,,,,,,, +BLM,San Bartolomé,,,,,,,,,, +KNA,San Cristóbal y Nieves,,,,,,,,,, +SMR,San Marino,,,,,,,,,, +MAF,San Martín (parte francesa),,,,,,,,,, +SPM,San Pedro y Miquelón,,,,,,,,,, +VCT,San Vicente y las Granadinas,,,,,,,,,, +SHN,"Santa Helena, Ascensión y Tristán de Acuña",,,,,,,,,, +LCA,Santa Lucía,,,,,,,,,, +STP,Santo Tomé y Príncipe,,,,,,,,,, +SEN,Senegal,,,,,,,,,, +SRB,Serbia,,,,,,,,,, +SYC,Seychelles,,,,,,,,,, +SLE,Sierra leona,,,,,,,,,, +SGP,Singapur,,,,,,,,,, +SXM,Sint Maarten (parte holandesa),,,,,,,,,, +SYR,"Siria, (la) República Árabe",,,,,,,,,, +SOM,Somalia,,,,,,,,,, +LKA,Sri Lanka,,,,,,,,,, +SWZ,Suazilandia,,,,,,,,,, +ZAF,Sudáfrica,,,,,,,,,, +SDN,Sudán (el),,,,,,,,,, +SSD,Sudán del Sur,,,,,,,,,, +SWE,Suecia,,,,Unión Europea,,,,,, +CHE,Suiza,,,,,,,,,, +SUR,Surinam,,,,,,,,,, +SJM,Svalbard y Jan Mayen,,,,,,,,,, +THA,Tailandia,,,,,,,,,, +TWN,Taiwán (Provincia de China),,,,,,,,,, +TZA,"Tanzania, República Unida de",,,,,,,,,, +TJK,Tayikistán,,,,,,,,,, +IOT,Territorio Británico del Océano Índico (el),,,,,,,,,, +ATF,Territorios Australes Franceses (los),,,,,,,,,, +TLS,Timor-Leste,,,,,,,,,, +TGO,Togo,,,,,,,,,, +TKL,Tokelau,,,,,,,,,, +TON,Tonga,,,,,,,,,, +TTO,Trinidad y Tobago,,,,,,,,,, +TUN,Túnez,,,,,,,,,, +TKM,Turkmenistán,,,,,,,,,, +TUR,Turquía,,,,,,,,,, +TUV,Tuvalu,,,,,,,,,, +UKR,Ucrania,,,,,,,,,, +UGA,Uganda,,,,,,,,,, +URY,Uruguay,,,,,,,,,, +UZB,Uzbekistán,,,,,,,,,, +VUT,Vanuatu,,,,,,,,,, +VAT,Santa Sede[Estado de la Ciudad del Vaticano] (la),,,,,,,,,, +VEN,"Venezuela, República Bolivariana de",,,,,,,,,, +VNM,Viet Nam,,,,,,,,,, +WLF,Wallis y Futuna,,,,,,,,,, +YEM,Yemen,,,,,,,,,, +DJI,Yibuti,,,,,,,,,, +ZMB,Zambia,,,,,,,,,, +ZWE,Zimbabue,,,,,,,,,, +ZZZ,Países no declarados,,,,,,,,,, diff --git a/tests/_files/cfdi40/c_PatenteAduanal.csv b/tests/_files/cfdi40/c_PatenteAduanal.csv new file mode 100644 index 0000000..5839c8a --- /dev/null +++ b/tests/_files/cfdi40/c_PatenteAduanal.csv @@ -0,0 +1,232 @@ +Catálogo de patentes aduanales,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,, +C_PatenteAduanal,Inicio de vigencia de la patente,Fin de vigencia de la patente,,,,,,,, +0000,2000-01-01,,,,,,,,, +0074,2001-07-03,,,,,,,,, +0101,2001-05-21,,,,,,,,, +0115,2001-05-17,,,,,,,,, +0122,2001-05-14,,,,,,,,, +0123,2001-05-16,,,,,,,,, +0149,2001-05-21,,,,,,,,, +0150,2001-05-22,,,,,,,,, +0182,2001-05-21,,,,,,,,, +0188,2001-05-23,,,,,,,,, +0203,2001-05-18,,,,,,,,, +0205,2001-05-21,,,,,,,,, +0227,2001-05-17,,,,,,,,, +0246,2001-05-21,,,,,,,,, +0247,2001-05-23,,,,,,,,, +0271,2001-07-31,,,,,,,,, +0273,2001-05-11,,,,,,,,, +0276,2001-06-21,,,,,,,,, +0289,2001-05-17,,,,,,,,, +0294,2001-05-21,,,,,,,,, +0309,2001-05-21,,,,,,,,, +0310,2001-05-23,,,,,,,,, +0312,2001-05-14,,,,,,,,, +0316,2001-05-21,,,,,,,,, +0318,2001-07-31,,,,,,,,, +0321,2001-05-18,,,,,,,,, +0323,2001-05-18,,,,,,,,, +0327,2001-05-21,,,,,,,,, +0328,2001-05-18,,,,,,,,, +0334,2001-05-14,,,,,,,,, +0339,2001-05-15,,,,,,,,, +0347,2001-05-21,,,,,,,,, +0348,2001-05-15,,,,,,,,, +0350,2001-05-17,,,,,,,,, +0361,2001-06-12,,,,,,,,, +0368,2001-05-15,,,,,,,,, +0381,2001-05-16,,,,,,,,, +0382,2001-05-17,,,,,,,,, +0387,2001-05-22,,,,,,,,, +0388,2001-05-17,,,,,,,,, +0389,2001-05-21,,,,,,,,, +0390,2001-08-01,,,,,,,,, +0394,2001-05-18,,,,,,,,, +0398,2001-06-15,,,,,,,,, +0400,2001-05-22,,,,,,,,, +0401,2001-06-12,,,,,,,,, +0403,2001-05-16,,,,,,,,, +0404,2001-05-22,,,,,,,,, +0406,2001-05-21,,,,,,,,, +0407,2001-05-18,,,,,,,,, +0411,2001-07-31,,,,,,,,, +0412,2001-05-08,,,,,,,,, +0413,2001-05-15,,,,,,,,, +0414,2001-05-21,,,,,,,,, +0418,2001-05-18,,,,,,,,, +0419,2001-05-17,,,,,,,,, +0420,2001-05-16,,,,,,,,, +0424,2001-05-21,,,,,,,,, +0425,2001-05-16,,,,,,,,, +0426,2001-05-21,,,,,,,,, +0427,2001-05-16,,,,,,,,, +0428,2001-06-08,,,,,,,,, +0429,2001-05-18,,,,,,,,, +0430,2001-05-22,,,,,,,,, +0432,2001-06-18,,,,,,,,, +0438,2001-05-15,,,,,,,,, +0440,2001-05-18,,,,,,,,, +0441,2001-10-19,,,,,,,,, +0442,2001-05-22,,,,,,,,, +0444,2001-05-18,,,,,,,,, +0445,2001-05-18,,,,,,,,, +0447,2001-05-23,,,,,,,,, +0449,2001-05-21,,,,,,,,, +0451,2001-05-11,,,,,,,,, +0454,2001-06-29,,,,,,,,, +0457,2001-05-21,,,,,,,,, +0460,2001-05-21,,,,,,,,, +0462,2001-05-15,,,,,,,,, +0464,2001-05-21,,,,,,,,, +0465,2001-05-17,,,,,,,,, +0467,2001-05-15,,,,,,,,, +0469,2001-05-21,,,,,,,,, +0472,2001-05-16,,,,,,,,, +0474,2002-07-01,,,,,,,,, +0476,2001-05-22,,,,,,,,, +0477,2001-05-18,,,,,,,,, +0478,2001-05-22,,,,,,,,, +0480,2001-05-14,,,,,,,,, +0481,2001-05-21,,,,,,,,, +0482,2001-05-15,,,,,,,,, +0483,2001-05-15,,,,,,,,, +0485,2001-05-18,,,,,,,,, +0486,2001-05-18,,,,,,,,, +0487,2001-05-22,,,,,,,,, +0489,2001-05-18,,,,,,,,, +0491,2001-05-18,,,,,,,,, +0492,2001-05-14,,,,,,,,, +0493,2001-05-21,,,,,,,,, +0494,2001-08-23,,,,,,,,, +0496,2001-05-18,,,,,,,,, +0498,2001-05-23,,,,,,,,, +0499,2001-05-15,,,,,,,,, +0500,2001-05-14,,,,,,,,, +0501,2001-05-16,,,,,,,,, +0503,2001-05-15,,,,,,,,, +0504,2001-05-11,,,,,,,,, +0506,2001-05-14,,,,,,,,, +0508,2001-05-21,,,,,,,,, +6124,2019-04-29,,,,,,,,, +6125,2019-04-29,,,,,,,,, +6126,2019-05-08,,,,,,,,, +6127,2019-06-20,,,,,,,,, +6128,2019-05-08,,,,,,,,, +6129,2019-06-05,,,,,,,,, +6130,2019-06-21,,,,,,,,, +6131,2019-08-26,,,,,,,,, +6133,2019-08-26,,,,,,,,, +6134,2019-06-21,,,,,,,,, +6135,2019-11-11,,,,,,,,, +6136,2019-10-10,,,,,,,,, +6141,2020-07-20,,,,,,,,, +6143,2021-07-20,,,,,,,,, +7001,2006-10-19,,,,,,,,, +7002,2006-11-08,,,,,,,,, +7003,2007-01-23,,,,,,,,, +7004,2007-02-26,,,,,,,,, +7005,2008-10-29,,,,,,,,, +7006,2007-08-10,,,,,,,,, +7007,2007-09-26,,,,,,,,, +7008,2008-01-30,,,,,,,,, +7009,2008-08-12,,,,,,,,, +7010,2008-10-03,,,,,,,,, +7011,2008-08-26,,,,,,,,, +7012,2008-09-18,,,,,,,,, +7013,2008-09-18,,,,,,,,, +7014,2009-01-20,,,,,,,,, +7015,2008-10-10,,,,,,,,, +7016,2009-03-03,,,,,,,,, +7017,2009-08-06,,,,,,,,, +7018,2010-12-01,,,,,,,,, +7019,2009-11-19,,,,,,,,, +7020,2009-11-03,,,,,,,,, +7021,2009-11-19,,,,,,,,, +7022,2010-02-15,,,,,,,,, +7023,2010-03-08,,,,,,,,, +7024,2010-09-09,,,,,,,,, +7025,2010-12-10,,,,,,,,, +7026,2011-02-14,,,,,,,,, +7027,2011-03-23,,,,,,,,, +7028,2011-03-24,,,,,,,,, +7029,2011-05-24,,,,,,,,, +7030,2011-06-06,,,,,,,,, +7031,2011-09-22,,,,,,,,, +7032,2011-09-21,,,,,,,,, +7033,2012-01-31,,,,,,,,, +7034,2012-02-10,,,,,,,,, +7035,2012-01-12,,,,,,,,, +7036,2012-03-05,,,,,,,,, +7037,2012-06-14,,,,,,,,, +7038,2012-07-12,,,,,,,,, +7039,2012-12-19,,,,,,,,, +7041,2013-08-20,,,,,,,,, +7042,2013-12-12,,,,,,,,, +7043,2013-12-11,,,,,,,,, +7044,2014-01-06,,,,,,,,, +7602,2008-11-21,,,,,,,,, +7603,2009-08-05,,,,,,,,, +7604,2010-08-04,,,,,,,,, +7605,2011-02-14,,,,,,,,, +7606,2012-01-02,,,,,,,,, +7607,2012-01-26,,,,,,,,, +7608,2014-05-12,,,,,,,,, +7609,2016-06-21,,,,,,,,, +7610,2017-01-25,,,,,,,,, +9001,2002-01-03,,,,,,,,, +9002,2002-01-03,,,,,,,,, +9003,2002-01-03,,,,,,,,, +9004,2002-01-03,,,,,,,,, +9005,2002-01-03,,,,,,,,, +9006,2002-01-03,,,,,,,,, +9007,2002-01-03,,,,,,,,, +9008,2002-01-03,,,,,,,,, +9009,2002-01-03,,,,,,,,, +9010,2002-01-03,,,,,,,,, +9011,2002-01-03,,,,,,,,, +9012,2002-01-03,,,,,,,,, +9013,2002-01-03,,,,,,,,, +9014,2002-01-03,,,,,,,,, +9015,2002-01-03,,,,,,,,, +9016,2002-01-03,,,,,,,,, +9017,2002-01-03,,,,,,,,, +9018,2002-01-03,,,,,,,,, +9019,2002-01-03,,,,,,,,, +9020,2002-01-03,,,,,,,,, +9021,2002-01-07,,,,,,,,, +9022,2002-01-07,,,,,,,,, +9023,2002-01-07,,,,,,,,, +9024,2002-01-07,,,,,,,,, +9025,2002-01-07,,,,,,,,, +9026,2002-01-07,,,,,,,,, +9027,2002-01-07,,,,,,,,, +9028,2002-08-20,,,,,,,,, +9029,2002-01-07,,,,,,,,, +9030,2002-01-07,,,,,,,,, +9031,2002-01-07,,,,,,,,, +9033,2002-01-07,,,,,,,,, +9034,2002-01-07,,,,,,,,, +9035,2002-08-28,,,,,,,,, +9037,2002-01-07,,,,,,,,, +9038,2002-01-07,,,,,,,,, +9039,2002-08-12,,,,,,,,, +9040,2002-01-07,,,,,,,,, +9041,2002-01-07,,,,,,,,, +9042,2002-01-07,,,,,,,,, +9043,2002-01-07,,,,,,,,, +9044,2002-01-07,,,,,,,,, +9045,2002-01-07,,,,,,,,, +9046,2002-01-07,,,,,,,,, +9047,2002-01-07,,,,,,,,, +9048,2002-08-29,,,,,,,,, +9049,2002-01-07,,,,,,,,, +9050,2002-01-07,,,,,,,,, +9051,2002-11-26,,,,,,,,, +9052,2003-07-11,,,,,,,,, +9053,2008-08-05,,,,,,,,, +9054,2012-04-26,,,,,,,,, +9055,2017-03-08,,,,,,,,, +9999,2011-03-02,,,,,,,,, diff --git a/tests/_files/cfdi40/c_Periodicidad.csv b/tests/_files/cfdi40/c_Periodicidad.csv new file mode 100644 index 0000000..8e5ba33 --- /dev/null +++ b/tests/_files/cfdi40/c_Periodicidad.csv @@ -0,0 +1,9 @@ +Catálogo periodicidad.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_Periodicidad,Descripción,Fecha inicio de vigencia,Fecha fin de vigencia,,,,,,,, +01,Diario,2022-01-01,,,,,,,,, +02,Semanal,2022-01-01,,,,,,,,, +03,Quincenal,2022-01-01,,,,,,,,, +04,Mensual,2022-01-01,,,,,,,,, +05,Bimestral,2022-01-01,,,,,,,,, diff --git a/tests/_files/cfdi40/c_RegimenFiscal.csv b/tests/_files/cfdi40/c_RegimenFiscal.csv new file mode 100644 index 0000000..bd43857 --- /dev/null +++ b/tests/_files/cfdi40/c_RegimenFiscal.csv @@ -0,0 +1,24 @@ +Catálogo de Régimen Fiscal.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +,,Aplica para tipo persona,,,,,,,,, +c_RegimenFiscal,Descripción,Física,Moral,Fecha de inicio de vigencia,Fecha de fin de vigencia,,,,,, +601,General de Ley Personas Morales,No,Sí,2022-01-01,,,,,,, +603,Personas Morales con Fines no Lucrativos,No,Sí,2022-01-01,,,,,,, +605,Sueldos y Salarios e Ingresos Asimilados a Salarios,Sí,No,2022-01-01,,,,,,, +606,Arrendamiento,Sí,No,2022-01-01,,,,,,, +607,Régimen de Enajenación o Adquisición de Bienes,Sí,No,2022-01-01,,,,,,, +608,Demás ingresos,Sí,No,2022-01-01,,,,,,, +610,Residentes en el Extranjero sin Establecimiento Permanente en México,Sí,Sí,2022-01-01,,,,,,, +611,Ingresos por Dividendos (socios y accionistas),Sí,No,2022-01-01,,,,,,, +612,Personas Físicas con Actividades Empresariales y Profesionales,Sí,No,2022-01-01,,,,,,, +614,Ingresos por intereses,Sí,No,2022-01-01,,,,,,, +615,Régimen de los ingresos por obtención de premios,Sí,No,2022-01-01,,,,,,, +616,Sin obligaciones fiscales,Sí,No,2022-01-01,,,,,,, +620,Sociedades Cooperativas de Producción que optan por diferir sus ingresos,No,Sí,2022-01-01,,,,,,, +621,Incorporación Fiscal,Sí,No,2022-01-01,,,,,,, +622,"Actividades Agrícolas, Ganaderas, Silvícolas y Pesqueras",No,Sí,2022-01-01,,,,,,, +623,Opcional para Grupos de Sociedades,No,Sí,2022-01-01,,,,,,, +624,Coordinados,No,Sí,2022-01-01,,,,,,, +625,Régimen de las Actividades Empresariales con ingresos a través de Plataformas Tecnológicas,Sí,No,2022-01-01,,,,,,, +626,Régimen Simplificado de Confianza,Sí,Sí,2022-01-01,,,,,,, diff --git a/tests/_files/cfdi40/c_TasaOCuota.csv b/tests/_files/cfdi40/c_TasaOCuota.csv new file mode 100644 index 0000000..6462f3b --- /dev/null +++ b/tests/_files/cfdi40/c_TasaOCuota.csv @@ -0,0 +1,24 @@ +Catálogo de tasas o cuotas de impuestos.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +Rango o Fijo,c_TasaOCuota,,Impuesto,Factor,Traslado,Retención,Fecha inicio de vigencia,Fecha fin de vigencia,,, +,Valor mínimo,Valor máximo,,,,,,,,, +Fijo,,0,IVA,Tasa,Sí,No,2022-01-01,,,, +Fijo,,0.16,IVA,Tasa,Sí,No,2022-01-01,,,, +Rango,0,0.16,IVA,Tasa,No,Sí,2022-01-01,,,, +Fijo,,0.08,IVA Crédito aplicado del 50%,Tasa,Sí,No,2022-01-01,,,, +Fijo,,0.265,IEPS,Tasa,Sí,Sí,2022-01-01,,,, +Fijo,,0.3,IEPS,Tasa,Sí,Sí,2022-01-01,,,, +Fijo,,0.53,IEPS,Tasa,Sí,Sí,2022-01-01,,,, +Fijo,,0.5,IEPS,Tasa,Sí,Sí,2022-01-01,,,, +Fijo,,1.6,IEPS,Tasa,Sí,Sí,2022-01-01,,,, +Fijo,,0.304,IEPS,Tasa,Sí,Sí,2022-01-01,,,, +Fijo,,0.25,IEPS,Tasa,Sí,Sí,2022-01-01,,,, +Fijo,,0.09,IEPS,Tasa,Sí,Sí,2022-01-01,,,, +Fijo,,0.08,IEPS,Tasa,Sí,Sí,2022-01-01,,,, +Fijo,,0.07,IEPS,Tasa,Sí,Sí,2022-01-01,,,, +Fijo,,0.06,IEPS,Tasa,Sí,Sí,2022-01-01,,,, +Fijo,,0.03,IEPS,Tasa,Sí,No,2022-01-01,,,, +Fijo,,0,IEPS,Tasa,Sí,No,2022-01-01,,,, +Rango,0,59.1449,IEPS,Cuota,Sí,Sí,2022-01-01,,,, +Rango,0,0.35,ISR,Tasa,No,Sí,2022-01-01,,,, diff --git a/tests/_files/cfdi40/c_TipoDeComprobante.csv b/tests/_files/cfdi40/c_TipoDeComprobante.csv new file mode 100644 index 0000000..007f7bc --- /dev/null +++ b/tests/_files/cfdi40/c_TipoDeComprobante.csv @@ -0,0 +1,10 @@ +Catálogo de tipos de comprobante.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_TipoDeComprobante,Descripción,Valor máximo,,Fecha inicio de vigencia,Fecha fin de vigencia,,,,,, +I,Ingreso,999999999999999999.999999,,2022-01-01,,,,,,, +E,Egreso,999999999999999999.999999,,2022-01-01,,,,,,, +T,Traslado,0,,2022-01-01,,,,,,, +N,Nómina,NS,NdS,2022-01-01,,,,,,, +,,999999999999999999.999999,999999999999999999.999999,2022-01-01,,,,,,, +P,Pago,999999999999999999.999999,,2022-01-01,,,,,,, diff --git a/tests/_files/cfdi40/c_TipoFactor.csv b/tests/_files/cfdi40/c_TipoFactor.csv new file mode 100644 index 0000000..0aa4f45 --- /dev/null +++ b/tests/_files/cfdi40/c_TipoFactor.csv @@ -0,0 +1,7 @@ +Catálogo tipo factor.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_TipoFactor,Fecha inicio de vigencia,Fecha fin de vigencia,,,,,,,,, +Tasa,2022-01-01,,,,,,,,,, +Cuota,2022-01-01,,,,,,,,,, +Exento,2022-01-01,,,,,,,,,, diff --git a/tests/_files/cfdi40/c_TipoRelacion.csv b/tests/_files/cfdi40/c_TipoRelacion.csv new file mode 100644 index 0000000..4fb4a22 --- /dev/null +++ b/tests/_files/cfdi40/c_TipoRelacion.csv @@ -0,0 +1,11 @@ +Catálogo de tipos de relación entre CFDI.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_TipoRelacion,Descripción,Fecha inicio de vigencia,Fecha fin de vigencia,,,,,,,, +1,Nota de crédito de los documentos relacionados,2022-01-01,,,,,,,,, +2,Nota de débito de los documentos relacionados,2022-01-01,,,,,,,,, +3,Devolución de mercancía sobre facturas o traslados previos,2022-01-01,,,,,,,,, +4,Sustitución de los CFDI previos,2022-01-01,,,,,,,,, +5,Traslados de mercancías facturados previamente,2022-01-01,,,,,,,,, +6,Factura generada por los traslados previos,2022-01-01,,,,,,,,, +7,CFDI por aplicación de anticipo,2022-01-01,,,,,,,,, diff --git a/tests/_files/cfdi40/c_UsoCFDI.csv b/tests/_files/cfdi40/c_UsoCFDI.csv new file mode 100644 index 0000000..459f69e --- /dev/null +++ b/tests/_files/cfdi40/c_UsoCFDI.csv @@ -0,0 +1,29 @@ +Catálogo de uso de comprobantes.,,,,,,,,,,, +Versión CFDI,Versión catálogo,Revisión catálogo,Fecha publicación de catálogo,Fecha inicio de vigencia del catálogo,Fecha fin de vigencia del catálogo,,,,,, +4.0,1.0,0,0,2022-01-01,,,,,,, +c_UsoCFDI,Descripción,Aplica para tipo persona,,Fecha inicio de vigencia,Fecha fin de vigencia,Regímen Fiscal Receptor,,,,, +,,Física,Moral,,,,,,,, +G01,Adquisición de mercancías.,Sí,Sí,2022-01-01,,"601, 603, 606, 612, 620, 621, 622, 623, 624, 625,626",,,,, +G02,"Devoluciones, descuentos o bonificaciones.",Sí,Sí,2022-01-01,,"601, 603, 606, 612, 620, 621, 622, 623, 624, 625,626",,,,, +G03,Gastos en general.,Sí,Sí,2022-01-01,,"601, 603, 606, 612, 620, 621, 622, 623, 624, 625, 626",,,,, +I01,Construcciones.,Sí,Sí,2022-01-01,,"601, 603, 606, 612, 620, 621, 622, 623, 624, 625, 626",,,,, +I02,Mobiliario y equipo de oficina por inversiones.,Sí,Sí,2022-01-01,,"601, 603, 606, 612, 620, 621, 622, 623, 624, 625, 626",,,,, +I03,Equipo de transporte.,Sí,Sí,2022-01-01,,"601, 603, 606, 612, 620, 621, 622, 623, 624, 625, 626",,,,, +I04,Equipo de computo y accesorios.,Sí,Sí,2022-01-01,,"601, 603, 606, 612, 620, 621, 622, 623, 624, 625, 626",,,,, +I05,"Dados, troqueles, moldes, matrices y herramental.",Sí,Sí,2022-01-01,,"601, 603, 606, 612, 620, 621, 622, 623, 624, 625, 626",,,,, +I06,Comunicaciones telefónicas.,Sí,Sí,2022-01-01,,"601, 603, 606, 612, 620, 621, 622, 623, 624, 625, 626",,,,, +I07,Comunicaciones satelitales.,Sí,Sí,2022-01-01,,"601, 603, 606, 612, 620, 621, 622, 623, 624, 625, 626",,,,, +I08,Otra maquinaria y equipo.,Sí,Sí,2022-01-01,,"601, 603, 606, 612, 620, 621, 622, 623, 624, 625, 626",,,,, +D01,"Honorarios médicos, dentales y gastos hospitalarios.",Sí,No,2022-01-01,,"605, 606, 608, 611, 612, 614, 607, 615, 625",,,,, +D02,Gastos médicos por incapacidad o discapacidad.,Sí,No,2022-01-01,,"605, 606, 608, 611, 612, 614, 607, 615, 625",,,,, +D03,Gastos funerales.,Sí,No,2022-01-01,,"605, 606, 608, 611, 612, 614, 607, 615, 625",,,,, +D04,Donativos.,Sí,No,2022-01-01,,"605, 606, 608, 611, 612, 614, 607, 615, 625",,,,, +D05,Intereses reales efectivamente pagados por créditos hipotecarios (casa habitación).,Sí,No,2022-01-01,,"605, 606, 608, 611, 612, 614, 607, 615, 625",,,,, +D06,Aportaciones voluntarias al SAR.,Sí,No,2022-01-01,,"605, 606, 608, 611, 612, 614, 607, 615, 625",,,,, +D07,Primas por seguros de gastos médicos.,Sí,No,2022-01-01,,"605, 606, 608, 611, 612, 614, 607, 615, 625",,,,, +D08,Gastos de transportación escolar obligatoria.,Sí,No,2022-01-01,,"605, 606, 608, 611, 612, 614, 607, 615, 625",,,,, +D09,"Depósitos en cuentas para el ahorro, primas que tengan como base planes de pensiones.",Sí,No,2022-01-01,,"605, 606, 608, 611, 612, 614, 607, 615, 625",,,,, +D10,Pagos por servicios educativos (colegiaturas).,Sí,No,2022-01-01,,"605, 606, 608, 611, 612, 614, 607, 615, 625",,,,, +S01,Sin efectos fiscales. ,Sí,Sí,2022-01-01,,"601, 603, 605, 606, 608, 610, 611, 612, 614, 616, 620, 621, 622, 623, 624, 607, 615, 625, 626",,,,, +CP01,Pagos,Sí,Sí,2022-01-01,,"601, 603, 605, 606, 608, 610, 611, 612, 614, 616, 620, 621, 622, 623, 624, 607, 615, 625, 626",,,,, +CN01,Nómina,Sí,No,2022-01-01,,605,,,,, diff --git a/tests/_files/sources/cfdi_40.xls b/tests/_files/sources/cfdi_40.xls new file mode 100644 index 0000000000000000000000000000000000000000..99873ef056fba4c8ef545095a7bfb29337d9135b GIT binary patch literal 495616 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∾r3z$YjCReYcey`=toB{>JVn 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

nh)iE9Lxz^)P80(Om*qjgJM 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 Date: Sat, 5 Mar 2022 02:45:13 -0600 Subject: [PATCH 4/6] Add cfdi_40.xsl source to SourceImporters --- src/Importers/SourcesImporter.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Importers/SourcesImporter.php b/src/Importers/SourcesImporter.php index 22a057d..e1d723a 100644 --- a/src/Importers/SourcesImporter.php +++ b/src/Importers/SourcesImporter.php @@ -15,6 +15,7 @@ public function import(string $source, Repository $repository, LoggerInterface $ { $importers = [ 'CFDI' => ['source' => $source . '/catCFDI.xls', 'importer' => new CfdiCatalogs()], + 'CFDI 4.0' => ['source' => $source . '/cfdi_40.xls', 'importer' => new Cfdi40Catalogs()], 'Nóminas' => ['source' => $source . '/catNomina.xls', 'importer' => new NominaCatalogs()], 'Nóminas - Estados' => [ 'source' => $source . '/nominas_estados.xls', From 2992a7c02a3702bccc1af940540eb3ca2cb604ca Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Sat, 5 Mar 2022 02:45:45 -0600 Subject: [PATCH 5/6] Update documentation about CFDI 4.0 --- README.md | 4 ++ docs/Catalogos.md | 135 ++++++++++++++++++++++++++++------------------ docs/Pruebas.md | 4 ++ 3 files changed, 92 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index fa9f04d..461f3c9 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,10 @@ php bin/sat-catalogos-update update-origins catalogs/ php bin/sat-catalogos-update update-database catalogs/ catalogs/catalogos.sqlite3 ``` +## About the catalogs included + +Read the file [*Catálogos SAT*](docs/Catalogos.md) for more information about the catalogs included (in spanish). + ## PHP Support This tool is compatible with last [PHP supported version](https://www.php.net/supported-versions.php). diff --git a/docs/Catalogos.md b/docs/Catalogos.md index b26c8ca..88470c2 100644 --- a/docs/Catalogos.md +++ b/docs/Catalogos.md @@ -26,62 +26,95 @@ Para consumir estos catálogos puede usar la librería independiente ## Tabla de catálogos -| Tabla | Origen | Catálogo | Notas | -|-------------------------------|---------------------------|-----------------------|--------------------------------------------------------------------------------------| -| cfdi_aduanas | catCFDI.xls | c_Aduana | | -| cfdi_claves_unidades | catCFDI.xls | c_ClaveUnidad | | -| cfdi_codigos_postales | catCFDI.xls | c_CodigoPostal | Este catálogo viene en dos partes, se relaciona con catálogos de CCE | -| cfdi_formas_pago | catCFDI.xls | c_FormaPago | | -| cfdi_impuestos | catCFDI.xls | c_Impuesto | | -| cfdi_metodos_pago | catCFDI.xls | c_MetodoPago | | -| cfdi_monedas | catCFDI.xls | c_Moneda | | -| cfdi_numeros_pedimento_aduana | catCFDI.xls | c_NumPedimentoAduana | No es un catálogo, es una tabla de reglas, contiene duplicados | -| cfdi_paises | catCFDI.xls | c_Pais | | -| cfdi_patentes_aduanales | catCFDI.xls | c_PatenteAduanal | | -| cfdi_regimenes_fiscales | catCFDI.xls | c_RegimenFiscal | | -| cfdi_productos_servicios | catCFDI.xls | c_ClaveProdServ | | -| cfdi_reglas_tasa_cuota | catCFDI.xls | c_TasaOCuota | No es un catálogo, es una tabla de reglas | -| cfdi_tipos_comprobantes | catCFDI.xls | c_TipoDeComprobante | No se divide el tipo Nómina en Ns y NdS | -| cfdi_tipos_factores | catCFDI.xls | c_TipoFactor | | -| cfdi_tipos_relaciones | catCFDI.xls | c_TipoRelacion | | -| cfdi_usos_cfdi | catCFDI.xls | c_UsoCFDI | | -| cce_claves_pedimentos | c_ClavePedimento.xls | c_ClavePedimento | | -| cce_colonias | c_Colonia.xls | c_Colonia | Viene en 3 partes | -| cce_estados | C_Estado.xls | c_Estado | Estados de México, Estados Unidos y Canadá | -| cce_fracciones_arancelarias | c_FraccionArancelaria.xls | c_FraccionArancelaria | | -| cce_incoterms | c_INCOTERM.xls | c_INCOTERM | | -| cce_localidades | c_Localidad.xls | c_Localidad | | -| cce_localidades | c_Localidad.xls | c_Localidad | | -| cce_motivos_traslado | c_MotivoTraslado.xls | c_MotivoTraslado | | -| cce_municipios | c_Municipio.xls | c_Municipio | | -| cce_tipos_operacion | c_TipoOperacion.xls | c_TipoOperacion | | -| cce_unidades_aduana | c_UnidadAduana.xls | c_UnidadAduana | No confundir con las claves de unidades, estas son las unidades de comercio exterior | -| nominas_bancos | catNomina.xls | c_Banco | | -| nominas_estados | nomina_estados.xls | c_Estado | Es el mismo que el publicado en cce_estados | -| nomina_origenes_recursos | catNomina.xls | c_OrigenRecurso | | -| nomina_periodicidades_pagos | catNomina.xls | c_PeriodicidadPago | | -| nomina_riesgos_puestos | catNomina.xls | | | -| nomina_tipos_contratos | catNomina.xls | c_TipoContrato | | -| nomina_tipos_deducciones | catNomina.xls | c_TipoDeduccion | | -| nomina_tipos_horas | catNomina.xls | c_TipoHoras | | -| nomina_tipos_incapacidades | catNomina.xls | c_TipoIncapacidad | | -| nomina_tipos_jornadas | catNomina.xls | c_TipoJornada | | -| nomina_tipos_nominas | catNomina.xls | c_TipoNomina | | -| nomina_tipos_otros_pagos | catNomina.xls | c_TipoOtroPago | | -| nomina_tipos_percepciones | catNomina.xls | c_TipoPercepcion | | -| nomina_tipos_regimenes | catNomina.xls | c_TipoRegimen | | - -## CFDI - -> - -> - - -Los catálogos de CFDI contienen los catálogos básicos de CFDI versión 3.3. +| Tabla | Origen | Catálogo | Notas | +|----------------------------------|---------------------------|-----------------------|--------------------------------------------------------------------------------------| +| cfdi_aduanas | catCFDI.xls | c_Aduana | | +| cfdi_claves_unidades | catCFDI.xls | c_ClaveUnidad | | +| cfdi_codigos_postales | catCFDI.xls | c_CodigoPostal | Este catálogo viene en dos partes, se relaciona con catálogos de CCE | +| cfdi_formas_pago | catCFDI.xls | c_FormaPago | | +| cfdi_impuestos | catCFDI.xls | c_Impuesto | | +| cfdi_metodos_pago | catCFDI.xls | c_MetodoPago | | +| cfdi_monedas | catCFDI.xls | c_Moneda | | +| cfdi_numeros_pedimento_aduana | catCFDI.xls | c_NumPedimentoAduana | No es un catálogo, es una tabla de reglas, contiene duplicados | +| cfdi_paises | catCFDI.xls | c_Pais | | +| cfdi_patentes_aduanales | catCFDI.xls | c_PatenteAduanal | | +| cfdi_regimenes_fiscales | catCFDI.xls | c_RegimenFiscal | | +| cfdi_productos_servicios | catCFDI.xls | c_ClaveProdServ | | +| cfdi_reglas_tasa_cuota | catCFDI.xls | c_TasaOCuota | No es un catálogo, es una tabla de reglas | +| cfdi_tipos_comprobantes | catCFDI.xls | c_TipoDeComprobante | No se divide el tipo Nómina en Ns y NdS | +| cfdi_tipos_factores | catCFDI.xls | c_TipoFactor | | +| cfdi_tipos_relaciones | catCFDI.xls | c_TipoRelacion | | +| cfdi_usos_cfdi | catCFDI.xls | c_UsoCFDI | | +| cfdi_40_aduanas | cfdi_40.xls | c_Aduana | | +| cfdi_40_claves_unidades | cfdi_40.xls | c_ClaveUnidad | | +| cfdi_40_codigos_postales | cfdi_40.xls | c_CodigoPostal | Este catálogo viene en dos partes, se relaciona con catálogos de CCE | +| cfdi_40_colonias | cfdi_40.xls | C_Colonia | | +| cfdi_40_estados | cfdi_40.xls | c_Estado | | +| cfdi_40_exportaciones | cfdi_40.xls | c_Exportacion | | +| cfdi_40_formas_pago | cfdi_40.xls | c_FormaPago | | +| cfdi_40_impuestos | cfdi_40.xls | c_Impuesto | | +| cfdi_40_localidades | cfdi_40.xls | C_Localidad | | +| cfdi_40_meses | cfdi_40.xls | c_Meses | | +| cfdi_40_metodos_pago | cfdi_40.xls | c_MetodoPago | | +| cfdi_40_monedas | cfdi_40.xls | c_Moneda | | +| cfdi_40_municipios | cfdi_40.xls | C_Municipio | | +| cfdi_40_numeros_pedimento_aduana | cfdi_40.xls | c_NumPedimentoAduana | No es un catálogo, es una tabla de reglas, contiene duplicados | +| cfdi_40_objetos_impuestos | cfdi_40.xls | c_ObjetoImp | | +| cfdi_40_paises | cfdi_40.xls | c_Pais | | +| cfdi_40_patentes_aduanales | cfdi_40.xls | c_PatenteAduanal | | +| cfdi_40_periodicidades | cfdi_40.xls | c_Periodicidad | | +| cfdi_40_productos_servicios | cfdi_40.xls | c_ClaveProdServ | | +| cfdi_40_regimenes_fiscales | cfdi_40.xls | c_RegimenFiscal | | +| cfdi_40_reglas_tasa_cuota | cfdi_40.xls | c_TasaOCuota | No es un catálogo, es una tabla de reglas | +| cfdi_40_tipos_comprobantes | cfdi_40.xls | c_TipoDeComprobante | No se divide el tipo Nómina en Ns y NdS | +| cfdi_40_tipos_factores | cfdi_40.xls | c_TipoFactor | | +| cfdi_40_tipos_relaciones | cfdi_40.xls | c_TipoRelacion | | +| cfdi_40_usos_cfdi | cfdi_40.xls | c_UsoCFDI | | +| cce_claves_pedimentos | c_ClavePedimento.xls | c_ClavePedimento | | +| cce_colonias | c_Colonia.xls | c_Colonia | Viene en 3 partes | +| cce_estados | C_Estado.xls | c_Estado | Estados de México, Estados Unidos y Canadá | +| cce_fracciones_arancelarias | c_FraccionArancelaria.xls | c_FraccionArancelaria | | +| cce_incoterms | c_INCOTERM.xls | c_INCOTERM | | +| cce_localidades | c_Localidad.xls | c_Localidad | | +| cce_localidades | c_Localidad.xls | c_Localidad | | +| cce_motivos_traslado | c_MotivoTraslado.xls | c_MotivoTraslado | | +| cce_municipios | c_Municipio.xls | c_Municipio | | +| cce_tipos_operacion | c_TipoOperacion.xls | c_TipoOperacion | | +| cce_unidades_aduana | c_UnidadAduana.xls | c_UnidadAduana | No confundir con las claves de unidades, estas son las unidades de comercio exterior | +| nominas_bancos | catNomina.xls | c_Banco | | +| nominas_estados | nomina_estados.xls | c_Estado | Es el mismo que el publicado en cce_estados | +| nomina_origenes_recursos | catNomina.xls | c_OrigenRecurso | | +| nomina_periodicidades_pagos | catNomina.xls | c_PeriodicidadPago | | +| nomina_riesgos_puestos | catNomina.xls | | | +| nomina_tipos_contratos | catNomina.xls | c_TipoContrato | | +| nomina_tipos_deducciones | catNomina.xls | c_TipoDeduccion | | +| nomina_tipos_horas | catNomina.xls | c_TipoHoras | | +| nomina_tipos_incapacidades | catNomina.xls | c_TipoIncapacidad | | +| nomina_tipos_jornadas | catNomina.xls | c_TipoJornada | | +| nomina_tipos_nominas | catNomina.xls | c_TipoNomina | | +| nomina_tipos_otros_pagos | catNomina.xls | c_TipoOtroPago | | +| nomina_tipos_percepciones | catNomina.xls | c_TipoPercepcion | | +| nomina_tipos_regimenes | catNomina.xls | c_TipoRegimen | | + +## CFDI 3.3 `cfdi_*` + +> - + +Los catálogos de CFDI contienen los catálogos de CFDI versión 3.3. Están publicados en formato XLS (Microsoft Excel 2003) y la conversión se hace pasando a Microsoft Excel 2007 y luego a archivos CSV en una sola carpeta. En la conversión también se juntan las hojas que están divididas en partes. Por lo anterior, solo existe un importador con múltiples inyectores. +## CFDI 4.0 `cfdi_40_*` + +> - + +Los catálogos de CFDI contienen los catálogos de CFDI versión 4.0. +Están publicados en formato XLS (Microsoft Excel 2003) y la conversión se hace pasando a Microsoft Excel 2007 y luego +a archivos CSV en una sola carpeta. En la conversión también se juntan las hojas que están divididas en partes. + +Por lo anterior, solo existe un importador con múltiples inyectores. ## CCE (Complemento de comercio exterior) diff --git a/docs/Pruebas.md b/docs/Pruebas.md index ce700f3..aaf7804 100644 --- a/docs/Pruebas.md +++ b/docs/Pruebas.md @@ -19,6 +19,7 @@ estos archivos y correr los tests. De esta forma podremos notar un cambio import - `tests/_files/cce/*.csv`: Archivos que salen de los catálogos de Comercio Exterior - `tests/_files/cfdi/*.csv`: Archivos que salen de los catálogos de CFDI 3.3 +- `tests/_files/cfdi40/*.csv`: Archivos que salen de los catálogos de CFDI 4.0 - `tests/_files/nomina/*.csv`: Archivos que salen de los catálogos de Nómina 1.2 - `tests/_files/rep/*.csv`: Archivos que salen de los catálogos de recibo electrónico de pagos @@ -42,12 +43,14 @@ php bin/sat-catalogos-update update-origins build/temp/origins.xml rm -rf tests/_files/sources rm -rf tests/_files/cfdi +rm -rf tests/_files/cfdi40 rm -rf tests/_files/nomina rm -rf tests/_files/rep rm -rf tests/_files/cce mkdir -p tests/_files/sources mkdir -p tests/_files/cfdi +mkdir -p tests/_files/cfdi40 mkdir -p tests/_files/nomina mkdir -p tests/_files/rep mkdir -p tests/_files/cce @@ -55,6 +58,7 @@ mkdir -p tests/_files/cce cp build/temp/*.xls tests/_files/sources php tests/convert-xls-to-csv-folder.php tests/_files/sources/catCFDI.xls tests/_files/cfdi +php tests/convert-xls-to-csv-folder.php tests/_files/sources/cfdi_40.xls tests/_files/cfdi40 php tests/convert-xls-to-csv-folder.php tests/_files/sources/catNomina.xls tests/_files/nomina php tests/convert-xls-to-csv-folder.php tests/_files/sources/catPagos.xls tests/_files/rep php tests/convert-xls-to-csv-folder.php tests/_files/sources/c_ClavePedimento.xls tests/_files/cce From 5bce27fc7ae0ba533a9bf3383d6491e4376c5994 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Sat, 5 Mar 2022 02:50:44 -0600 Subject: [PATCH 6/6] Prepare version 2.3.0 --- docs/CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 9268581..20ead7f 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,15 @@ # phpcfdi/sat-catalogos-populate Changelog +## Version 2.3.0 2022-03-05 + +Add CFDI 4.0 catalogs. + +- Add *Origin* as a scrap from SAT website, saving the file as `cfdi_40.xsl`. +- Add *Source importer* from `cfdi_40.xsl`. It includes 25 catalogs. +- Importers create tables with prefix `cfdi_40_*`. +- Update `docs/Catalogos.md` with CFDI 4.0 catalogs. +- Refactor how to know what lines to skip when join two CVS files. + ## Version 2.2.1 2022-03-04 Include `Nóminas - Estados` origin to `dump-origins` command.