Skip to content

Commit

Permalink
Merge pull request #24 from brazanation/issue-23
Browse files Browse the repository at this point in the history
rename NFeAccessKey to SpedAccessKey
  • Loading branch information
tonicospinelli authored Nov 28, 2016
2 parents e08ce5c + 808e0c5 commit 9d40eae
Show file tree
Hide file tree
Showing 18 changed files with 893 additions and 171 deletions.
23 changes: 15 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,25 @@ catch (InvalidDocumentException $e){
}
```

### Chave NFE (chave da nota fiscal eletrônica)
### Chave de Acesso Sped (chave da NFe, CTe e MDFe)

NFe Access Key
Sped Access Key

Available models:
* NFe
* NFCe
* CTe
* CTeOther
* MDFe

```php
use Brazanation\Documents\NFeAccessKey;
use Brazanation\Documents\Sped\NFe;
use Brazanation\Documents\Exception\InvalidDocument as InvalidDocumentException;

try {
$nfeKey = new NFeAccessKey('52060433009911002506550120000007800267301615');
echo $nfeKey; // prints 52060433009911002506550120000007800267301615
echo $nfeKey->format(); // prints 5206 0433 0099 1100 2506 5501 2000 0007 8002 6730 1615
$accessKey = new NFe('52060433009911002506550120000007800267301615');
echo $accessKey; // prints 52060433009911002506550120000007800267301615
echo $accessKey->format(); // prints 5206 0433 0099 1100 2506 5501 2000 0007 8002 6730 1615
catch (InvalidDocumentException $e){
echo $e->getMessage();
}
Expand All @@ -104,15 +111,15 @@ or generate your number

```php
try {
$nfeKey = NFeAccessKey::generate(
$accessKey = NFe::generate(
52,
\DateTime::createFromFormat('ym', '0604'),
new Cnpj('33009911002506'),
12,
780,
26730161
);
echo $nfeKey; // prints 52060433009911002506550120000007800267301615
echo $accessKey; // prints 52060433009911002506550120000007800267301615
catch (InvalidDocumentException $e){
echo $e->getMessage();
}
Expand Down
24 changes: 23 additions & 1 deletion src/AbstractDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,19 @@
namespace Brazanation\Documents;

use Brazanation\Documents\Exception\InvalidDocument as InvalidDocumentException;

use Brazanation\Documents\Exception\Readonly;

/**
* Class AbstractDocument
*
* @package Brazanation\Documents
*
* @property string $number
* @property string $digit
* @property int $length
* @property int $numberOfDigits
* @property string $type
*/
abstract class AbstractDocument implements DigitCalculable, Formattable
{
/**
Expand Down Expand Up @@ -49,6 +61,16 @@ public function __construct($number, $length, $numberOfDigits, $type)
$this->number = $number;
}

public function __get($name)
{
return $this->$name;
}

public function __set($name, $value)
{
throw Readonly::notAllowed(static::class, $name);
}

/**
* Check if document number is valid.
*
Expand Down
11 changes: 11 additions & 0 deletions src/Exception/Readonly.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Brazanation\Documents\Exception;

class Readonly extends \RuntimeException
{
public static function notAllowed($class, $property)
{
return new static("Not allowed define a new value for {$class}::\${$property}");
}
}
95 changes: 0 additions & 95 deletions src/NFeAccessKey.php

This file was deleted.

156 changes: 156 additions & 0 deletions src/Sped/AbstractAccessKey.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?php

namespace Brazanation\Documents\Sped;

use Brazanation\Documents\AbstractDocument;
use Brazanation\Documents\Cnpj;
use Brazanation\Documents\DigitCalculator;

/**
* Class SpedAccessKey
*
* @package Brazanation\Documents
*
* @property int $state
* @property \DateTime $generatedAt
* @property Cnpj $cnpj
* @property int $model
* @property int $sequence
* @property int $invoiceNumber
* @property int $controlNumber
*/
abstract class AbstractAccessKey extends AbstractDocument
{
const LABEL = 'SpedAccessKey';

const LENGTH = 44;

const REGEX = '/([\d]{4})/';

const MASK = '$1 ';

protected $state;

protected $generatedAt;

protected $cnpj;

protected $model;

protected $sequence;

protected $invoiceNumber;

protected $controlNumber;

/**
* SpedAccessKey constructor.
*
* @param $accessKey
*/
public function __construct($accessKey)
{
$accessKey = preg_replace('/\D/', '', $accessKey);
parent::__construct($accessKey, static::LENGTH, 1, static::LABEL);
$this->loadFromKey($accessKey);
}

private function loadFromKey($accessKey)
{
$startPosition = 0;
$this->state = substr($accessKey, $startPosition, 2);

$startPosition += 2;
$this->generatedAt = \DateTime::createFromFormat('ymd H:i:s', substr($accessKey, $startPosition, 4) . '01 00:00:00');

$startPosition += 4;
$this->cnpj = new Cnpj(substr($accessKey, $startPosition, 14));

$startPosition += 14;
$this->model = new Model(substr($accessKey, $startPosition, 2));

$startPosition += 2;
$this->sequence = substr($accessKey, $startPosition, 3);

$startPosition += 3;
$this->invoiceNumber = substr($accessKey, $startPosition, 9);

$startPosition += 9;
$this->controlNumber = substr($accessKey, $startPosition, 9);

$startPosition += 9;
$this->digit = substr($accessKey, $startPosition, 1);
}

/**
* Generates a valid Sped Access Key.
*
* @param int $state IBGE state code.
* @param \DateTime $generatedAt Year and month when invoice was created.
* @param Cnpj $cnpj Cnpj from issuer.
* @param Model $model Document model.
* @param int $sequence Invoice sequence.
* @param int $invoiceNumber Invoice number.
* @param int $controlNumber Control number.
*
* @return AbstractAccessKey
*/
protected static function generateKey(
$state,
\DateTime $generatedAt,
Cnpj $cnpj,
Model $model,
$sequence,
$invoiceNumber,
$controlNumber
) {
$yearMonth = $generatedAt->format('ym');
$sequence = str_pad($sequence, 3, 0, STR_PAD_LEFT);
$invoiceNumber = str_pad($invoiceNumber, 9, 0, STR_PAD_LEFT);
$controlNumber = str_pad($controlNumber, 9, 0, STR_PAD_LEFT);

$baseNumber = "{$state}{$yearMonth}{$cnpj}{$model}{$sequence}{$invoiceNumber}{$controlNumber}";

$digit = self::calculateDigitFrom($baseNumber);

$instance = new static("{$baseNumber}{$digit}");
$instance->generatedAt = $generatedAt;

return $instance;
}

/**
* {@inheritdoc}
*/
public function format()
{
return trim(preg_replace(self::REGEX, self::MASK, "{$this}"));
}

/**
* {@inheritdoc}
*/
public function calculateDigit($baseNumber)
{
return self::calculateDigitFrom($baseNumber);
}

/**
* Calculate check digit from base number.
*
* It is static because is used from generate static method.
*
* @param string $baseNumber Base numeric section to be calculate your digit.
*
* @return string
*/
public static function calculateDigitFrom($baseNumber)
{
$calculator = new DigitCalculator($baseNumber);
$calculator->useComplementaryInsteadOfModule();
$calculator->withModule(DigitCalculator::MODULE_11);
$digit = $calculator->calculate();

return "{$digit}";
}
}
43 changes: 43 additions & 0 deletions src/Sped/CTe.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Brazanation\Documents\Sped;

use Brazanation\Documents\Cnpj;

final class CTe extends AbstractAccessKey
{
const LABEL = 'CTeAccessKey';

/**
* Generates a valid Sped Access Key.
*
* @param int $state IBGE state code.
* @param \DateTime $generatedAt Year and month when invoice was created.
* @param Cnpj $cnpj Cnpj from issuer.
* @param int $sequence Invoice sequence.
* @param int $invoiceNumber Invoice number.
* @param int $controlNumber Control number.
*
* @return NFe
*/
public static function generate(
$state,
\DateTime $generatedAt,
Cnpj $cnpj,
$sequence,
$invoiceNumber,
$controlNumber
) {
$accessKey = self::generateKey(
$state,
$generatedAt,
$cnpj,
Model::CTe(),
$sequence,
$invoiceNumber,
$controlNumber
);

return new self("{$accessKey}");
}
}
Loading

0 comments on commit 9d40eae

Please sign in to comment.