Skip to content

Commit 3ffa120

Browse files
committed
Version 2.3.0
2 parents 5cf4b11 + d853787 commit 3ffa120

28 files changed

+635
-69
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# eclipxe/CfdiUtils
22

33
[![Source Code][badge-source]][source]
4+
[![Gitter][badge-gitter]][gitter]
45
[![Latest Version][badge-release]][release]
56
[![Software License][badge-license]][license]
67
[![Build Status][badge-build]][build]
@@ -28,7 +29,7 @@ Main features:
2829
- Calculate `Comprobante` sums based on the list of `Conceptos`
2930
- Retrieve the CFDI version information
3031
- Keep a local copy of the three of XSD and XSLT file dependences from SAT
31-
32+
- Check the SAT WebService to get the status of a CDI ('Activo', 'Candelado' & 'No encontrado')
3233

3334
## Installation
3435

@@ -72,6 +73,7 @@ and licensed for use under the MIT License (MIT). Please see [LICENSE][] for mor
7273
[documentation]: https://github.com/eclipxe13/CfdiUtils/wiki
7374

7475
[source]: https://github.com/eclipxe13/CfdiUtils
76+
[gitter]: https://gitter.im/eclipxe13/php-cfdi
7577
[release]: https://github.com/eclipxe13/CfdiUtils/releases
7678
[license]: https://github.com/eclipxe13/CfdiUtils/blob/master/LICENSE
7779
[build]: https://travis-ci.org/eclipxe13/CfdiUtils?branch=master
@@ -81,6 +83,7 @@ and licensed for use under the MIT License (MIT). Please see [LICENSE][] for mor
8183
[downloads]: https://packagist.org/packages/eclipxe/CfdiUtils
8284

8385
[badge-source]: http://img.shields.io/badge/source-eclipxe13/CfdiUtils-blue.svg?style=flat-square
86+
[badge-gitter]: https://img.shields.io/gitter/room/nwjs/nw.js.svg?style=flat-square
8487
[badge-release]: https://img.shields.io/github/release/eclipxe13/CfdiUtils.svg?style=flat-square
8588
[badge-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square
8689
[badge-build]: https://img.shields.io/travis/eclipxe13/CfdiUtils/master.svg?style=flat-square

composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
],
1818
"require": {
1919
"php": ">=7.0",
20+
"ext-libxml": "*",
21+
"ext-openssl": "*",
22+
"ext-soap": "*",
2023
"eclipxe/xmlresourceretriever": "^1.2",
2124
"eclipxe/xmlschemavalidator": "^2.0"
2225
},
@@ -29,7 +32,7 @@
2932
"jakub-onderka/php-parallel-lint": "^0.9",
3033
"squizlabs/php_codesniffer": "^3.0",
3134
"friendsofphp/php-cs-fixer": "^2.4",
32-
"phpstan/phpstan-shim": "^0.8.5"
35+
"phpstan/phpstan-shim": "^0.9.1"
3336
},
3437
"autoload": {
3538
"psr-4": {

docs/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
# Version 2.3.0 2018-01-25
2+
- Add a client `\CfdiUtils\ConsultaCfdiSat\WebService` for the SAT WebService
3+
https://consultaqr.facturaelectronica.sat.gob.mx/ConsultaCFDIService.svc?singleWsdl
4+
- Fix bug, must use `children()` method instead of `children` property.
5+
Did not appears before because the variable using the property was always
6+
a `Node` but other implementation of `NodeInterface` would cause this to break.
7+
- Add a lot of fixes in docblocks to move `@param $var` to `@param type $var`.
8+
- Add extensions requirements to composer.json: libxml, openssl & soap.
9+
- Upgrade `phpstan/phpstan-shim` to version 0.9.1, the not-simple-to-see bug fixed
10+
in this version was found by `phpstan` - https://github.com/phpstan/phpstan
11+
12+
113
# Version 2.2.0 2018-01-24
214
- Refactor namespace `\CfdiUtils\CadenaOrigen` (backwards compatible):
315
- Instead of one only xslt builder now it includes:
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
namespace CfdiUtils\ConsultaCfdiSat;
3+
4+
class Config
5+
{
6+
const DEFAULT_WSDL_URL = 'https://consultaqr.facturaelectronica.sat.gob.mx/ConsultaCFDIService.svc?singleWsdl';
7+
8+
/** @var int */
9+
private $timeout;
10+
11+
/** @var bool */
12+
private $verifyPeer;
13+
14+
/** @var string */
15+
private $wsdlUrl;
16+
17+
public function __construct(int $timeout = 10, bool $verifyPeer = true, string $wsdlUrl = '')
18+
{
19+
$this->timeout = $timeout;
20+
$this->verifyPeer = $verifyPeer;
21+
$this->wsdlUrl = $wsdlUrl ? : static::DEFAULT_WSDL_URL;
22+
}
23+
24+
public function getTimeout(): int
25+
{
26+
return $this->timeout;
27+
}
28+
29+
public function shouldVerifyPeer(): bool
30+
{
31+
return $this->verifyPeer;
32+
}
33+
34+
public function getWsdlUrl(): string
35+
{
36+
return $this->wsdlUrl;
37+
}
38+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
namespace CfdiUtils\ConsultaCfdiSat;
3+
4+
class RequestParameters
5+
{
6+
/** @var string */
7+
private $version;
8+
9+
/** @var string */
10+
private $rfcEmisor;
11+
12+
/** @var string */
13+
private $rfcReceptor;
14+
15+
/** @var string */
16+
private $total;
17+
18+
/** @var float */
19+
private $totalFloat;
20+
21+
/** @var string */
22+
private $uuid;
23+
24+
/** @var string */
25+
private $sello;
26+
27+
public function __construct(
28+
string $version,
29+
string $rfcEmisor,
30+
string $rfcReceptor,
31+
string $total,
32+
string $uuid,
33+
string $sello = ''
34+
) {
35+
$this->setVersion($version);
36+
$this->rfcEmisor = $rfcEmisor;
37+
$this->rfcReceptor = $rfcReceptor;
38+
$this->total = $total;
39+
$this->totalFloat = (float) trim(str_replace(',', '', $this->total));
40+
$this->uuid = $uuid;
41+
$this->sello = $sello;
42+
}
43+
44+
public function getVersion(): string
45+
{
46+
return $this->version;
47+
}
48+
49+
public function setVersion(string $version)
50+
{
51+
if (! in_array($version, ['3.2', '3.3'], true)) {
52+
throw new \UnexpectedValueException('The version is not allowed');
53+
}
54+
$this->version = $version;
55+
}
56+
57+
public function getRfcEmisor(): string
58+
{
59+
return $this->rfcEmisor;
60+
}
61+
62+
public function getRfcReceptor(): string
63+
{
64+
return $this->rfcReceptor;
65+
}
66+
67+
public function getTotal(): string
68+
{
69+
return $this->total;
70+
}
71+
72+
public function getTotalFloat(): float
73+
{
74+
return $this->totalFloat;
75+
}
76+
77+
public function getUuid(): string
78+
{
79+
return $this->uuid;
80+
}
81+
82+
public function getSello(): string
83+
{
84+
return $this->sello;
85+
}
86+
87+
public function expression(): string
88+
{
89+
if ('3.3' === $this->version) {
90+
return $this->expressionVersion33();
91+
}
92+
if ('3.2' === $this->version) {
93+
return $this->expressionVersion32();
94+
}
95+
return '';
96+
}
97+
98+
public function expressionVersion32(): string
99+
{
100+
return '?' . implode('&', [
101+
're=' . strval($this->rfcEmisor),
102+
'rr=' . strval($this->rfcReceptor),
103+
'tt=' . str_pad(trim(number_format($this->totalFloat, 6, '.', ''), '0'), 17, '0', STR_PAD_LEFT),
104+
'id=' . strval($this->uuid),
105+
]);
106+
}
107+
108+
public function expressionVersion33(): string
109+
{
110+
return 'https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?' . implode('&', [
111+
'id=' . strval($this->uuid),
112+
're=' . strval($this->rfcEmisor),
113+
'rr=' . strval($this->rfcReceptor),
114+
'tt=' . trim(number_format($this->totalFloat, 6, '.', ''), '0'),
115+
'fe=' . substr($this->sello, -8),
116+
]);
117+
}
118+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
namespace CfdiUtils\ConsultaCfdiSat;
3+
4+
class StatusResponse
5+
{
6+
/** @var string */
7+
private $code;
8+
9+
/** @var string */
10+
private $cfdi;
11+
12+
public function __construct(string $statusCode, string $status)
13+
{
14+
$this->code = $statusCode;
15+
$this->cfdi = $status;
16+
}
17+
18+
public function getCode(): string
19+
{
20+
return $this->code;
21+
}
22+
23+
public function getCfdi(): string
24+
{
25+
return $this->cfdi;
26+
}
27+
28+
public function responseWasOk(): bool
29+
{
30+
return ('S - ' === substr($this->code, 0, 4));
31+
}
32+
33+
public function isVigente(): bool
34+
{
35+
return ('Vigente' === $this->cfdi);
36+
}
37+
38+
public function isNotFound(): bool
39+
{
40+
return ('No Encontrado' === $this->cfdi);
41+
}
42+
43+
public function isCancelled(): bool
44+
{
45+
return ('Cancelado' === $this->cfdi);
46+
}
47+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
namespace CfdiUtils\ConsultaCfdiSat;
3+
4+
use SoapClient;
5+
6+
class WebService
7+
{
8+
/** @var SoapClient|null */
9+
private $soapClient;
10+
11+
/** @var Config */
12+
private $config;
13+
14+
public function __construct(Config $config = null)
15+
{
16+
$this->config = $config ? : new Config();
17+
}
18+
19+
public function getConfig(): Config
20+
{
21+
return $this->config;
22+
}
23+
24+
public function getSoapClient(): SoapClient
25+
{
26+
if (! $this->soapClient instanceof SoapClient) {
27+
$this->soapClient = $this->createSoapClient();
28+
}
29+
return $this->soapClient;
30+
}
31+
32+
public function destroySoapClient()
33+
{
34+
$this->soapClient = null;
35+
}
36+
37+
protected function createSoapClient(): SoapClient
38+
{
39+
$config = $this->getConfig();
40+
$soapOptions = [
41+
'soap_version' => SOAP_1_1,
42+
'cache_wsdl' => WSDL_CACHE_NONE,
43+
'exceptions' => 1,
44+
'stream_context' => stream_context_create([
45+
'ssl' => [
46+
'verify_peer' => $config->shouldVerifyPeer(),
47+
],
48+
]),
49+
'connection_timeout' => $config->getTimeout(),
50+
'trace' => false, // use this setting for development
51+
];
52+
53+
return new SoapClient($config->getWsdlUrl(), $soapOptions);
54+
}
55+
56+
public function request(RequestParameters $requestParameters): StatusResponse
57+
{
58+
$parameters = (object) [
59+
'expresionImpresa' => $requestParameters->expression(),
60+
];
61+
$rawResponse = $this->getSoapClient()->{'Consulta'}($parameters);
62+
if (! $rawResponse instanceof \stdClass) {
63+
throw new \RuntimeException('The consulta web service did not return any result');
64+
}
65+
return $this->rawResultToConsultaResponse($rawResponse);
66+
}
67+
68+
protected function rawResultToConsultaResponse(\stdClass $rawResponse): StatusResponse
69+
{
70+
if (! isset($rawResponse->{'ConsultaResult'})) {
71+
throw new \RuntimeException('The consulta web service did not have expected ConsultaResult');
72+
}
73+
$result = (array) $rawResponse->{'ConsultaResult'};
74+
if (! isset($result['CodigoEstatus'])) {
75+
throw new \RuntimeException('The consulta web service did not have expected ConsultaResult:CodigoEstatus');
76+
}
77+
if (! isset($result['Estado'])) {
78+
throw new \RuntimeException('The consulta web service did not have expected ConsultaResult:Estado');
79+
}
80+
return new StatusResponse($result['CodigoEstatus'], $result['Estado']);
81+
}
82+
}

src/CfdiUtils/Nodes/Attributes.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public function exportArray(): array
7272
}
7373

7474
/**
75-
* @param $value
75+
* @param mixed $value
7676
* @return string|null
7777
*/
7878
private function castValueToString($value)

src/CfdiUtils/Nodes/Node.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public function searchNode(string ...$searchPath)
106106
{
107107
$node = $this;
108108
foreach ($searchPath as $searchName) {
109-
$node = $node->children->firstNodeWithName($searchName);
109+
$node = $node->children()->firstNodeWithName($searchName);
110110
if (null === $node) {
111111
break;
112112
}

tests/CfdiUtilsTests/CadenaOrigen/GenericBuilderTestCase.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ public function providerCfdiToCadenaOrigen()
2727
}
2828

2929
/**
30-
* @param $xmlLocation
31-
* @param $expectedTransformation
32-
* @param $xsltLocation
30+
* @param string $xmlLocation
31+
* @param string $expectedTransformation
32+
* @param string $xsltLocation
3333
* @dataProvider providerCfdiToCadenaOrigen
3434
*/
3535
public function testCfdiToCadenaOrigen($xmlLocation, $expectedTransformation, $xsltLocation)

0 commit comments

Comments
 (0)