Skip to content

Commit f673f3c

Browse files
authored
Merge pull request #2 from eclipxe13/master
Version 2.0.0
2 parents 2529d85 + 4d69cce commit f673f3c

15 files changed

+219
-48
lines changed

.php_cs.dist

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ declare(strict_types=1);
44

55
return PhpCsFixer\Config::create()
66
->setRiskyAllowed(true)
7-
->setCacheFile(__DIR__.'/build/.php_cs.cache')
7+
->setCacheFile(__DIR__ . '/build/.php_cs.cache')
88
->setRules([
99
'@PSR2' => true,
1010
'@PHP70Migration' => true,

.scrutinizer.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ build:
88
analysis:
99
environment:
1010
php:
11-
version: 7.3
11+
version: "7.3"
1212
project_setup:
1313
override: true
1414
tests:

.travis.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ sudo: false
66

77
# php compatibility
88
php:
9-
- 7.2
10-
- 7.3
9+
- "7.2"
10+
- "7.3"
1111

1212
cache:
1313
- directories:

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ composer require phpcfdi/cfdi-expresiones
5353

5454
```php
5555
<?php
56-
use PhpCfdi\CfdiExpresiones\ExpressionExtractor;
56+
use PhpCfdi\CfdiExpresiones\DiscoverExtractor;
5757

5858
// creamos el extractor
59-
$extractor = new ExpressionExtractor();
59+
$extractor = new DiscoverExtractor();
6060

6161
// abrimos el documento en un DOMDocument
6262
$document = new DOMDocument();

docs/CHANGELOG.md

+10-12
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
# CHANGELOG
22

3-
## About SemVer
4-
5-
In summary, [SemVer](https://semver.org/) can be viewed as ` Breaking . Feature . Fix `, where:
6-
7-
- Breaking version = includes incompatible changes to the API
8-
- Feature version = adds new feature(s) in a backwards-compatible manner
9-
- Fix version = includes backwards-compatible bug fixes
10-
11-
**Non breaking changes (doesn't apply any of the SemVer rules)**
12-
13-
- Version `0.x.x`
14-
- Library elements with annotation `@internal` doesn't apply any of the SemVer rules
3+
## Version 2.0.0 2019-03-28
4+
5+
- Allows to create an expression with format fixes from specific types
6+
- Change `ExpressionExtractorInterface` to add `public function format(array $values): string`
7+
- Give a unique name for extractors, so when discovering by type can obtain an item
8+
- Change `ExpressionExtractorInterface` to add `public function uniqueName(): string`
9+
- `Comprobante33` uses `CFDI33`
10+
- `Comprobante32` uses `CFDI32`
11+
- `Retenciones10` uses `RET10`
12+
- Rename `ExpressionExtractor` to `DiscoverExtractor`, it makes more sense
1513

1614

1715
## Version 1.0.0 2019-03-27

docs/SEMVER.md

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# SEMVER
2+
3+
Respetamos el estándar [Versionado Semántico 2.0.0](https://semver.org/lang/es/).
4+
5+
En resumen, [SemVer](https://semver.org/) es un sistema de versiones de tres componentes `X.Y.Z`
6+
que nombraremos así: ` Breaking . Feature . Fix `, donde:
7+
8+
- `Breaking`: Rompe la compatibilidad de código con versiones anteriores.
9+
- `Feature`: Agrega una nueva característica que es compatible con lo anterior.
10+
- `Fix`: Incluye algún cambio (generalmente correcciones) que no agregan nueva funcionalidad.
11+
12+
## Composer
13+
14+
[Composer](https://getcomposer.org/) es un gestor de dependencias en proyectos para PHP.
15+
Este gestor usa las [reglas](https://getcomposer.org/doc/articles/versions.md)
16+
de versionado semántico para instalar y actualizar paquetes.
17+
18+
Te recomendamos instalar dependencias de librerías (no frameworks) con *Caret Version Range*.
19+
Por ejemplo: `"vendor/package": "^2.5"`.
20+
21+
Esto significa que:
22+
23+
- no debe actualizar a versiones `3.x.x`
24+
- no debe utilizar ninguna versión menor a `2.5.0`
25+
26+
## Versiones 0.x.y no rompe compatibilidad
27+
28+
Las versiones que inician con cero, por ejemplo `0.y.z`, no se ajustan a las reglas de versionado.
29+
Se considera que estas versiones son previas a la madurez del proyecto y por lo tanto
30+
introducen cambios sin previo aviso.
31+
32+
## `@internal` no rompe compatibilidad
33+
34+
Si la librería contiene elementos marcados como `@internal` significa que no deben ser utilizados
35+
por tu código. Son partes de código internos de la librería.
36+
Por lo tanto, no se consideran breaking changes.
37+
38+
Cuando un elemento es `@internal`, dicho elemento:
39+
40+
- no debe ser una entrada (parámetro)
41+
- no debe ser una salida (retorno)
42+
- no debe exponer exponer funcionalidades en los objetos públicos (rasgos)

src/ExpressionExtractor.php renamed to src/DiscoverExtractor.php

+28-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use PhpCfdi\CfdiExpresiones\Extractors\Comprobante33;
1111
use PhpCfdi\CfdiExpresiones\Extractors\Retenciones10;
1212

13-
class ExpressionExtractor implements ExpressionExtractorInterface
13+
class DiscoverExtractor implements ExpressionExtractorInterface
1414
{
1515
/** @var ExpressionExtractorInterface[] */
1616
private $expressions;
@@ -35,11 +35,22 @@ public function defaultExtractors(): array
3535
];
3636
}
3737

38+
/** @return ExpressionExtractorInterface[] */
3839
public function currentExpressionExtractors(): array
3940
{
4041
return $this->expressions;
4142
}
4243

44+
protected function findByUniqueName(string $uniqueName): ?ExpressionExtractorInterface
45+
{
46+
foreach ($this->expressions as $expression) {
47+
if ($uniqueName === $expression->uniqueName()) {
48+
return $expression;
49+
}
50+
}
51+
return null;
52+
}
53+
4354
protected function findMatch(DOMDocument $document): ?ExpressionExtractorInterface
4455
{
4556
foreach ($this->expressions as $expression) {
@@ -54,7 +65,7 @@ protected function getFirstMatch(DOMDocument $document): ExpressionExtractorInte
5465
{
5566
$discovered = $this->findMatch($document);
5667
if (null === $discovered) {
57-
throw new UnmatchedDocumentException('Cannot discover any ExpressionExtractor that matches with document');
68+
throw new UnmatchedDocumentException('Cannot discover any DiscoverExtractor that matches with document');
5869
}
5970
return $discovered;
6071
}
@@ -64,9 +75,24 @@ public function matches(DOMDocument $document): bool
6475
return (null !== $this->findMatch($document));
6576
}
6677

78+
public function uniqueName(): string
79+
{
80+
return 'discover';
81+
}
82+
6783
public function extract(DOMDocument $document): string
6884
{
6985
$discovered = $this->getFirstMatch($document);
7086
return $discovered->extract($document);
7187
}
88+
89+
public function format(array $values, $type = ''): string
90+
{
91+
$extractor = $this->findByUniqueName($type);
92+
if (null === $extractor) {
93+
throw new UnmatchedDocumentException('DiscoverExtractor requires type key with an extractor identifier');
94+
}
95+
unset($values['type']);
96+
return $extractor->format($values);
97+
}
7298
}

src/ExpressionExtractorInterface.php

+10
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,17 @@
88

99
interface ExpressionExtractorInterface
1010
{
11+
public function uniqueName(): string;
12+
1113
public function matches(DOMDocument $document): bool;
1214

1315
public function extract(DOMDocument $document): string;
16+
17+
/**
18+
* Format an expression based on given values
19+
*
20+
* @param array<string, string> $values
21+
* @return string
22+
*/
23+
public function format(array $values): string;
1424
}

src/Extractors/Comprobante32.php

+22-6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ public function __construct()
2020
$this->matchDetector = new MatchDetector('http://www.sat.gob.mx/cfd/3', 'cfdi:Comprobante', 'version', '3.2');
2121
}
2222

23+
public function uniqueName(): string
24+
{
25+
return 'CFDI32';
26+
}
27+
2328
public function matches(DOMDocument $document): bool
2429
{
2530
return $this->matchDetector->matches($document);
@@ -35,16 +40,27 @@ public function extract(DOMDocument $document): string
3540
$uuid = $helper->getAttribute('cfdi:Comprobante', 'cfdi:Complemento', 'tfd:TimbreFiscalDigital', 'UUID');
3641
$rfcEmisor = $helper->getAttribute('cfdi:Comprobante', 'cfdi:Emisor', 'rfc');
3742
$rfcReceptor = $helper->getAttribute('cfdi:Comprobante', 'cfdi:Receptor', 'rfc');
38-
$totalComprobante = $helper->getAttribute('cfdi:Comprobante', 'total');
43+
$total = $helper->getAttribute('cfdi:Comprobante', 'total');
3944

40-
return '?' . implode('&', [
41-
're=' . $rfcEmisor,
42-
'rr=' . $rfcReceptor,
43-
'tt=' . $this->formatTotal($totalComprobante),
44-
'id=' . $uuid,
45+
return $this->format([
46+
're' => $rfcEmisor,
47+
'rr' => $rfcReceptor,
48+
'tt' => $total,
49+
'id' => $uuid,
4550
]);
4651
}
4752

53+
public function format(array $values): string
54+
{
55+
return '?'
56+
. implode('&', [
57+
're=' . ($values['re'] ?? ''),
58+
'rr=' . ($values['rr'] ?? ''),
59+
'tt=' . $this->formatTotal($values['tt'] ?? ''),
60+
'id=' . ($values['id'] ?? ''),
61+
]);
62+
}
63+
4864
public function formatTotal(string $input): string
4965
{
5066
return str_pad(number_format(floatval($input), 6, '.', ''), 17, '0', STR_PAD_LEFT);

src/Extractors/Comprobante33.php

+24-9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ public function __construct()
2020
$this->matchDetector = new MatchDetector('http://www.sat.gob.mx/cfd/3', 'cfdi:Comprobante', 'Version', '3.3');
2121
}
2222

23+
public function uniqueName(): string
24+
{
25+
return 'CFDI33';
26+
}
27+
2328
public function matches(DOMDocument $document): bool
2429
{
2530
return $this->matchDetector->matches($document);
@@ -35,20 +40,30 @@ public function extract(DOMDocument $document): string
3540
$uuid = $helper->getAttribute('cfdi:Comprobante', 'cfdi:Complemento', 'tfd:TimbreFiscalDigital', 'UUID');
3641
$rfcEmisor = $helper->getAttribute('cfdi:Comprobante', 'cfdi:Emisor', 'Rfc');
3742
$rfcReceptor = $helper->getAttribute('cfdi:Comprobante', 'cfdi:Receptor', 'Rfc');
38-
$totalComprobante = $helper->getAttribute('cfdi:Comprobante', 'Total');
43+
$total = $helper->getAttribute('cfdi:Comprobante', 'Total');
3944
$sello = substr($helper->getAttribute('cfdi:Comprobante', 'Sello'), -8);
4045

41-
$total = $this->formatTotal($totalComprobante);
42-
43-
return 'https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?' . implode('&', [
44-
'id=' . $uuid,
45-
're=' . $rfcEmisor,
46-
'rr=' . $rfcReceptor,
47-
'tt=' . $total,
48-
'fe=' . substr($sello, -8),
46+
return $this->format([
47+
'id' => $uuid,
48+
're' => $rfcEmisor,
49+
'rr' => $rfcReceptor,
50+
'tt' => $total,
51+
'fe' => substr($sello, -8),
4952
]);
5053
}
5154

55+
public function format(array $values): string
56+
{
57+
return 'https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?'
58+
. implode('&', [
59+
'id=' . ($values['id'] ?? ''),
60+
're=' . ($values['re'] ?? ''),
61+
'rr=' . ($values['rr'] ?? ''),
62+
'tt=' . $this->formatTotal($values['tt'] ?? ''),
63+
'fe=' . ($values['fe'] ?? ''),
64+
]);
65+
}
66+
5267
public function formatTotal(string $input): string
5368
{
5469
$total = rtrim(number_format(floatval($input), 6, '.', ''), '0');

src/Extractors/Retenciones10.php

+32-6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public function __construct()
2626
);
2727
}
2828

29+
public function uniqueName(): string
30+
{
31+
return 'RET10';
32+
}
33+
2934
public function matches(DOMDocument $document): bool
3035
{
3136
return $this->matchDetector->matches($document);
@@ -76,12 +81,33 @@ public function extract(DOMDocument $document): string
7681
$helper->getAttribute('retenciones:Retenciones', 'retenciones:Totales', 'montoTotOperacion')
7782
);
7883

79-
return '?' . implode('&', array_filter([
80-
're=' . $rfcEmisor,
81-
$rfcReceptorKey . '=' . $rfcReceptor,
82-
'tt=' . $this->formatTotal($total),
83-
'id=' . $uuid,
84-
]));
84+
return $this->format([
85+
're' => $rfcEmisor,
86+
$rfcReceptorKey => $rfcReceptor,
87+
'tt' => $this->formatTotal($total),
88+
'id' => $uuid,
89+
]);
90+
}
91+
92+
public function format(array $values): string
93+
{
94+
$receptorKey = 'rr';
95+
if (isset($values['nr'])) {
96+
$receptorKey = 'nr';
97+
$values['nr'] = $this->formatForeignTaxId($values['nr']);
98+
}
99+
return '?'
100+
. implode('&', [
101+
're=' . ($values['re'] ?? ''),
102+
$receptorKey . '=' . ($values[$receptorKey] ?? ''),
103+
'tt=' . $this->formatTotal($values['tt'] ?? ''),
104+
'id=' . ($values['id'] ?? ''),
105+
]);
106+
}
107+
108+
public function formatForeignTaxId(string $foreignTaxId): string
109+
{
110+
return str_pad($foreignTaxId, 20, '0', STR_PAD_LEFT);
85111
}
86112

87113
public function formatTotal(string $input): string

0 commit comments

Comments
 (0)