diff --git a/README.md b/README.md
index 259f80f..1b58855 100644
--- a/README.md
+++ b/README.md
@@ -272,7 +272,7 @@ Puede que los cambios del ejemplo no sean lógicos, es solo para ilustrar cómo
- Filtrando por únicamente documentos vigentes (excluye cancelados).
- Filtrando por el RFC a cuenta de terceros `XXX01010199A`.
- Filtrando por el RFC contraparte `MAG041126GT8`. Como se solicitan recibidos, entonces son los emidos por ese RFC.
-- Filtrando por el UUID `96623061-61fe-49de-b298-c7156476aa8b`
+- Filtrando por el UUID `96623061-61fe-49de-b298-c7156476aa8b`.
```php
withUuid(Uuid::create('96623061-61fe-49de-b298-c7156476aa8b'))
+;
+```
+
### Verificar una consulta
La verificación depende de que la consulta haya sido aceptada.
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index b13595e..a4f437e 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -14,6 +14,20 @@ que nombraremos así: ` Breaking . Feature . Fix `, donde:
**Importante:** Las reglas de SEMVER no aplican si estás usando una rama (por ejemplo `main-dev`)
o estás usando una versión cero (por ejemplo `0.18.4`).
+## Versión 0.5.2 2022-09-30
+
+#### Consulta por UUID
+
+Gracias a la solicitud de cambios en [`luisiturrios1/python-cfdiclient#42`](https://github.com/luisiturrios1/python-cfdiclient/pull/42)
+por `@alan196`, hemos podido verificar que la documentación del servicio con respecto a la consulta por UUID está incorrecta.
+
+- El campo no se llama `UUID`, se llama `Folio`.
+- El campo `RfcSolicitante` no se debe omitir.
+- El campo `TipoSolicitud` no se debe omitir.
+- Los demás campos no deben existir.
+
+Por lo tanto, se han hecho las correcciones necesarias para hacer la consulta por `UUID`.
+
## Versión 0.5.1 2022-09-28
### Se corrigen XML mal formados
diff --git a/docs/problema-filtros-no-aplicados.md b/docs/problema-filtros-no-aplicados.md
index 3f3e7c6..7d8dc93 100644
--- a/docs/problema-filtros-no-aplicados.md
+++ b/docs/problema-filtros-no-aplicados.md
@@ -19,17 +19,24 @@ En esta versión se agregan nuevos filtros, permitiendo hacer solicitudes más e
Los siguientes filtros no están funcionando en la consulta de CFDI Regulares:
-- Filtro por UUID.
- Filtro de documentos cancelados cuando se solicita un paquete de documentos XML.
El filtro funciona correctamente para paquetes de Metadata.
Los siguientes filtros no están funcionando en la consulta de CFDI de retenciones e información de pagos:
- Filtro por complemento.
-- Filtro por UUID.
## Actualizaciones
+### 2022-09-30
+
+Hemos notado que la documentación del SAT en relación con la consulta por UUID está incorrecta:
+
+- El campo no se llama `UUID`, se llama `Folio`.
+- El campo `RfcSolicitante` se debe especificar.
+- El campo `TipoSolicitud` se debe especificar.
+- Los demás campos no deben existir.
+
### 2022-03-04
El SAT actualiza el servicio a la versión 1.2, no resuelve las solicitudes ingresadas.
diff --git a/src/RequestBuilder/FielRequestBuilder/FielRequestBuilder.php b/src/RequestBuilder/FielRequestBuilder/FielRequestBuilder.php
index 2680038..d6877e6 100644
--- a/src/RequestBuilder/FielRequestBuilder/FielRequestBuilder.php
+++ b/src/RequestBuilder/FielRequestBuilder/FielRequestBuilder.php
@@ -74,34 +74,57 @@ public function authorization(DateTime $created, DateTime $expires, string $secu
public function query(QueryParameters $queryParameters): string
{
- // normalize input
- $start = $queryParameters->getPeriod()->getStart()->format('Y-m-d\TH:i:s');
- $end = $queryParameters->getPeriod()->getEnd()->format('Y-m-d\TH:i:s');
+ $queryByUuid = ! $queryParameters->getUuid()->isEmpty();
+ $xmlRfcReceived = '';
$requestType = $queryParameters->getRequestType()->getQueryAttributeValue($queryParameters->getServiceType());
$rfcSigner = mb_strtoupper($this->getFiel()->getRfc());
- if ($queryParameters->getDownloadType()->isIssued()) {
- // issued documents, counterparts are receivers
- $rfcIssuer = $rfcSigner;
- $rfcReceivers = $queryParameters->getRfcMatches();
- } else {
- // received documents, counterpart is issuer
- $rfcIssuer = $queryParameters->getRfcMatches()->getFirst()->getValue();
- $rfcReceivers = RfcMatches::createFromValues($rfcSigner);
- }
- $solicitudAttributes = array_filter(
- [
- 'RfcSolicitante' => $rfcSigner,
+ $solicitudAttributes = [
+ 'RfcSolicitante' => $rfcSigner,
+ 'TipoSolicitud' => $requestType,
+ ];
+
+ if ($queryByUuid) {
+ $solicitudAttributes = $solicitudAttributes + [
+ 'Folio' => $queryParameters->getUuid()->getValue(),
+ ];
+ } else {
+ $start = $queryParameters->getPeriod()->getStart()->format('Y-m-d\TH:i:s');
+ $end = $queryParameters->getPeriod()->getEnd()->format('Y-m-d\TH:i:s');
+ if ($queryParameters->getDownloadType()->isIssued()) {
+ // issued documents, counterparts are receivers
+ $rfcIssuer = $rfcSigner;
+ $rfcReceivers = $queryParameters->getRfcMatches();
+ } else {
+ // received documents, counterpart is issuer
+ $rfcIssuer = $queryParameters->getRfcMatches()->getFirst()->getValue();
+ $rfcReceivers = RfcMatches::createFromValues($rfcSigner);
+ }
+ $solicitudAttributes = $solicitudAttributes + [
'FechaInicial' => $start,
'FechaFinal' => $end,
- 'TipoSolicitud' => $requestType,
'RfcEmisor' => $rfcIssuer,
'TipoComprobante' => $queryParameters->getDocumentType()->value(),
'EstadoComprobante' => $queryParameters->getDocumentStatus()->value(),
- 'UUID' => $queryParameters->getUuid()->getValue(),
'RfcACuentaTerceros' => $queryParameters->getRfcOnBehalf()->getValue(),
'Complemento' => $queryParameters->getComplement()->value(),
- ],
+ ];
+ if (! $rfcReceivers->isEmpty()) {
+ $xmlRfcReceived = implode('', array_map(
+ function (RfcMatch $rfcMatch): string {
+ return sprintf(
+ '%s',
+ $this->parseXml($rfcMatch->getValue())
+ );
+ },
+ iterator_to_array($rfcReceivers)
+ ));
+ $xmlRfcReceived = "{$xmlRfcReceived}";
+ }
+ }
+
+ $solicitudAttributes = array_filter(
+ $solicitudAttributes,
static function (string $value): bool {
return '' !== $value;
}
@@ -116,20 +139,6 @@ function (string $name, string $value): string {
$solicitudAttributes,
));
- $xmlRfcReceived = '';
- if (! $rfcReceivers->isEmpty()) {
- $xmlRfcReceived = implode('', array_map(
- function (RfcMatch $rfcMatch): string {
- return sprintf(
- '%s',
- $this->parseXml($rfcMatch->getValue())
- );
- },
- iterator_to_array($rfcReceivers)
- ));
- $xmlRfcReceived = "{$xmlRfcReceived}";
- }
-
$toDigestXml = <<
diff --git a/tests/Integration/ConsumeCfdiServicesUsingFakeFielTest.php b/tests/Integration/ConsumeCfdiServicesUsingFakeFielTest.php
index 4dff080..369e241 100644
--- a/tests/Integration/ConsumeCfdiServicesUsingFakeFielTest.php
+++ b/tests/Integration/ConsumeCfdiServicesUsingFakeFielTest.php
@@ -36,7 +36,6 @@ public function testQueryChangeAllParameters(): void
->withDocumentType(DocumentType::nomina())
->withComplement(ComplementoCfdi::nomina12())
->withDocumentStatus(DocumentStatus::active())
- ->withUuid(Uuid::create('96623061-61fe-49de-b298-c7156476aa8b'))
->withRfcOnBehalf(RfcOnBehalf::create('XXX01010199A'))
->withRfcMatch(RfcMatch::create('AAA010101AAA'))
;
@@ -49,6 +48,22 @@ public function testQueryChangeAllParameters(): void
);
}
+ public function testQueryUuid(): void
+ {
+ $service = $this->createService();
+
+ $parameters = QueryParameters::create()
+ ->withUuid(Uuid::create('96623061-61fe-49de-b298-c7156476aa8b'))
+ ;
+
+ $result = $service->query($parameters);
+ $this->assertSame(
+ 305,
+ $result->getStatus()->getCode(),
+ 'Expected to receive a 305 - Certificado Inválido from SAT since FIEL is for testing'
+ );
+ }
+
public function testServiceEndpointsDifferentThanQueryEndpointsThrowsError(): void
{
$service = $this->createService();
diff --git a/tests/Integration/ConsumeRetencionesServicesUsingFakeFielTest.php b/tests/Integration/ConsumeRetencionesServicesUsingFakeFielTest.php
index 6cd1119..7a1c0d9 100644
--- a/tests/Integration/ConsumeRetencionesServicesUsingFakeFielTest.php
+++ b/tests/Integration/ConsumeRetencionesServicesUsingFakeFielTest.php
@@ -27,7 +27,7 @@ protected function getServiceEndpoints(): ServiceEndpoints
return ServiceEndpoints::retenciones();
}
- public function testQueryChangeAllParameters(): void
+ public function testQueryChangeFilters(): void
{
$service = $this->createService();
@@ -37,7 +37,6 @@ public function testQueryChangeAllParameters(): void
->withRequestType(RequestType::xml())
->withComplement(ComplementoRetenciones::undefined())
->withDocumentStatus(DocumentStatus::active())
- ->withUuid(Uuid::create('96623061-61fe-49de-b298-c7156476aa8b'))
->withRfcOnBehalf(RfcOnBehalf::create('XXX01010199A'))
->withRfcMatch(RfcMatch::create('AAA010101AAA'))
;
@@ -50,6 +49,22 @@ public function testQueryChangeAllParameters(): void
);
}
+ public function testQueryByUuid(): void
+ {
+ $service = $this->createService();
+
+ $parameters = QueryParameters::create()
+ ->withUuid(Uuid::create('96623061-61fe-49de-b298-c7156476aa8b'))
+ ;
+
+ $result = $service->query($parameters);
+ $this->assertSame(
+ 305,
+ $result->getStatus()->getCode(),
+ 'Expected to receive a 305 - Certificado Inválido from SAT since FIEL is for testing'
+ );
+ }
+
public function testServiceEndpointsDifferentThanQueryEndpointsThrowsError(): void
{
$service = $this->createService();
diff --git a/tests/Unit/RequestBuilder/FielRequestBuilder/FielRequestBuilderTest.php b/tests/Unit/RequestBuilder/FielRequestBuilder/FielRequestBuilderTest.php
index 2c5ea3c..65c429b 100644
--- a/tests/Unit/RequestBuilder/FielRequestBuilder/FielRequestBuilderTest.php
+++ b/tests/Unit/RequestBuilder/FielRequestBuilder/FielRequestBuilderTest.php
@@ -91,7 +91,7 @@ private function extractSecurityTokenFromXml(string $requestBody): string
return $matches['id'] ?? '';
}
- public function testQueryReceived(): void
+ public function testQueryReceivedByFilters(): void
{
$requestBuilder = $this->createFielRequestBuilderUsingTestingFiles();
$parameters = QueryParameters::create()
@@ -102,14 +102,32 @@ public function testQueryReceived(): void
->withDocumentType(DocumentType::nomina())
->withComplement(ComplementoCfdi::nomina12())
->withDocumentStatus(DocumentStatus::active())
- ->withUuid(Uuid::create('96623061-61fe-49de-b298-c7156476aa8b'))
->withRfcOnBehalf(RfcOnBehalf::create('XXX01010199A'))
->withRfcMatch(RfcMatch::create('AAA010101AAA'))
;
$requestBody = $requestBuilder->query($parameters);
$this->assertSame(
- $this->xmlFormat(Helpers::nospaces($this->fileContents('query/request-received.xml'))),
+ $this->xmlFormat(Helpers::nospaces($this->fileContents('query/request-received-by-filters.xml'))),
+ $this->xmlFormat($requestBody)
+ );
+
+ $xmlSecVerification = (new EnvelopSignatureVerifier())
+ ->verify($requestBody, 'http://DescargaMasivaTerceros.sat.gob.mx', 'SolicitaDescarga');
+ $this->assertTrue($xmlSecVerification, 'The signature cannot be verified using XMLSecLibs');
+ }
+
+ public function testQueryReceivedByUuid(): void
+ {
+ $requestBuilder = $this->createFielRequestBuilderUsingTestingFiles();
+ $parameters = QueryParameters::create()
+ ->withServiceType(ServiceType::cfdi())
+ ->withUuid(Uuid::create('96623061-61fe-49de-b298-c7156476aa8b'))
+ ;
+ $requestBody = $requestBuilder->query($parameters);
+
+ $this->assertSame(
+ $this->xmlFormat(Helpers::nospaces($this->fileContents('query/request-received-by-uuid.xml'))),
$this->xmlFormat($requestBody)
);
diff --git a/tests/_files/query/request-received.xml b/tests/_files/query/request-received-by-filters.xml
similarity index 86%
rename from tests/_files/query/request-received.xml
rename to tests/_files/query/request-received-by-filters.xml
index b12ac5b..ed6be76 100644
--- a/tests/_files/query/request-received.xml
+++ b/tests/_files/query/request-received-by-filters.xml
@@ -3,8 +3,10 @@
-
- EKU9003173C9
+
+
+ EKU9003173C9
+
@@ -14,10 +16,10 @@
- lvCqCw1nWeW7biQuSsjD2KltrQ4=
+ urJ4pg32vV2oozJcBBKRcxoAydo=
- KSTQj+KcLjZEw2iLt2YZn/KB7b96ciHZLci9cHAKl/uGkt7XpQnV1X18ZX9spZZZvlkQyH/gDoEgtMA0yb1oO6ACO66hnfQTaY6b3luhIKrIN9VOdBus6ymrKNhj4mI+ev+HIn1jX1vH8KuVm0lcQ87via8RoOulyvR7lmbuSGILJsshGheofV+eibBdqWe8ukGYYu/iXE9xp+NmI2ltNYizn8fM3wV7F7H51WoJL0lokapcnRk3AeQAbwWw9Yh1dCsb1CqhyRQp6D9fOHpPbQSdhdpdHn774DbH/sqG658Hvx343WrwjDzotLPLVKfGnSTcihDSka6nqXb+EGc4UQ==
+ U0+zQI1YH5DGtlULhm01lGwoBd1vdbIv/myz/gPshujerNvRzzw9mhGCCq8E7BMsLKefbl4TTOOkL5wvFqczzcKrHS8lFTkw7073CIPVrUyhbajCaqDGRtTvHx84xpi83vknZJhuOu+Pl6gyNIu/g4/MSFtSZ9CKqIu62VBAuepGggY2jsceyMIqNhtLOuR9yGSPR2kTABypkIjvyK9NqM/JivCmHV3FXv6280eHcf40gAtHpTw++ERSRuhW/rkimyJrHLIeMvZpfT9JpORsUCbUHmdEOQae0zXHp0mcGV0woWiRKSBcA2yogl+rrqLc1cbsX5I6jfYTdaegcoe0eQ==
diff --git a/tests/_files/query/request-received-by-uuid.xml b/tests/_files/query/request-received-by-uuid.xml
new file mode 100644
index 0000000..d39bad1
--- /dev/null
+++ b/tests/_files/query/request-received-by-uuid.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A0teWlShxOD/65O111KTBA+TOSk=
+
+
+ d0KaOIjhmXRKuSmbqP/tFoyEqBiNwab5rd8L9mCnjg0TxtbRgJz9+5I7LP0JwJiVWlzcPFoOwth68vSmFqr+hEtvpYlYPmUrPMMiheIv+6D28DLErBlZSRmnXuu3EJuI7D29JAMB2MYML8N8n8Y/NOLGhO3qQIJDAa8AjQCIxgokipU9iZsHtDcHcHZOocCFMWNOBTDLdd8TOsi6HNgWEDeUL18nJ7W1QOamQAU3fmKSPF3I37pISu/MHExPayqDZEaDkbKl0u9j8GGSlFyOreLjvkyfZWj9azlu/jyMIy/DwlEeIviPrccc/nnDQ1T3wYrB2QNeSeP7Xb8QCOx+ug==
+
+
+
+ CN=AC UAT,O=SERVICIO DE ADMINISTRACION TRIBUTARIA,OU=SAT-IES Authority,emailAddress=oscar.martinez@sat.gob.mx,street=3ra cerrada de cadiz,postalCode=06370,C=MX,ST=CIUDAD DE MEXICO,L=COYOACAN,x500UniqueIdentifier=2.5.4.45,unstructuredName=responsable: ACDMA-SAT
+ 292233162870206001759766198444326234574038511927
+
+ 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
+
+
+
+
+
+
+