diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 9f4ac8ee..010e1064 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -28,6 +28,9 @@ jobs: - name: Generate Documentation run: php tools/phpdocumentor run --config=phpdoc.xml + - name: Create CNAME file + run: echo "lib-core.docs.libredte.cl" > build/docs/CNAME + - name: Deploy to GitHub Pages if: success() uses: peaceiris/actions-gh-pages@v4 diff --git a/.scrutinizer.yml b/.scrutinizer.yml index e190dda5..12a90581 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -10,9 +10,6 @@ build: dependencies: before: - composer install --no-progress --no-suggest --prefer-dist - cache: - directories: - - vendor tools: php_code_sniffer: diff --git a/src/Repository/ImpuestosAdicionalesRepository.php b/src/Repository/ImpuestosAdicionalesRepository.php index 651b2794..689bec5b 100644 --- a/src/Repository/ImpuestosAdicionalesRepository.php +++ b/src/Repository/ImpuestosAdicionalesRepository.php @@ -106,8 +106,8 @@ public function getRetenido(array $OtrosImp): float { $retenido = 0.0; foreach ($OtrosImp as $Imp) { - if ($this->getTipo((int)$Imp['CodImp']) === 'R') { - $retenido += (float)$Imp['MntImp']; + if ($this->getTipo((int) $Imp['CodImp']) === 'R') { + $retenido += (float) $Imp['MntImp']; } } return $retenido; diff --git a/src/Sii/Dte/Documento/AbstractDocumento.php b/src/Sii/Dte/Documento/AbstractDocumento.php index f2b53943..ecfe0832 100644 --- a/src/Sii/Dte/Documento/AbstractDocumento.php +++ b/src/Sii/Dte/Documento/AbstractDocumento.php @@ -306,8 +306,15 @@ public function getTotales(): array public function getMontoTotal(): int|float { $data = $this->getData(); + $monto = $data['Encabezado']['Totales']['MntTotal']; - return $data['Encabezado']['Totales']['MntTotal']; + // Verificar si el monto es equivalente a un entero. + if (is_float($monto) && floor($monto) == $monto) { + return (int) $monto; + } + + // Entregar como flotante. + return $monto; } /** diff --git a/src/Sii/Dte/Documento/Normalization/IvaMntTotalNormalizationTrait.php b/src/Sii/Dte/Documento/Normalization/IvaMntTotalNormalizationTrait.php index 58e560a3..5c755443 100644 --- a/src/Sii/Dte/Documento/Normalization/IvaMntTotalNormalizationTrait.php +++ b/src/Sii/Dte/Documento/Normalization/IvaMntTotalNormalizationTrait.php @@ -121,6 +121,13 @@ protected function applyIvaMntTotalNormalization(array $data): array } } + // Si hay IVA definido se cambia a valor entero. El IVA no es decimal. + if (is_numeric($data['Encabezado']['Totales']['IVA'] ?? null)) { + $data['Encabezado']['Totales']['IVA'] = + (int) $data['Encabezado']['Totales']['IVA'] + ; + } + // Si hay impuesto retenido o adicional se contabiliza en el total. if (!empty($data['Encabezado']['Totales']['ImptoReten'])) { foreach ($data['Encabezado']['Totales']['ImptoReten'] as &$ImptoReten) { @@ -181,6 +188,17 @@ protected function applyIvaMntTotalNormalization(array $data): array } } + // Si hay monto total definido, y el documento no es de exportación, se + // cambia a valor entero. El monto total no es decimal en documentos + // nacionales. + if (is_numeric($data['Encabezado']['Totales']['MntTotal'] ?? null)) { + if (!$this->getTipoDocumento()->esExportacion()) { + $data['Encabezado']['Totales']['MntTotal'] = + (int) $data['Encabezado']['Totales']['MntTotal'] + ; + } + } + // Entregar los datos normalizados. return $data; } diff --git a/tests/resources/use_cases/xml_converter.php b/tests/resources/use_cases/xml_converter.php index 1e45a5c2..05cd1449 100644 --- a/tests/resources/use_cases/xml_converter.php +++ b/tests/resources/use_cases/xml_converter.php @@ -75,7 +75,7 @@ // Caso con nodos vacíos. 'empty_node' => [ 'data' => ['root' => ['element' => '']], - 'expected' => ['root' => ['element' => '']], + 'expected' => ['root' => ['element' => null]], 'expectedException' => null, ], // Caso con múltiples valores repetidos. @@ -306,7 +306,7 @@ // Caso con nodos vacíos. 'empty_node' => [ 'xmlContent' => '', - 'expected' => ['root' => ['element' => '']], + 'expected' => ['root' => ['element' => null]], 'expectedException' => null, ], // Caso con múltiples valores repetidos. diff --git a/tests/src/Functional/Repository/ImpuestosAdicionalesRepositoryTest.php b/tests/src/Functional/Repository/ImpuestosAdicionalesRepositoryTest.php index afe9b048..af1fc676 100644 --- a/tests/src/Functional/Repository/ImpuestosAdicionalesRepositoryTest.php +++ b/tests/src/Functional/Repository/ImpuestosAdicionalesRepositoryTest.php @@ -58,7 +58,7 @@ public function testGetGlosa(): void public function testGetTasa(): void { - $this->assertSame(19, $this->repository->getTasa(15)); + $this->assertSame(19.0, $this->repository->getTasa(15)); $this->assertSame(31.5, $this->repository->getTasa(24)); $this->assertFalse($this->repository->getTasa(999)); } @@ -71,6 +71,6 @@ public function testGetRetenido(): void ['CodImp' => 30, 'MntImp' => 700], ]; - $this->assertSame(1700, $this->repository->getRetenido($OtrosImp)); + $this->assertSame(1700, (int) $this->repository->getRetenido($OtrosImp)); } } diff --git a/tests/src/Functional/Sii/Dte/Documento/EmitirIndividualmenteDocumentosOkTest.php b/tests/src/Functional/Sii/Dte/Documento/EmitirIndividualmenteDocumentosOkTest.php index 5caf3eb3..fc78395c 100644 --- a/tests/src/Functional/Sii/Dte/Documento/EmitirIndividualmenteDocumentosOkTest.php +++ b/tests/src/Functional/Sii/Dte/Documento/EmitirIndividualmenteDocumentosOkTest.php @@ -206,6 +206,18 @@ private function validateExpectedValues( // Si el valor esperado no es un arreglo, se compara directamente. else { + // Si el valor actual es un flotante, se revisa si se debe + // convertir a un entero para usar assertSame() con el tipo de + // datos correcto y que no falle porque se compara entero con + // float. + if ( + is_float($actualValues[$key]) + && floor($actualValues[$key]) == $actualValues[$key] + ) { + $actualValues[$key] = (int) $actualValues[$key]; + } + + // Realizar validación del valor. $this->assertSame( $expectedValue, $actualValues[$key],