Skip to content

Commit

Permalink
Version 2.12.10
Browse files Browse the repository at this point in the history
  • Loading branch information
eclipxe13 committed Jul 19, 2020
2 parents e458aaf + e203010 commit d84cb73
Show file tree
Hide file tree
Showing 24 changed files with 247 additions and 42 deletions.
6 changes: 5 additions & 1 deletion .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,15 @@ install:
if (! (Test-Path ${Env:saxonb-path})) {
appveyor-retry choco install --ignore-checksums --yes saxonhe --no-progress
}
# install project dependences and list available tools
- cd c:\projects\project
- appveyor-retry composer install --prefer-dist --no-progress --no-interaction --ansi
- dir vendor\bin
# sat-xml resources as a dependency
- ps: |
appveyor-retry appveyor DownloadFile https://github.com/phpcfdi/resources-sat-xml/archive/master.zip -Filename c:\projects\project\build\sat-xml.zip
Expand-Archive -LiteralPath c:\projects\project\build\sat-xml.zip -DestinationPath c:\projects\project\build\ -Force
Move-Item -Path c:\projects\project\build\resources-sat-xml-master\resources -Destination c:\projects\project\build\resources
## Run the actual test
test_script:
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ before_script:
- travis_retry composer install --no-interaction --prefer-dist
- travis_retry npm install
- travis_retry pip install --user mkdocs
- travis_retry bash tests/resource-sat-xml-download build/

script:
- vendor/bin/phpcs -sp src/ tests/
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ and licensed for use under the MIT License (MIT). Please see [LICENSE][] for mor
[discord]: https://discord.gg/aFGYXvX
[release]: https://github.com/eclipxe13/CfdiUtils/releases
[license]: https://github.com/eclipxe13/CfdiUtils/blob/master/LICENSE
[build]: https://travis-ci.org/eclipxe13/CfdiUtils?branch=master
[build]: https://travis-ci.com/eclipxe13/CfdiUtils?branch=master
[appveyor]: https://ci.appveyor.com/project/eclipxe13/cfdiutils/branch/master
[quality]: https://scrutinizer-ci.com/g/eclipxe13/CfdiUtils/?branch=master
[coverage]: https://scrutinizer-ci.com/g/eclipxe13/CfdiUtils/code-structure/master/code-coverage/src/CfdiUtils/
Expand All @@ -105,7 +105,7 @@ and licensed for use under the MIT License (MIT). Please see [LICENSE][] for mor
[badge-discord]: https://img.shields.io/discord/459860554090283019?logo=discord&style=flat-square
[badge-release]: https://img.shields.io/github/release/eclipxe13/CfdiUtils?logo=git&style=flat-square
[badge-license]: https://img.shields.io/github/license/eclipxe13/CfdiUtils?logo=open-source-initiative&style=flat-square
[badge-build]: https://img.shields.io/travis/eclipxe13/CfdiUtils/master?logo=travis&style=flat-square
[badge-build]: https://img.shields.io/travis/com/eclipxe13/CfdiUtils/master?logo=travis&style=flat-square
[badge-appveyor]: https://img.shields.io/appveyor/ci/eclipxe13/cfdiutils/master?logo=appveyor&style=flat-square
[badge-quality]: https://img.shields.io/scrutinizer/g/eclipxe13/CfdiUtils/master?logo=scrutinizer-ci&style=flat-square
[badge-coverage]: https://img.shields.io/scrutinizer/coverage/g/eclipxe13/CfdiUtils/master?logo=scrutinizer-ci&style=flat-square
Expand Down
36 changes: 33 additions & 3 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,40 @@
- Remove file `ConsultaCFDIServiceSAT.svc.xml`.
- Change visibility of `CfdiUtils\Cleaner\Cleaner#removeIncompleteSchemaLocation()` to private.

## UNRELEASED
## Version 2.12.10 2020-07-18

- *2020-07-14*: Documentation: "Descarga de recursos XSD y XSLT"
- *2020-07-18*: Documentation: Add last document to `mkdocs:nav`, format rewording and links.
- Documentation "Descarga de recursos XSD y XSLT"

- *2020-07-14*: Documentation: "Descarga de recursos XSD y XSLT"
- *2020-07-18*: Documentation: Add last document to `mkdocs:nav`, format rewording and links.

- Add `tests/resource-sat-xml-download`, include it on travis build.

SAT has been failing providing XSD and XSLT files. This tool obtains (via `tests/resource-sat-xml-download`) a fresh copy
of those files from [`phpcfdi/resources-sat-xml`](https://github.com/phpcfdi/resources-sat-xml) project for development.

- Add script to install [`phpcfdi/resources-sat-xml`](https://github.com/phpcfdi/resources-sat-xml) on AppVeyor build.

- Fix default locations for TFD 1.0.

In the past, SAT allowed at least 2 different URLS for TFD 1.0 on XSD and XSLT files. In this version this is
normalized with [`phpcfdi/sat-ns-registry`](https://github.com/phpcfdi/sat-ns-registry) project.

- Add a new cleaner method `Cleaner::fixKnownSchemaLocationsXsdUrls` to override the XSD file URLS for CFDI and TFD.

This replaces any known and found url ignoring case and put the correct one,
it also replaces `http://www.sat.gob.mx/sitio_internet/TimbreFiscalDigital/TimbreFiscalDigital.xsd` (unused)
with `http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigital.xsd` (official).

- Improve explanation on `TFDSELLO01` when unable to get certificate.

The assert `TFDSELLO01` *El Sello SAT del Timbre Fiscal Digital corresponde al certificado SAT*, now includes the
exception message when unable to obtain a certificate.

- Remove insecure downloader from testing.

This was introduced previously because the webserver was using invalid SSL certificates.
This problem does not exist anymore (since 2019-10-24).


## Version 2.12.9 2020-04-25
Expand Down
6 changes: 5 additions & 1 deletion docs/TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@

## Verificar problemas conocidos

### Descarga de certificados desde <https://rdc.sat.gob.mx/rccf/>
### Descarga de certificados desde <https://rdc.sat.gob.mx/rccf/> por certificados vencidos

Ver: <https://www.phpcfdi.com/sat/problemas-conocidos/descarga-certificados/#problemas-de-caducidad-de-certificados>

*Actualización 2020-07-18*: Desde 2019-10-24 este problema parece solucionado.

La descarga de certificados desde `https://rdc.sat.gob.mx/rccf/` falla por un error de configuración
en el servidor web del SAT. Por ello se han puesto instancias especiales de descargadores `PhpDownloader`
Expand Down
16 changes: 16 additions & 0 deletions src/CfdiUtils/Cleaner/Cleaner.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use CfdiUtils\Cfdi;
use CfdiUtils\Cleaner\BeforeLoad\BeforeLoadCleanerInterface;
use CfdiUtils\Cleaner\Cleaners\SchemaLocationsXsdUrlsFixer;
use CfdiUtils\Utils\SchemaLocations;
use CfdiUtils\Utils\Xml;
use DOMAttr;
Expand Down Expand Up @@ -91,6 +92,7 @@ public function clean()
$this->removeNonSatNSschemaLocations();
$this->removeUnusedNamespaces();
$this->collapseComprobanteComplemento();
$this->fixKnownSchemaLocationsXsdUrls();
}

/**
Expand Down Expand Up @@ -308,6 +310,20 @@ public function collapseComprobanteComplemento()
}
}

/**
* Procedure to fix XSD known location paths for CFDI and TFD
*
* @return void
*/
public function fixKnownSchemaLocationsXsdUrls()
{
$xsiLocations = $this->obtainXsiSchemaLocations();
$schemasFixer = SchemaLocationsXsdUrlsFixer::createWithKnownSatUrls();
foreach ($xsiLocations as $xsiSchemaLocation) {
$schemasFixer->fixSchemaLocationAttribute($xsiSchemaLocation);
}
}

/** @return DOMNodeList|DOMAttr[] */
private function obtainXsiSchemaLocations(): DOMNodeList
{
Expand Down
72 changes: 72 additions & 0 deletions src/CfdiUtils/Cleaner/Cleaners/SchemaLocationsXsdUrlsFixer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

declare(strict_types=1);

namespace CfdiUtils\Cleaner\Cleaners;

use CfdiUtils\Internals\StringUncaseReplacer;
use CfdiUtils\Utils\SchemaLocations;
use DOMAttr;

/**
* Class SchemaLocationsXsdUrlsFixer
*
* This class is an abstraction of method Cleaner::fixKnownSchemaLocationsXsdUrls
*
* @internal
*/
final class SchemaLocationsXsdUrlsFixer
{
/** @var StringUncaseReplacer */
private $replacer;

/**
* Create a new instance based on a map using keys as replacement and values as an array of needles
*
* @param array<string, array<string>> $replacements
*/
private function __construct(array $replacements)
{
$this->replacer = StringUncaseReplacer::create($replacements);
}

/**
* Created a new instance based on known CFDI and TFD
* It also includes the incorrect but allowed TFD 1.0 alternate urls
*
* @return static
*/
public static function createWithKnownSatUrls(): self
{
return new self([
'http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd' => [],
'http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd' => [],
'http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv3.xsd' => [],
'http://www.sat.gob.mx/sitio_internet/cfd/2/cfdv22.xsd' => [],
'http://www.sat.gob.mx/sitio_internet/cfd/2/cfdv2.xsd' => [],
'http://www.sat.gob.mx/sitio_internet/cfd/1/cfdv1.xsd' => [],
'http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigitalv11.xsd' => [],
'http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigital.xsd' => [
'http://www.sat.gob.mx/sitio_internet/TimbreFiscalDigital/TimbreFiscalDigital.xsd',
],
]);
}

public function fixSchemaLocationAttribute(DOMAttr $xsiSchemaLocation)
{
$schemas = SchemaLocations::fromString($xsiSchemaLocation->value, false);
$this->fixSchemaLocations($schemas);
$fixedValue = $schemas->asString();
if ($xsiSchemaLocation->value !== $fixedValue) {
$xsiSchemaLocation->value = $fixedValue;
}
}

public function fixSchemaLocations(SchemaLocations $schemaLocations)
{
foreach ($schemaLocations as $ns => $url) {
$url = $this->replacer->findReplacement($url) ?: $url;
$schemaLocations->append($ns, $url);
}
}
}
53 changes: 53 additions & 0 deletions src/CfdiUtils/Internals/StringUncaseReplacer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace CfdiUtils\Internals;

/** @internal */
final class StringUncaseReplacer
{
/** @var array<string, array<string, true>> */
private $replacements;

/**
* @param array<string, array<string, true>> $replacements
*/
private function __construct(array $replacements = [])
{
$this->replacements = $replacements;
}

/**
* @param array<string, array<string>> $replacements
* @return static
*/
public static function create(array $replacements): self
{
$replacer = new self();
foreach ($replacements as $replacement => $needles) {
$replacer->addReplacement($replacement, ...$needles);
}
return $replacer;
}

private function addReplacement(string $replacement, string ...$needle)
{
$needle[] = $replacement; // also include the replacement itself
foreach ($needle as $entry) {
$entry = mb_strtolower($entry); // normalize url to compare
$this->replacements[$replacement][$entry] = true;
}
}

public function findReplacement(string $url): string
{
$url = mb_strtolower($url); // normalize url to compare
foreach ($this->replacements as $replacement => $entries) {
if (isset($entries[$url])) {
return $replacement;
}
}
return '';
}
}
2 changes: 1 addition & 1 deletion src/CfdiUtils/TimbreFiscalDigital/TfdCadenaDeOrigen.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class TfdCadenaDeOrigen implements XmlResolverPropertyInterface, XsltBuilderProp
use XmlResolverPropertyTrait;
use XsltBuilderPropertyTrait;

const TFD_10 = 'http://www.sat.gob.mx/sitio_internet/timbrefiscaldigital/cadenaoriginal_TFD_1_0.xslt';
const TFD_10 = 'http://www.sat.gob.mx/sitio_internet/cfd/timbrefiscaldigital/cadenaoriginal_TFD_1_0.xslt';

const TFD_11 = 'http://www.sat.gob.mx/sitio_internet/cfd/timbrefiscaldigital/cadenaoriginal_TFD_1_1.xslt';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public function validate(NodeInterface $comprobante, Asserts $asserts)
} catch (\Throwable $ex) {
$assert->setStatus(
Status::error(),
sprintf('No se ha podido obtener el certificado %s', $certificadoSAT)
sprintf('No se ha podido obtener el certificado %s: %s', $certificadoSAT, $ex->getMessage())
);
return;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/CfdiUtilsTests/Certificado/CerRetrieverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function testRetrieveValidCertificate()
// after this date this test may fail
$certificateId = '00001000000406258094';
$cerNumber = new SatCertificateNumber($certificateId);
$retriever = $this->newResolver($this->newInsecurePhpDownloader())->newCerRetriever();
$retriever = $this->newResolver()->newCerRetriever();
$remoteUrl = $cerNumber->remoteUrl();
$localPath = $retriever->buildPath($remoteUrl);

Expand Down
3 changes: 1 addition & 2 deletions tests/CfdiUtilsTests/CfdiValidator33Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ public function testValidateCfdi33Real()
$cfdiFile = $this->utilAsset('cfdi33-real.xml');
$cfdi = Cfdi::newFromString(strval(file_get_contents($cfdiFile)));

$validator = new CfdiValidator33();
$validator->getXmlResolver()->setDownloader($this->newInsecurePhpDownloader());
$validator = new CfdiValidator33($this->newResolver());
$asserts = $validator->validate($cfdi->getSource(), $cfdi->getNode());
// $asserts->hasErrors() && print_r($asserts->errors());
$this->assertFalse(
Expand Down
12 changes: 10 additions & 2 deletions tests/CfdiUtilsTests/Cleaner/CleanerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ public function testCleanOnDetail()
$step3 = $this->utilAsset('cleaner/v32-no-nonsat-nodes.xml');
$step4 = $this->utilAsset('cleaner/v32-no-nonsat-schemalocations.xml');
$step5 = $this->utilAsset('cleaner/v32-no-nonsat-xmlns.xml');
foreach ([$basefile, $step1, $step3, $step2, $step4, $step5] as $filename) {
$step6 = $this->utilAsset('cleaner/v32-schemalocations-replacements.xml');
foreach ([$basefile, $step1, $step3, $step2, $step4, $step5, $step6] as $filename) {
$this->assertFileExists($basefile, "The file $filename for testing does not exists");
}
$cleaner = new Cleaner(strval(file_get_contents($basefile)));
Expand Down Expand Up @@ -130,8 +131,15 @@ public function testCleanOnDetail()
'Compare that xmlns definitions were removed'
);

$cleaner->fixKnownSchemaLocationsXsdUrls();
$this->assertXmlStringEqualsXmlFile(
$step5,
$step6,
$cleaner->retrieveXml(),
'Compare that schemaLocations definitions were changed'
);

$this->assertXmlStringEqualsXmlFile(
$step6,
Cleaner::staticClean(strval(file_get_contents($basefile))),
'Check static method for cleaning is giving the same results as detailed execution'
);
Expand Down
23 changes: 3 additions & 20 deletions tests/CfdiUtilsTests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

use CfdiUtils\Certificado\SatCertificateNumber;
use CfdiUtils\XmlResolver\XmlResolver;
use XmlResourceRetriever\Downloader\DownloaderInterface;
use XmlResourceRetriever\Downloader\PhpDownloader;

abstract class TestCase extends \PHPUnit\Framework\TestCase
{
Expand All @@ -19,25 +17,10 @@ protected function isRunningOnWindows(): bool
return ('\\' === DIRECTORY_SEPARATOR);
}

protected function newInsecurePhpDownloader(): DownloaderInterface
/** @return XmlResolver */
protected function newResolver()
{
// disable ssl verification connecting to https://rdc.sat.gob.mx/ since SAT web server has config errors
return new PhpDownloader(
stream_context_create([
'ssl' => [
'verify_peer' => false,
],
])
);
}

protected function newResolver(DownloaderInterface $downloader = null)
{
$xmlResolver = new XmlResolver();
if (null !== $downloader) {
$xmlResolver->setDownloader($downloader);
}
return $xmlResolver;
return new XmlResolver();
}

protected function downloadResourceIfNotExists(string $remote): string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ class TimbreFiscalDigitalSelloTest extends ValidateTestCase
protected function setUp()
{
parent::setUp();
$this->hydrater->getXmlResolver()->setDownloader($this->newInsecurePhpDownloader());
$this->validator = new TimbreFiscalDigitalSello();
$this->hydrater->hydrate($this->validator);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/assets/cleaner/v32-dirty-errors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<abc:Sample xmlns:abc="http://example.com/xsd/abc" xsi:schemaLocation="http://example.com/xsd/abc http://example.com/xsd/abc.xsd" x="1"/>
</cfdi:Addenda>
<cfdi:Complemento>
<tfd:TimbreFiscalDigital xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigital.xsd" version="1.0"/>
<tfd:TimbreFiscalDigital xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/timbrefiscaldigital/TimbreFiscalDigital.xsd" version="1.0"/>
<add:point x="1" y="2" add:removed="Check if this attributte is removed"/>
</cfdi:Complemento>
</cfdi:Comprobante>
2 changes: 1 addition & 1 deletion tests/assets/cleaner/v32-dirty.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<abc:Sample xmlns:abc="http://example.com/xsd/abc" xsi:schemaLocation="http://example.com/xsd/abc http://example.com/xsd/abc.xsd" x="1"/>
</cfdi:Addenda>
<cfdi:Complemento>
<tfd:TimbreFiscalDigital xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigital.xsd" version="1.0"/>
<tfd:TimbreFiscalDigital xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/timbrefiscaldigital/TimbreFiscalDigital.xsd" version="1.0"/>
<add:point x="1" y="2" add:removed="Check if this attributte is removed"/>
</cfdi:Complemento>
</cfdi:Comprobante>
Loading

0 comments on commit d84cb73

Please sign in to comment.