%global _empty_manifest_terminate_build 0
Name: python-bradocs4py
Version: 1.3.1.0
Release: 1
Summary: Implementa a funcionalidade validar_inscao_estadual.
License: MIT
URL: https://github.com/namio/BRADocs4Py.git
Source0: https://mirrors.nju.edu.cn/pypi/web/packages/55/d0/b448136daeec51703d557700540749d1ec7a4d734997b040c1d233e27ae1/bradocs4py-1.3.1.0.tar.gz
BuildArch: noarch
%description
[![PyPI](https://img.shields.io/pypi/v/BRADocs4Py.svg)](https://pypi.org/project/bradocs4py/)
[![GitHub top language](https://img.shields.io/github/languages/top/namio/BRADocs4Py.svg)](https://github.com/namio/BRADocs4Py.git)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/BRADocs4Py.svg)](https://pypi.org/project/bradocs4py/)
[![PyPI - Wheel](https://img.shields.io/pypi/wheel/BRADocs4Py.svg)](https://pypi.org/project/bradocs4py/)
[![PyPI - Implementation](https://img.shields.io/pypi/implementation/BRADocs4Py.svg)](https://pypi.org/project/bradocs4py/)
[![GitHub](https://img.shields.io/github/license/namio/BRADocs4Py.svg)](https://github.com/namio/BRADocs4Py/blob/master/LICENSE)
[![GitHub last commit](https://img.shields.io/github/last-commit/namio/BRADocs4PY.svg)](https://github.com/namio/BRADocs4Py.git)
[![Say Thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/namio)
# BRADocs4Py
BRADocs4Py é uma biblioteca que visa fornecer componentes para trabalhar com tipos de dados específicos da realidade brasileira.
Esta biblioteca surgiu mediante a necessidade de se ter tipos específicos que possibilitem lidar com documentos de identificação próprios do Brasil, como é o caso do Cadastro de Pessoa Física (CPF) e do Cadastro Nacional de Pessoa Jurídica (CNPJ).
Além de conter classes que representam o modelo computacional dos principais documentos brasileiros, esta biblioteca também disponibiliza classes que permitem a validação e a geração de números válidos para estes documentos; sendo estas últimas disponibilizadas exclusivamente para fins de testes computacionais.
> This software is coded and documented in portuguese only as it is intended to be used to generate the necessary files for the brazilian government regarding to digital bookkeeping.
## Requisitos
* python
## Como instalar
$ pip install bradocs4py
## Objetivos do Projeto
A ideia inicial do projeto e unificar em uma única biblioteca módulos que permitam representar computacionalmente e validar documentos brasileiros - inicialmente CPF e CNPJ, além de permitir a geração de números válidos para estes documentos.
## Compatibilidade do Projeto
O projeto inicialmente suportará apenas Python 3.6.5+.
Outras linguagens de programação poderão ter versões especificas conforme minha disponibilidade de tempo.
## Status do Projeto
O projeto está em fase inicial de desenvolvimento.
| Módulo | Situação |
|:------------------------------------|:---------------:|
| [DocumentoIdentificacao](#di) |Funcional |
| [CPF](#cpf) |Funcional |
| [ValidadorCpf](#vcpf) |Funcional |
| [GeradorCpf](#gcpf) |Funcional |
| [Cnpj](#cnpj) |Funcional |
| [ValidadorCnpj](#vcnpj) |Funcional |
| [GeradorCnpj](#gcnpj) |Funcional |
| [InscricaoEstadual](#ie) |Funcional |
| [ValidadorInscricaoEstadual](#vie) |Funcional |
| [GeradorInscricaoEstadual](#gie) |Não implementado |
| [InscricaoSuframa](#is) |Funcional |
| [ValidadorSuframa](#vs) |Funcional |
| [GeradorSuframa](#gs) |Funcional |
| [ChaveAcessoNFe](#chave) |Funcional |
| [ValidadorChaveAcessoNFe](#vchave) |Funcional |
| [GeradorChaveAcessoNFe](#gchave) |Funcional |
| [GTIN](#gtin) |Funcional |
| [ValidadorGTIN](#vgtin) |Funcional |
| [GeradorGTIN](#ggtin) |Funcional |
### DocumentoIdentificacao
Classe abstrata, não podendo ser instanciada diretamente, serve como base para todas as classes que representam um documento de identificação ou qualquer outro documento brasileiro que necessite de validação.
### CPF
Classe usada para representar em código Pyhton um _Cadastro de Pessoa Física_ (CPF); permitindo representá-lo textualmente, com a devida formatação e identificar a sua validade.
#### Utilização
>>> cpf = CPF('52513127765')
>>> cpf
'525.131.277-65'
>>> cpf.isValid
True
>>> cpf.rawValue
52513127765
>>> cpf = CPF('abcdefghijk')
>>> cpf.isValid
False
>>> print(cpf)
abcdefghijk
>>> print(cpf.rawValue)
abcdefghijk
> Independente do conteúdo passado ao se criar uma instância de CPF, **sempre** obter-se-á uma instância deste. Caberá consultar a propriedade __isValid__ de uma instância de CPF para verificar se esta é válida ou não.
> A representação textual de uma instância de CPF só será exibida caso esta instância contenha um número válido de CPF; ao contrário será exibida a _string_ utilizada para criá-la.
> Para obter a _string_ utilizada ao instanciar um CPF, basta acessar a propriedade **rawValue** da instância criada.
### ValidadorCpf
Classe responsável por validar uma instância de CPF ou uma _string_ contendo a representação numérica de um CPF.
#### Utilização
>>> cpf = CPF('abcdefghijk')
>>> ValidadorCpf.validar(cpf)
False
>>> ValidadorCpf.validar('123.456.789-00')
False
Foi criado um CPF válido, porém foi digitado um caractere de separação diferente dos caracteres esperados (.-/ ). Mesmo assim, o validador informa tratar-se de um CPF correto
>>> cpf = CPF('508,697,212-40')
>>> ValidadorCpf.validar(cpf)
True
### GeradorCpf
Classe responsável por gerar aleatoriamente um CPF válido.
#### Utilização
>>> cpf = GeradorCpf.gerar()
>>> cpf.isValid
True
### Cnpj
Classe usada para representar em código Pyhton um _Cadastro Nacional de Pessoa Jurídica_ (CNPJ); permitindo representá-lo textualmente, com a devida formatação e identificar a sua validade.
#### Utilização
>>> cnpj = Cnpj('abcdefghijklmn')
>>> cnpj.isValid
False
>>> cnpj = Cnpj('12345678901234')
>>> cnpj.isValid
False
>>> cnpj = Cnpj('19.658.147/0001-0O')
>>> cnpj.isValid
False
>>> cnpj = Cnpj('19.658.147/0001-00')
>>> cnpj.isValid
True
> Independente do conteúdo passado ao se criar uma instância de CNPJ, **sempre** obter-se-á uma instância deste. Caberá consultar a propriedade __isValid__ de uma instância de CNPJ para verificar se esta é válida ou não.
> A representação textual de uma instância de CNPJ só será exibida caso esta instância contenha um número válido de CNPJ; ao contrário será exibida a _string_ utilizada para criá-la.
> Para obter a _string_ utilizada ao instanciar um CNPJ, basta acessar a propriedade **rawValue** da instância criada.
### ValidadorCnpj
Classe responsável por validar uma instância de CNPJ ou uma _string_ contendo a representação numérica de um CNPJ.
#### Utilização
>>> cnpj = Cnpj('abcdefghijklmn')
>>> ValidadorCnpj.validar(cnpj)
False
>>> cnpj = Cnpj('19.658.147/0001-0O')
>>>ValidadorCnpj.validar(cnpj)
False
>>> ValidadorCnpj.validar('12345678901234')
False
>>> cnpj = Cnpj('34 633 423,0001/60')
>>> ValidadorCnpj.validar(cnpj)
True
>>> ValidadorCnpj.validar('05.692.744/0001-38')
True
### GeradorCnpj
Classe responsável por gerar aleatoriamente um CNPJ válido.
#### Utilização
>>> cnpj = GeradorCnpj.gerar()
>>> cnpj.isValid
True
### InscricaoSuframa
Representa o número de inscrição na Superintendência da Zona Franca de Manaus (SUFRAMA)
> A SUFRAMA mantém controle sobre as empresas com insentivo fiscal, identificando-as através do número de _Inscrição SUFRAMA_.
A composição deste indicador é: _SS.NNNN.LLD_, onde:
**SS** representa o __código do setor de atividade__ da empresa, conforme exemplo abaixo:
| Código | Descrição |
| :----: | :---------------------------|
| 01 e 02 | Cooperativa |
| 10 e 11 | Comércio |
| 20 | Indústria com projeto pleno |
| 60 | Serviços |
**NNNN** número sequencial
**LL** representa o código da licalidade da Unidade Administrativa da Suframa que habilitou a empresa, conforme exemplo abaixo:
| Código | Descrição |
| :----: | :-----------|
| 01 | Manaus |
| 10 | Boa Vista |
| 30 | Porto Velho |
**D** dígito verificador
#### Validação
* Campo numérico com 9 posições (incluindo o dígito verificador).
* Pode iniciar por 0 (zero), mas não pode iniciar por 00.
* Dígito verificador calculado por [__módulo 11__](https://pt.wikipedia.org/wiki/D%C3%ADgito_verificador#Módulo_11 "Método de cálculo do dígito verificador usando Módulo 11"), pesos 2 a 9.
#### Utilização
>>> x = InscricaoSuframa('01.1234.129')
>>> x.rawValue
'011234129'
>>> print(x)
01.1234.129
>>> x.isValid
False
>>> x = InscricaoSuframa('101580100')
>>> x.rawValue
'101580100'
>>> print(x)
10.1580.100
>>> x.isValid
True
>>> x = InscricaoSuframa('1015801OO')
>>> x.rawValue
'1015801OO'
>>> print(x)
1015801OO
>>> x.isValid
False
### ValidadorSuframa
Valida uma instância de InscricaoSuframa ou uma _string_ contendo a representação numérica de uma Inscrição Suframa.
#### Utilização
# Validação de uma _string_ representando uma Inscrição Suframa:
>>> ValidadorSuframa.validar('101580100')
True
# Validação de uma _string_ representando uma Inscrição Suframa inválida (contendo caracteres não numéricos):
>>> ValidadorSuframa.validar('1015801OO')
False
# Validação de uma instância de InscriçãoSuframa:
>>> x = InscricaoSuframa('01.1234.129')
>>> ValidadorSuframa.validar(x)
False
### GeradorSuframa
Gera aleatoriamente uma Inscrição Suframa válida
>>> x = GeradorSuframa.gerar()
>>> x.isValid
True
> **IMPORTANTE**: O __GeradorSuframa__ tem por objetivo ajudar estudantes, programadores, analistas de sistemas e testadores de código a gerar Inscrições Suframa válidas visando auxiliar as rotinas de testes de softwares em desenvolvimento.
> A má utilização dos dados gerados pelo __GeradorSuframa__ é de **total responsabilidade do usuário** desta biblioteca.
> As inscrições são geradas de forma aleatória, respeitando as leis de formação estabelecidas pela SUFRAMA.
### InscricaoEstadual
Representa, em código Pyhton, uma _Inscrição Estadual_ (IE), ou o registro do contribuinte no cadastro do ICMS mantido pela Receita Estadual; permitindo representá-lo textualmente, com a devida formatação e identificar a sua validade.
#### Utilização
>>> ie = InscricaoEstadual('613.855.219.926', 'SP')
>>> ie.isValid
True
>>> ie.rawValue
'613855219926'
>>> ie.UF
'SP'
>>> print(ie)
613.855.219.926
### ValidadorInscricaoEstadual
Valida a consistência de uma instância de InscricaoEstadual ou uma _string_ contendo a representação numérica de uma Inscrição Estadual para uma determinada Unidade da Federação, informada juntamente com a representação numérica da IE a qual se deseja validar.
> A validação da Inscrição Estadual para cada Unidade da Federação brasileira, leva em consideração o disposto no [__Convênio 57/59__](http://www.sintegra.gov.br/conv_5795.html "ConvênioICMS 57/59"), como também as orientações e especificidades contidas na página [Conferências de Inscrições Estaduais](http://www.sintegra.gov.br/insc_est.html "Conferência de Inscrições Estaduais") do SINTEGRA.
#### Utilização
>>> ie = InscricaoEstadual('613.855.219.926', 'SP')
>>> ValidadorInscricaoEstadual.validar(ie)
True
>>> ValidadorInscricaoEstadual.validarStr('207653461', 'RN')
True
>>> ValidadorInscricaoEstadual.validarStr('209564598', 'TO')
False
> **NOTA**: Caso não se deseje utilizar o __ValidadorInscricaoEstadual__, pode-se utilizar o validador específico para uma determinada Unidade da Federação.
Cada Unidade da Federação brasileira possui o seu próprio validador, definido por: **Validador**XX, onde _XX_ deve ser substituído pela sigla da Unidade da Federação desejada.
O Exemplo a seguir mostra como utilizar somente o validador específico para o Ceará, visando validar uma Inscrição Estadual deste Estado:
>>> from bradocs4py.validadoresie import ValidadorCE
>>> ValidadorCE.validar('1234567')
False
>>> ValidadorCE.validar('50374156-6')
True
> **IMPORTANTE**: Ao contrário de ValidadorInscricaoEstadual, os validadores específicos de cada UF validam somente uma cadeia de caracteres (_string_) contendo o número representativo da Inscrição Estadual a ser validada.
### ChaveAcessoNFe
Representa a **Chave de Acesso** de uma Nota Fiscal Eletrônica.
#### Lei de formação de uma Chave de Acesso de NF-e
A Chave de Acesso da Nota Fiscal Eletrônica é representada por uma sequência de 44 caracteres numéricos, devendo ser composta pelos seguintes campos que se encontram dispersos no Layout da NF-e:
* UF - Código da UF do emitente do Documento Fiscal
* AAMM - Ano e mês da emissão da NF-e
* CNPJ - CNPJ do emitente do Documento Fiscal
* Modelo - Modelo do Documento Fiscal
* Série - Série do Documento Fiscal
* Número - Número do Documento Fiscal
* Forma Emissão - Forma de emissão do Documento Fiscal
* Código Numérico - Código numérico que compõe a Chave de Acesso
* DV - Dígito verificados
| Código | UF | AAMM | CNPJ | Modelo | Série | Número | Forma Emissão | Código Numérico | DV |
| :--------:|:----:|:----:|:----:|:------:|:-----:|:------:|:-------------:|:---------------:|:----:|
|Quantidade de caracteres |02 |04 |14 |02 |03 |09 |01 |08 |01 |
#### Utilização
>>> ca = ChaveAcessoNFe('23 1811 06850713000120 55 001 001766829 1 11103011 2')
>>> ca
>>> print(ca)
2318 1106 8507 1300 0120 5500 1001 7668 2911 1103 0112
>>> ca.rawValue
'23181106850713000120550010017668291111030112'
>>> ca.isValid
True
### ValidadorChaveAcessoNFe
Valida a consistência e a integridade de uma instância de [ChaveAcessoNFe](#chave) ou uma _string_ contendo a representação numérica de uma Chave de Acesso, através do cálculo de seu _dígito verificador_.
> O **Dígito Verificador** (DV) visa garantir a integridade da Chave de Acesso, protegendo-a principalmente contra digitações erradas.
#### Utilização
>>> chave = ChaveAcessoNFe(35181298957205000164667451830925015791400679)
>>> validarChaveAcessoNFe(chave)
True
>>> ValidadorChaveAcessoNFe.validar(52060433009911002506550120000007800267301615)
True
>>> ValidadorChaveAcessoNFe.validar('52060433009911002506550120000007800267301615')
True
>>> ValidadorChaveAcessoNFe.validar('52060433009911002506550120000007800267301625')
False
ou
>>> validarChaveAcessoNFe(52060433009911002506550120000007800267301615)
True
>>> validarChaveAcessoNFe('52060433009911002506550120000007800267301615')
True
>>> validarChaveAcessoNFe('52060433009911002506550120000007800267301625')
False
>>> validarChaveAcessoNFe(chave)
True
#### Cálculo do dígito verificador
O dígito verificador da chave de acesso da NF-e é baseado em um cálculo do módulo 11. O módulo 11 de um número é calculado multiplicando-se cada algarismo pela sequência de multiplicadores 2,3,4,5,6,7,8,9,2,3, ..., posicionados da direita para a esquerda.
A somatória dos resultados das ponderações dos algarismos é dividida por 11 e o DV (dígito verificador) será a diferença entre o divisor (11) e o resto da divisão:
DV = 11 - (resto da divisão)
> Quando o resto da divisão for 0 (zero) ou 1 (um), o DV deverá ser igual a 0 (zero).
Exemplo: consideremos a seguinte chave de acesso: _52060433009911002506550120000007800267301615_
Isolando o _dígito verificador_, temos: _5206043300991100250655012000000780026730161_
|**Chave** | 5 | 2 | 0 | 6 | 0 | 4 | 3 | 3 | 0 | 0 | 9 | 9 | 1 | 1 | 0 | 0 | 2 | 5 | 0 | 6 | 5 | 5 | 0 | 1 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 7 | 8 | 0 | 0 | 2 | 6 | 7 | 3 | 0 | 1 | 6 | 1 |
|:------------------------|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|**Pesos** | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 |
|**Ponderação** |20 | 6 | 0 |54 | 0 |28 |18 |15 | 0 | 0 |18 |81 | 8 | 7 | 0 | 0 | 8 |15 | 0 |54 |40 |35 | 0 | 5 | 8 | 0 | 0 | 0 | 0 | 0 | 0 |35 |32 | 0 | 0 |18 |48 |49 |18 | 0 | 4 |18 | 2 |
**Somatório das ponderações**: _644_
Dividindo o somatório das ponderações por **11**, temos: 644/11 = 58, restando **6**
Como o dígito verificador (DV) = 11 - (resto da divisão), temos: **11 - 6 = 5**
Neste caso o DV da chave de acesso da NF-e é igual a "5".
#### Verificação da _consistência_ da Chave de Acesso
Por ter uma [lei de formação](#lfchave) peculiar, o _[ValidadorChaveAcessoNFe](#vchave)_ verifica a consistência de uma determinada chave de acesso, observando:
* se os dois primeiros dígitos correspondem ao código, segundo o IBGE, de uma Unidade da Federação Brasileira;
* Se a data de emissão (**mês** e **ano**) *ano* de emissão não é **posterior** à data (mês e ano) atual;
* Se o *mês* de emissão, que corresponde ao terceiro par de dígitos, corresponde ao valor de um dos meses do ano;
* Se o *CNPJ* do emitente corresponde a um número de CNPJ válido.
> Desta forma, para que uma chave de acesso de NF-e seja válida, esta deverá passar pelo cálculo do Dígito Verificador e pelo teste de consistência.
### GeradorChaveAcessoNFe
Gera uma [Chave de Acesso de NF-e](#chave) válida.
A chave gerada pelo [GeradorChaveAcessoNFe](#gchave) obedece às [regras de consistência](#consistenciachave) anteriormente citadas.
#### Utilização
>>> chave = GeradorChaveAcessoNFe.gerar()
>>> chave
>>> print(chave)
2518 1230 1738 3400 0160 6512 2705 9459 8418 3830 0521
>>> chave.rawValue
'25181230173834000160651227059459841838300521'
>>> chave.isValid
True
OU
>>> chave = gerarChaveAcessoNFe
>>> chave
>>> print(chave)
1118 1205 0017 0900 0125 6504 2852 2143 4939 5680 0409
>>> chave.rawValue
'11181205001709000125650428522143493956800409'
>>> chave.isValid
True
É possível passar para o gerador qualquer um dos seguintes parâmetros, ou combinação deles:
* UF - [Gera de uma chave de acesso para uma determinada Unidade da Federação](#gchaveUF) Brasileira
* anoEmissao - [Gera uma chave de acesso para um determinado ano de emissão](#gchaveAno)
* mesEmissao - [Gera uma chave de acesso para um determinado mês de emissão](#gchaveMes)
* cnpjEmitente - [Gera uma chave de acesso informando o CNPJ do emitente](#gchaveCNPJ)
* modelo - [Gera uma chame de acesso informando o modelo do documento fiscal](#gchaveModelo)
* serie - [Gera uma chave de acesso informando a série do Documento Fiscal](#gchaveSerie)
* numero - [Gera uma chave de acesso informando o núemro do Documento Fiscal](#gchaveNumero)
* formaEmissao - [Gera uma chave de acesso informando o tipo de emissão da NF-e](#gchaveEmissao)
##### Gerar uma chave de acesso para uma determinada Unidade da Federação (23 - Ceará):
>>> chave = GeradorChaveAcessoNFe.gerar(UF=23)
>>> chave.rawValue
'23181200840039000117652898295631409915000755'
##### Gerar uma chave de acesso para um determinado ano:
>>> chave = GeradorChaveAcessoNFe.gerar(anoEmissao=2015)
>>> chave.rawValue
'23151289106950000109651490922639616463100456'
##### Gerar uma chave de acesso para um determinado mês:
>>> chave = GeradorChaveAcessoNFe.gerar(mesEmissao=8)
>>> chave.rawValue
'15180853477826000102655678711686215463600041'
##### Gerar uma chave de acesso para uma determinada data (mês e ano) de emissão:
>>> chave = GeradorChaveAcessoNFe.gerar(anoEmissao=2015, mesEmissao=1)
>>> chave.rawValue
'29150139480855000100653317092547617382300904'
##### Gerar uma chave de acesso informando o CNPJ do emitente:
>>> chave = GeradorChaveAcessoNFe.gerar(cnpjEmitente='64802611000136')
>>> chave.rawValue
'13181264802611000136651456599176257515300837'
##### Gerar uma chave de acesso de uma NF-e, utilizada nas operações de venda no varejo (modelo de documento fiscal = 55)
>>> chave = GeradorChaveAcessoNFe.gerar(modelo=55)
>>> chave.rawValue
'27181282761929000106555079534095503558300935'
##### Gerar uma chave de acesso para uma NF-e que não possui série:
>>> chave = GeradorChaveAcessoNFe.gerar(serie=0)
>>> chave.rawValue
'13181202699369000160650006987155021599900654'
> Nota: A série também pode ser informada como uma cadeia de caracteres numéricos. No exemplo acima, poderia ter sido informado **'000'** para _serie_.
##### Gerar uma chave de acesso informando o número do documento fiscal:
>>> chave = GeradorChaveAcessoNFe.gerar(numero=1766829)
>>> chave.rawValue
'23181241761925000132652850017668297691400378'
##### Gerar uma chave de acesso para uma NF-e emitida com Contingência FS-IA, com impressão do DANFE em formulário de segurança (Tipo de emissã0 = 2)
>>> chave = GeradorChaveAcessoNFe.gerar(formaEmissao=2)
>>> chave.rawValue
'51181278981604000153656457693627102018200143'
Isto posto, desejando-se criar uma chave de acesso emitida no Ceará (Código IBGE=23) em Maio de 2016, para o CNPJ 64802611/0001-36, teríamos:
>>> chave = GeradorChaveAcessoNFe.gerar(formaEmissao=2, UF=23, anoEmissao=2016, mesEmissao=5, cnpjEmitente=64802611000136)
>>> chave.rawValue
'23160564802611000136554038699639442073100081'
>>> chave.isValid
True
> **Atenção**: a forma abreviada do gerador _(gerarChaveAcessoNFe)_ não permite a passagem de parâmetros.
### GTIN
Representa um Número Global do Item Comercial - Global Trade Item Number (GTIN)
O GTIN é um identificador para itens comerciais desenvolvido e controlado pela [GS1][gs1], antiga EAN/UCC. Os GTINs,
anteriormente chamados de códigos EAN, são atribuídos para qualquer item (produto ou serviço) que pode ser
precificado, pedido ou faturado em qualquer ponto da cadeia de suprimentos. O GTIN é utilizado para recuperar
informação pré-definida e abrange desde as matérias primas até produtos acabados. GTIN é um termo “guarda-chuva”
para descrever toda a família de identificação das estruturas de dados GS1 para itens comerciais (produtos e serviços).
Os GTINs podem ter o tamanho de 8, 12, 13 ou 14 dígitos e podem ser construídos utilizando qualquer uma das quatro
estruturas de numeração dependendo da aplicação. O GTIN-8 é codificado no código de barras EAN-8. O GTIN-12 é mais
utilizado no código de barras UPC-A, o GTIN-13 é codificado no EAN-13 e o GTIN-14 no ITF-14.
#### Utilização
##### Criando uma instância de [GTIN](#gtin) a partir de um inteiro
>>> gtin = GTIN(6291041500213)
>>> gtin
>>> gtin.rawValue
'6291041500213'
>>> gtin.isValid
True
##### Criando uma instância de [GTIN](#gtin) a partir de uma cadeia de caracteres numéricos
>>> gtin = GTIN('35723189')
>>> gtin
>>> gtin.rawValue
'35723189'
>>> gtin.isValid
True
### ValidadorGTIN
Valida uma instância de GTIN, um inteiro ou uma cadeia de caracteres numéricos que representa um GTIN, a partir do [cálculo de seu dígito verificador][calculo-digito-gtin], o qual assegura a sua integridade.
> Nota: Muito embora o ValidadorGTIN valide uma instância de GTIN, a validação desta instância pode ser verificada através da sua propriedade _isValid_, conforme exemplos acima.
#### Utilização
>>> gtin = GTIN('35723189')
>>> ValidadorGTIN.validar(gtin)
True
>>> ValidadorGTIN.validar('3572318')
False
>>> ValidadorGTIN.validar('35723189')
True
>>> ValidadorGTIN.validar(6291041500213)
True
>>> ValidadorGTIN.validar('62910415OO213')
False
**OU**
>>> gtin = GTIN('35723189')
>>> validar_gtin(gtin)
True
>>> validar_gtin('3572318')
False
>>> validar_gtin('35723189')
True
>>> validar_gtin(6291041500213)
True
>>> validar_gtin('62910415OO213')
False
### GeradorGTIN
Gera uma instância de um [GTIN](#gtin) válido.
>IMPORTANTE: Este gerador de GTIN tem como intenção ajudar estudantes, programadores, analistas e testadores de sistemas computacionais a gerar GTINs válidas. Normalmente necessárias parar testar seus softwares em desenvolvimento. A má utilização dos dados aqui gerados é de total responsabilidade do usuário. Os números são gerados de forma aleatória, respeitando as regras de criação de um GTIN.
#### Utilização
>>> gtin = GeradorGTIN.gerar()
>>> gtin
**ou**
>>> gtin = gerar_gtin()
>>> gtin
É possível informar ao gerador o tipo de GTIN que se deseja gerar. Para isso, deve-se passar o _GeradorGTIN.TipoGTIN_ desejado.
##### Para gerar um GTIN-8
>>> gtin = GeradorGTIN.gerar(GeradorGTIN.TipoGTIN.GTIN8)
>>> gtin
Também é possível gerar GTINs chamando diretamente _gerar_gtin_:
>>> gtin = gerar_gtin(GeradorGTIN.TipoGTIN.GTIN13)
>>> gtin
Utilize:
* GeradorGTIN.TipoGTIN.GTIN8 para gerar GTIN-8
* GeradorGTIN.TipoGTIN.GTIN12 para gerar GTIN-12
* GeradorGTIN.TipoGTIN.GTIN13 para gerar GTIN-13, ou
* GeradorGTIN.TipoGTIN.GTIN14 para gerar GTIN-14
> Se não for passado nenhum tipo para o gerador, este gerará sempre um GTIN-8.
[gs1]: https://www.gs1br.org
[calculo-digito-gtin]: https://www.gs1.org/services/how-calculate-check-digit-manually
%package -n python3-bradocs4py
Summary: Implementa a funcionalidade validar_inscao_estadual.
Provides: python-bradocs4py
BuildRequires: python3-devel
BuildRequires: python3-setuptools
BuildRequires: python3-pip
%description -n python3-bradocs4py
[![PyPI](https://img.shields.io/pypi/v/BRADocs4Py.svg)](https://pypi.org/project/bradocs4py/)
[![GitHub top language](https://img.shields.io/github/languages/top/namio/BRADocs4Py.svg)](https://github.com/namio/BRADocs4Py.git)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/BRADocs4Py.svg)](https://pypi.org/project/bradocs4py/)
[![PyPI - Wheel](https://img.shields.io/pypi/wheel/BRADocs4Py.svg)](https://pypi.org/project/bradocs4py/)
[![PyPI - Implementation](https://img.shields.io/pypi/implementation/BRADocs4Py.svg)](https://pypi.org/project/bradocs4py/)
[![GitHub](https://img.shields.io/github/license/namio/BRADocs4Py.svg)](https://github.com/namio/BRADocs4Py/blob/master/LICENSE)
[![GitHub last commit](https://img.shields.io/github/last-commit/namio/BRADocs4PY.svg)](https://github.com/namio/BRADocs4Py.git)
[![Say Thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/namio)
# BRADocs4Py
BRADocs4Py é uma biblioteca que visa fornecer componentes para trabalhar com tipos de dados específicos da realidade brasileira.
Esta biblioteca surgiu mediante a necessidade de se ter tipos específicos que possibilitem lidar com documentos de identificação próprios do Brasil, como é o caso do Cadastro de Pessoa Física (CPF) e do Cadastro Nacional de Pessoa Jurídica (CNPJ).
Além de conter classes que representam o modelo computacional dos principais documentos brasileiros, esta biblioteca também disponibiliza classes que permitem a validação e a geração de números válidos para estes documentos; sendo estas últimas disponibilizadas exclusivamente para fins de testes computacionais.
> This software is coded and documented in portuguese only as it is intended to be used to generate the necessary files for the brazilian government regarding to digital bookkeeping.
## Requisitos
* python
## Como instalar
$ pip install bradocs4py
## Objetivos do Projeto
A ideia inicial do projeto e unificar em uma única biblioteca módulos que permitam representar computacionalmente e validar documentos brasileiros - inicialmente CPF e CNPJ, além de permitir a geração de números válidos para estes documentos.
## Compatibilidade do Projeto
O projeto inicialmente suportará apenas Python 3.6.5+.
Outras linguagens de programação poderão ter versões especificas conforme minha disponibilidade de tempo.
## Status do Projeto
O projeto está em fase inicial de desenvolvimento.
| Módulo | Situação |
|:------------------------------------|:---------------:|
| [DocumentoIdentificacao](#di) |Funcional |
| [CPF](#cpf) |Funcional |
| [ValidadorCpf](#vcpf) |Funcional |
| [GeradorCpf](#gcpf) |Funcional |
| [Cnpj](#cnpj) |Funcional |
| [ValidadorCnpj](#vcnpj) |Funcional |
| [GeradorCnpj](#gcnpj) |Funcional |
| [InscricaoEstadual](#ie) |Funcional |
| [ValidadorInscricaoEstadual](#vie) |Funcional |
| [GeradorInscricaoEstadual](#gie) |Não implementado |
| [InscricaoSuframa](#is) |Funcional |
| [ValidadorSuframa](#vs) |Funcional |
| [GeradorSuframa](#gs) |Funcional |
| [ChaveAcessoNFe](#chave) |Funcional |
| [ValidadorChaveAcessoNFe](#vchave) |Funcional |
| [GeradorChaveAcessoNFe](#gchave) |Funcional |
| [GTIN](#gtin) |Funcional |
| [ValidadorGTIN](#vgtin) |Funcional |
| [GeradorGTIN](#ggtin) |Funcional |
### DocumentoIdentificacao
Classe abstrata, não podendo ser instanciada diretamente, serve como base para todas as classes que representam um documento de identificação ou qualquer outro documento brasileiro que necessite de validação.
### CPF
Classe usada para representar em código Pyhton um _Cadastro de Pessoa Física_ (CPF); permitindo representá-lo textualmente, com a devida formatação e identificar a sua validade.
#### Utilização
>>> cpf = CPF('52513127765')
>>> cpf
'525.131.277-65'
>>> cpf.isValid
True
>>> cpf.rawValue
52513127765
>>> cpf = CPF('abcdefghijk')
>>> cpf.isValid
False
>>> print(cpf)
abcdefghijk
>>> print(cpf.rawValue)
abcdefghijk
> Independente do conteúdo passado ao se criar uma instância de CPF, **sempre** obter-se-á uma instância deste. Caberá consultar a propriedade __isValid__ de uma instância de CPF para verificar se esta é válida ou não.
> A representação textual de uma instância de CPF só será exibida caso esta instância contenha um número válido de CPF; ao contrário será exibida a _string_ utilizada para criá-la.
> Para obter a _string_ utilizada ao instanciar um CPF, basta acessar a propriedade **rawValue** da instância criada.
### ValidadorCpf
Classe responsável por validar uma instância de CPF ou uma _string_ contendo a representação numérica de um CPF.
#### Utilização
>>> cpf = CPF('abcdefghijk')
>>> ValidadorCpf.validar(cpf)
False
>>> ValidadorCpf.validar('123.456.789-00')
False
Foi criado um CPF válido, porém foi digitado um caractere de separação diferente dos caracteres esperados (.-/ ). Mesmo assim, o validador informa tratar-se de um CPF correto
>>> cpf = CPF('508,697,212-40')
>>> ValidadorCpf.validar(cpf)
True
### GeradorCpf
Classe responsável por gerar aleatoriamente um CPF válido.
#### Utilização
>>> cpf = GeradorCpf.gerar()
>>> cpf.isValid
True
### Cnpj
Classe usada para representar em código Pyhton um _Cadastro Nacional de Pessoa Jurídica_ (CNPJ); permitindo representá-lo textualmente, com a devida formatação e identificar a sua validade.
#### Utilização
>>> cnpj = Cnpj('abcdefghijklmn')
>>> cnpj.isValid
False
>>> cnpj = Cnpj('12345678901234')
>>> cnpj.isValid
False
>>> cnpj = Cnpj('19.658.147/0001-0O')
>>> cnpj.isValid
False
>>> cnpj = Cnpj('19.658.147/0001-00')
>>> cnpj.isValid
True
> Independente do conteúdo passado ao se criar uma instância de CNPJ, **sempre** obter-se-á uma instância deste. Caberá consultar a propriedade __isValid__ de uma instância de CNPJ para verificar se esta é válida ou não.
> A representação textual de uma instância de CNPJ só será exibida caso esta instância contenha um número válido de CNPJ; ao contrário será exibida a _string_ utilizada para criá-la.
> Para obter a _string_ utilizada ao instanciar um CNPJ, basta acessar a propriedade **rawValue** da instância criada.
### ValidadorCnpj
Classe responsável por validar uma instância de CNPJ ou uma _string_ contendo a representação numérica de um CNPJ.
#### Utilização
>>> cnpj = Cnpj('abcdefghijklmn')
>>> ValidadorCnpj.validar(cnpj)
False
>>> cnpj = Cnpj('19.658.147/0001-0O')
>>>ValidadorCnpj.validar(cnpj)
False
>>> ValidadorCnpj.validar('12345678901234')
False
>>> cnpj = Cnpj('34 633 423,0001/60')
>>> ValidadorCnpj.validar(cnpj)
True
>>> ValidadorCnpj.validar('05.692.744/0001-38')
True
### GeradorCnpj
Classe responsável por gerar aleatoriamente um CNPJ válido.
#### Utilização
>>> cnpj = GeradorCnpj.gerar()
>>> cnpj.isValid
True
### InscricaoSuframa
Representa o número de inscrição na Superintendência da Zona Franca de Manaus (SUFRAMA)
> A SUFRAMA mantém controle sobre as empresas com insentivo fiscal, identificando-as através do número de _Inscrição SUFRAMA_.
A composição deste indicador é: _SS.NNNN.LLD_, onde:
**SS** representa o __código do setor de atividade__ da empresa, conforme exemplo abaixo:
| Código | Descrição |
| :----: | :---------------------------|
| 01 e 02 | Cooperativa |
| 10 e 11 | Comércio |
| 20 | Indústria com projeto pleno |
| 60 | Serviços |
**NNNN** número sequencial
**LL** representa o código da licalidade da Unidade Administrativa da Suframa que habilitou a empresa, conforme exemplo abaixo:
| Código | Descrição |
| :----: | :-----------|
| 01 | Manaus |
| 10 | Boa Vista |
| 30 | Porto Velho |
**D** dígito verificador
#### Validação
* Campo numérico com 9 posições (incluindo o dígito verificador).
* Pode iniciar por 0 (zero), mas não pode iniciar por 00.
* Dígito verificador calculado por [__módulo 11__](https://pt.wikipedia.org/wiki/D%C3%ADgito_verificador#Módulo_11 "Método de cálculo do dígito verificador usando Módulo 11"), pesos 2 a 9.
#### Utilização
>>> x = InscricaoSuframa('01.1234.129')
>>> x.rawValue
'011234129'
>>> print(x)
01.1234.129
>>> x.isValid
False
>>> x = InscricaoSuframa('101580100')
>>> x.rawValue
'101580100'
>>> print(x)
10.1580.100
>>> x.isValid
True
>>> x = InscricaoSuframa('1015801OO')
>>> x.rawValue
'1015801OO'
>>> print(x)
1015801OO
>>> x.isValid
False
### ValidadorSuframa
Valida uma instância de InscricaoSuframa ou uma _string_ contendo a representação numérica de uma Inscrição Suframa.
#### Utilização
# Validação de uma _string_ representando uma Inscrição Suframa:
>>> ValidadorSuframa.validar('101580100')
True
# Validação de uma _string_ representando uma Inscrição Suframa inválida (contendo caracteres não numéricos):
>>> ValidadorSuframa.validar('1015801OO')
False
# Validação de uma instância de InscriçãoSuframa:
>>> x = InscricaoSuframa('01.1234.129')
>>> ValidadorSuframa.validar(x)
False
### GeradorSuframa
Gera aleatoriamente uma Inscrição Suframa válida
>>> x = GeradorSuframa.gerar()
>>> x.isValid
True
> **IMPORTANTE**: O __GeradorSuframa__ tem por objetivo ajudar estudantes, programadores, analistas de sistemas e testadores de código a gerar Inscrições Suframa válidas visando auxiliar as rotinas de testes de softwares em desenvolvimento.
> A má utilização dos dados gerados pelo __GeradorSuframa__ é de **total responsabilidade do usuário** desta biblioteca.
> As inscrições são geradas de forma aleatória, respeitando as leis de formação estabelecidas pela SUFRAMA.
### InscricaoEstadual
Representa, em código Pyhton, uma _Inscrição Estadual_ (IE), ou o registro do contribuinte no cadastro do ICMS mantido pela Receita Estadual; permitindo representá-lo textualmente, com a devida formatação e identificar a sua validade.
#### Utilização
>>> ie = InscricaoEstadual('613.855.219.926', 'SP')
>>> ie.isValid
True
>>> ie.rawValue
'613855219926'
>>> ie.UF
'SP'
>>> print(ie)
613.855.219.926
### ValidadorInscricaoEstadual
Valida a consistência de uma instância de InscricaoEstadual ou uma _string_ contendo a representação numérica de uma Inscrição Estadual para uma determinada Unidade da Federação, informada juntamente com a representação numérica da IE a qual se deseja validar.
> A validação da Inscrição Estadual para cada Unidade da Federação brasileira, leva em consideração o disposto no [__Convênio 57/59__](http://www.sintegra.gov.br/conv_5795.html "ConvênioICMS 57/59"), como também as orientações e especificidades contidas na página [Conferências de Inscrições Estaduais](http://www.sintegra.gov.br/insc_est.html "Conferência de Inscrições Estaduais") do SINTEGRA.
#### Utilização
>>> ie = InscricaoEstadual('613.855.219.926', 'SP')
>>> ValidadorInscricaoEstadual.validar(ie)
True
>>> ValidadorInscricaoEstadual.validarStr('207653461', 'RN')
True
>>> ValidadorInscricaoEstadual.validarStr('209564598', 'TO')
False
> **NOTA**: Caso não se deseje utilizar o __ValidadorInscricaoEstadual__, pode-se utilizar o validador específico para uma determinada Unidade da Federação.
Cada Unidade da Federação brasileira possui o seu próprio validador, definido por: **Validador**XX, onde _XX_ deve ser substituído pela sigla da Unidade da Federação desejada.
O Exemplo a seguir mostra como utilizar somente o validador específico para o Ceará, visando validar uma Inscrição Estadual deste Estado:
>>> from bradocs4py.validadoresie import ValidadorCE
>>> ValidadorCE.validar('1234567')
False
>>> ValidadorCE.validar('50374156-6')
True
> **IMPORTANTE**: Ao contrário de ValidadorInscricaoEstadual, os validadores específicos de cada UF validam somente uma cadeia de caracteres (_string_) contendo o número representativo da Inscrição Estadual a ser validada.
### ChaveAcessoNFe
Representa a **Chave de Acesso** de uma Nota Fiscal Eletrônica.
#### Lei de formação de uma Chave de Acesso de NF-e
A Chave de Acesso da Nota Fiscal Eletrônica é representada por uma sequência de 44 caracteres numéricos, devendo ser composta pelos seguintes campos que se encontram dispersos no Layout da NF-e:
* UF - Código da UF do emitente do Documento Fiscal
* AAMM - Ano e mês da emissão da NF-e
* CNPJ - CNPJ do emitente do Documento Fiscal
* Modelo - Modelo do Documento Fiscal
* Série - Série do Documento Fiscal
* Número - Número do Documento Fiscal
* Forma Emissão - Forma de emissão do Documento Fiscal
* Código Numérico - Código numérico que compõe a Chave de Acesso
* DV - Dígito verificados
| Código | UF | AAMM | CNPJ | Modelo | Série | Número | Forma Emissão | Código Numérico | DV |
| :--------:|:----:|:----:|:----:|:------:|:-----:|:------:|:-------------:|:---------------:|:----:|
|Quantidade de caracteres |02 |04 |14 |02 |03 |09 |01 |08 |01 |
#### Utilização
>>> ca = ChaveAcessoNFe('23 1811 06850713000120 55 001 001766829 1 11103011 2')
>>> ca
>>> print(ca)
2318 1106 8507 1300 0120 5500 1001 7668 2911 1103 0112
>>> ca.rawValue
'23181106850713000120550010017668291111030112'
>>> ca.isValid
True
### ValidadorChaveAcessoNFe
Valida a consistência e a integridade de uma instância de [ChaveAcessoNFe](#chave) ou uma _string_ contendo a representação numérica de uma Chave de Acesso, através do cálculo de seu _dígito verificador_.
> O **Dígito Verificador** (DV) visa garantir a integridade da Chave de Acesso, protegendo-a principalmente contra digitações erradas.
#### Utilização
>>> chave = ChaveAcessoNFe(35181298957205000164667451830925015791400679)
>>> validarChaveAcessoNFe(chave)
True
>>> ValidadorChaveAcessoNFe.validar(52060433009911002506550120000007800267301615)
True
>>> ValidadorChaveAcessoNFe.validar('52060433009911002506550120000007800267301615')
True
>>> ValidadorChaveAcessoNFe.validar('52060433009911002506550120000007800267301625')
False
ou
>>> validarChaveAcessoNFe(52060433009911002506550120000007800267301615)
True
>>> validarChaveAcessoNFe('52060433009911002506550120000007800267301615')
True
>>> validarChaveAcessoNFe('52060433009911002506550120000007800267301625')
False
>>> validarChaveAcessoNFe(chave)
True
#### Cálculo do dígito verificador
O dígito verificador da chave de acesso da NF-e é baseado em um cálculo do módulo 11. O módulo 11 de um número é calculado multiplicando-se cada algarismo pela sequência de multiplicadores 2,3,4,5,6,7,8,9,2,3, ..., posicionados da direita para a esquerda.
A somatória dos resultados das ponderações dos algarismos é dividida por 11 e o DV (dígito verificador) será a diferença entre o divisor (11) e o resto da divisão:
DV = 11 - (resto da divisão)
> Quando o resto da divisão for 0 (zero) ou 1 (um), o DV deverá ser igual a 0 (zero).
Exemplo: consideremos a seguinte chave de acesso: _52060433009911002506550120000007800267301615_
Isolando o _dígito verificador_, temos: _5206043300991100250655012000000780026730161_
|**Chave** | 5 | 2 | 0 | 6 | 0 | 4 | 3 | 3 | 0 | 0 | 9 | 9 | 1 | 1 | 0 | 0 | 2 | 5 | 0 | 6 | 5 | 5 | 0 | 1 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 7 | 8 | 0 | 0 | 2 | 6 | 7 | 3 | 0 | 1 | 6 | 1 |
|:------------------------|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|**Pesos** | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 |
|**Ponderação** |20 | 6 | 0 |54 | 0 |28 |18 |15 | 0 | 0 |18 |81 | 8 | 7 | 0 | 0 | 8 |15 | 0 |54 |40 |35 | 0 | 5 | 8 | 0 | 0 | 0 | 0 | 0 | 0 |35 |32 | 0 | 0 |18 |48 |49 |18 | 0 | 4 |18 | 2 |
**Somatório das ponderações**: _644_
Dividindo o somatório das ponderações por **11**, temos: 644/11 = 58, restando **6**
Como o dígito verificador (DV) = 11 - (resto da divisão), temos: **11 - 6 = 5**
Neste caso o DV da chave de acesso da NF-e é igual a "5".
#### Verificação da _consistência_ da Chave de Acesso
Por ter uma [lei de formação](#lfchave) peculiar, o _[ValidadorChaveAcessoNFe](#vchave)_ verifica a consistência de uma determinada chave de acesso, observando:
* se os dois primeiros dígitos correspondem ao código, segundo o IBGE, de uma Unidade da Federação Brasileira;
* Se a data de emissão (**mês** e **ano**) *ano* de emissão não é **posterior** à data (mês e ano) atual;
* Se o *mês* de emissão, que corresponde ao terceiro par de dígitos, corresponde ao valor de um dos meses do ano;
* Se o *CNPJ* do emitente corresponde a um número de CNPJ válido.
> Desta forma, para que uma chave de acesso de NF-e seja válida, esta deverá passar pelo cálculo do Dígito Verificador e pelo teste de consistência.
### GeradorChaveAcessoNFe
Gera uma [Chave de Acesso de NF-e](#chave) válida.
A chave gerada pelo [GeradorChaveAcessoNFe](#gchave) obedece às [regras de consistência](#consistenciachave) anteriormente citadas.
#### Utilização
>>> chave = GeradorChaveAcessoNFe.gerar()
>>> chave
>>> print(chave)
2518 1230 1738 3400 0160 6512 2705 9459 8418 3830 0521
>>> chave.rawValue
'25181230173834000160651227059459841838300521'
>>> chave.isValid
True
OU
>>> chave = gerarChaveAcessoNFe
>>> chave
>>> print(chave)
1118 1205 0017 0900 0125 6504 2852 2143 4939 5680 0409
>>> chave.rawValue
'11181205001709000125650428522143493956800409'
>>> chave.isValid
True
É possível passar para o gerador qualquer um dos seguintes parâmetros, ou combinação deles:
* UF - [Gera de uma chave de acesso para uma determinada Unidade da Federação](#gchaveUF) Brasileira
* anoEmissao - [Gera uma chave de acesso para um determinado ano de emissão](#gchaveAno)
* mesEmissao - [Gera uma chave de acesso para um determinado mês de emissão](#gchaveMes)
* cnpjEmitente - [Gera uma chave de acesso informando o CNPJ do emitente](#gchaveCNPJ)
* modelo - [Gera uma chame de acesso informando o modelo do documento fiscal](#gchaveModelo)
* serie - [Gera uma chave de acesso informando a série do Documento Fiscal](#gchaveSerie)
* numero - [Gera uma chave de acesso informando o núemro do Documento Fiscal](#gchaveNumero)
* formaEmissao - [Gera uma chave de acesso informando o tipo de emissão da NF-e](#gchaveEmissao)
##### Gerar uma chave de acesso para uma determinada Unidade da Federação (23 - Ceará):
>>> chave = GeradorChaveAcessoNFe.gerar(UF=23)
>>> chave.rawValue
'23181200840039000117652898295631409915000755'
##### Gerar uma chave de acesso para um determinado ano:
>>> chave = GeradorChaveAcessoNFe.gerar(anoEmissao=2015)
>>> chave.rawValue
'23151289106950000109651490922639616463100456'
##### Gerar uma chave de acesso para um determinado mês:
>>> chave = GeradorChaveAcessoNFe.gerar(mesEmissao=8)
>>> chave.rawValue
'15180853477826000102655678711686215463600041'
##### Gerar uma chave de acesso para uma determinada data (mês e ano) de emissão:
>>> chave = GeradorChaveAcessoNFe.gerar(anoEmissao=2015, mesEmissao=1)
>>> chave.rawValue
'29150139480855000100653317092547617382300904'
##### Gerar uma chave de acesso informando o CNPJ do emitente:
>>> chave = GeradorChaveAcessoNFe.gerar(cnpjEmitente='64802611000136')
>>> chave.rawValue
'13181264802611000136651456599176257515300837'
##### Gerar uma chave de acesso de uma NF-e, utilizada nas operações de venda no varejo (modelo de documento fiscal = 55)
>>> chave = GeradorChaveAcessoNFe.gerar(modelo=55)
>>> chave.rawValue
'27181282761929000106555079534095503558300935'
##### Gerar uma chave de acesso para uma NF-e que não possui série:
>>> chave = GeradorChaveAcessoNFe.gerar(serie=0)
>>> chave.rawValue
'13181202699369000160650006987155021599900654'
> Nota: A série também pode ser informada como uma cadeia de caracteres numéricos. No exemplo acima, poderia ter sido informado **'000'** para _serie_.
##### Gerar uma chave de acesso informando o número do documento fiscal:
>>> chave = GeradorChaveAcessoNFe.gerar(numero=1766829)
>>> chave.rawValue
'23181241761925000132652850017668297691400378'
##### Gerar uma chave de acesso para uma NF-e emitida com Contingência FS-IA, com impressão do DANFE em formulário de segurança (Tipo de emissã0 = 2)
>>> chave = GeradorChaveAcessoNFe.gerar(formaEmissao=2)
>>> chave.rawValue
'51181278981604000153656457693627102018200143'
Isto posto, desejando-se criar uma chave de acesso emitida no Ceará (Código IBGE=23) em Maio de 2016, para o CNPJ 64802611/0001-36, teríamos:
>>> chave = GeradorChaveAcessoNFe.gerar(formaEmissao=2, UF=23, anoEmissao=2016, mesEmissao=5, cnpjEmitente=64802611000136)
>>> chave.rawValue
'23160564802611000136554038699639442073100081'
>>> chave.isValid
True
> **Atenção**: a forma abreviada do gerador _(gerarChaveAcessoNFe)_ não permite a passagem de parâmetros.
### GTIN
Representa um Número Global do Item Comercial - Global Trade Item Number (GTIN)
O GTIN é um identificador para itens comerciais desenvolvido e controlado pela [GS1][gs1], antiga EAN/UCC. Os GTINs,
anteriormente chamados de códigos EAN, são atribuídos para qualquer item (produto ou serviço) que pode ser
precificado, pedido ou faturado em qualquer ponto da cadeia de suprimentos. O GTIN é utilizado para recuperar
informação pré-definida e abrange desde as matérias primas até produtos acabados. GTIN é um termo “guarda-chuva”
para descrever toda a família de identificação das estruturas de dados GS1 para itens comerciais (produtos e serviços).
Os GTINs podem ter o tamanho de 8, 12, 13 ou 14 dígitos e podem ser construídos utilizando qualquer uma das quatro
estruturas de numeração dependendo da aplicação. O GTIN-8 é codificado no código de barras EAN-8. O GTIN-12 é mais
utilizado no código de barras UPC-A, o GTIN-13 é codificado no EAN-13 e o GTIN-14 no ITF-14.
#### Utilização
##### Criando uma instância de [GTIN](#gtin) a partir de um inteiro
>>> gtin = GTIN(6291041500213)
>>> gtin
>>> gtin.rawValue
'6291041500213'
>>> gtin.isValid
True
##### Criando uma instância de [GTIN](#gtin) a partir de uma cadeia de caracteres numéricos
>>> gtin = GTIN('35723189')
>>> gtin
>>> gtin.rawValue
'35723189'
>>> gtin.isValid
True
### ValidadorGTIN
Valida uma instância de GTIN, um inteiro ou uma cadeia de caracteres numéricos que representa um GTIN, a partir do [cálculo de seu dígito verificador][calculo-digito-gtin], o qual assegura a sua integridade.
> Nota: Muito embora o ValidadorGTIN valide uma instância de GTIN, a validação desta instância pode ser verificada através da sua propriedade _isValid_, conforme exemplos acima.
#### Utilização
>>> gtin = GTIN('35723189')
>>> ValidadorGTIN.validar(gtin)
True
>>> ValidadorGTIN.validar('3572318')
False
>>> ValidadorGTIN.validar('35723189')
True
>>> ValidadorGTIN.validar(6291041500213)
True
>>> ValidadorGTIN.validar('62910415OO213')
False
**OU**
>>> gtin = GTIN('35723189')
>>> validar_gtin(gtin)
True
>>> validar_gtin('3572318')
False
>>> validar_gtin('35723189')
True
>>> validar_gtin(6291041500213)
True
>>> validar_gtin('62910415OO213')
False
### GeradorGTIN
Gera uma instância de um [GTIN](#gtin) válido.
>IMPORTANTE: Este gerador de GTIN tem como intenção ajudar estudantes, programadores, analistas e testadores de sistemas computacionais a gerar GTINs válidas. Normalmente necessárias parar testar seus softwares em desenvolvimento. A má utilização dos dados aqui gerados é de total responsabilidade do usuário. Os números são gerados de forma aleatória, respeitando as regras de criação de um GTIN.
#### Utilização
>>> gtin = GeradorGTIN.gerar()
>>> gtin
**ou**
>>> gtin = gerar_gtin()
>>> gtin
É possível informar ao gerador o tipo de GTIN que se deseja gerar. Para isso, deve-se passar o _GeradorGTIN.TipoGTIN_ desejado.
##### Para gerar um GTIN-8
>>> gtin = GeradorGTIN.gerar(GeradorGTIN.TipoGTIN.GTIN8)
>>> gtin
Também é possível gerar GTINs chamando diretamente _gerar_gtin_:
>>> gtin = gerar_gtin(GeradorGTIN.TipoGTIN.GTIN13)
>>> gtin
Utilize:
* GeradorGTIN.TipoGTIN.GTIN8 para gerar GTIN-8
* GeradorGTIN.TipoGTIN.GTIN12 para gerar GTIN-12
* GeradorGTIN.TipoGTIN.GTIN13 para gerar GTIN-13, ou
* GeradorGTIN.TipoGTIN.GTIN14 para gerar GTIN-14
> Se não for passado nenhum tipo para o gerador, este gerará sempre um GTIN-8.
[gs1]: https://www.gs1br.org
[calculo-digito-gtin]: https://www.gs1.org/services/how-calculate-check-digit-manually
%package help
Summary: Development documents and examples for bradocs4py
Provides: python3-bradocs4py-doc
%description help
[![PyPI](https://img.shields.io/pypi/v/BRADocs4Py.svg)](https://pypi.org/project/bradocs4py/)
[![GitHub top language](https://img.shields.io/github/languages/top/namio/BRADocs4Py.svg)](https://github.com/namio/BRADocs4Py.git)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/BRADocs4Py.svg)](https://pypi.org/project/bradocs4py/)
[![PyPI - Wheel](https://img.shields.io/pypi/wheel/BRADocs4Py.svg)](https://pypi.org/project/bradocs4py/)
[![PyPI - Implementation](https://img.shields.io/pypi/implementation/BRADocs4Py.svg)](https://pypi.org/project/bradocs4py/)
[![GitHub](https://img.shields.io/github/license/namio/BRADocs4Py.svg)](https://github.com/namio/BRADocs4Py/blob/master/LICENSE)
[![GitHub last commit](https://img.shields.io/github/last-commit/namio/BRADocs4PY.svg)](https://github.com/namio/BRADocs4Py.git)
[![Say Thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/namio)
# BRADocs4Py
BRADocs4Py é uma biblioteca que visa fornecer componentes para trabalhar com tipos de dados específicos da realidade brasileira.
Esta biblioteca surgiu mediante a necessidade de se ter tipos específicos que possibilitem lidar com documentos de identificação próprios do Brasil, como é o caso do Cadastro de Pessoa Física (CPF) e do Cadastro Nacional de Pessoa Jurídica (CNPJ).
Além de conter classes que representam o modelo computacional dos principais documentos brasileiros, esta biblioteca também disponibiliza classes que permitem a validação e a geração de números válidos para estes documentos; sendo estas últimas disponibilizadas exclusivamente para fins de testes computacionais.
> This software is coded and documented in portuguese only as it is intended to be used to generate the necessary files for the brazilian government regarding to digital bookkeeping.
## Requisitos
* python
## Como instalar
$ pip install bradocs4py
## Objetivos do Projeto
A ideia inicial do projeto e unificar em uma única biblioteca módulos que permitam representar computacionalmente e validar documentos brasileiros - inicialmente CPF e CNPJ, além de permitir a geração de números válidos para estes documentos.
## Compatibilidade do Projeto
O projeto inicialmente suportará apenas Python 3.6.5+.
Outras linguagens de programação poderão ter versões especificas conforme minha disponibilidade de tempo.
## Status do Projeto
O projeto está em fase inicial de desenvolvimento.
| Módulo | Situação |
|:------------------------------------|:---------------:|
| [DocumentoIdentificacao](#di) |Funcional |
| [CPF](#cpf) |Funcional |
| [ValidadorCpf](#vcpf) |Funcional |
| [GeradorCpf](#gcpf) |Funcional |
| [Cnpj](#cnpj) |Funcional |
| [ValidadorCnpj](#vcnpj) |Funcional |
| [GeradorCnpj](#gcnpj) |Funcional |
| [InscricaoEstadual](#ie) |Funcional |
| [ValidadorInscricaoEstadual](#vie) |Funcional |
| [GeradorInscricaoEstadual](#gie) |Não implementado |
| [InscricaoSuframa](#is) |Funcional |
| [ValidadorSuframa](#vs) |Funcional |
| [GeradorSuframa](#gs) |Funcional |
| [ChaveAcessoNFe](#chave) |Funcional |
| [ValidadorChaveAcessoNFe](#vchave) |Funcional |
| [GeradorChaveAcessoNFe](#gchave) |Funcional |
| [GTIN](#gtin) |Funcional |
| [ValidadorGTIN](#vgtin) |Funcional |
| [GeradorGTIN](#ggtin) |Funcional |
### DocumentoIdentificacao
Classe abstrata, não podendo ser instanciada diretamente, serve como base para todas as classes que representam um documento de identificação ou qualquer outro documento brasileiro que necessite de validação.
### CPF
Classe usada para representar em código Pyhton um _Cadastro de Pessoa Física_ (CPF); permitindo representá-lo textualmente, com a devida formatação e identificar a sua validade.
#### Utilização
>>> cpf = CPF('52513127765')
>>> cpf
'525.131.277-65'
>>> cpf.isValid
True
>>> cpf.rawValue
52513127765
>>> cpf = CPF('abcdefghijk')
>>> cpf.isValid
False
>>> print(cpf)
abcdefghijk
>>> print(cpf.rawValue)
abcdefghijk
> Independente do conteúdo passado ao se criar uma instância de CPF, **sempre** obter-se-á uma instância deste. Caberá consultar a propriedade __isValid__ de uma instância de CPF para verificar se esta é válida ou não.
> A representação textual de uma instância de CPF só será exibida caso esta instância contenha um número válido de CPF; ao contrário será exibida a _string_ utilizada para criá-la.
> Para obter a _string_ utilizada ao instanciar um CPF, basta acessar a propriedade **rawValue** da instância criada.
### ValidadorCpf
Classe responsável por validar uma instância de CPF ou uma _string_ contendo a representação numérica de um CPF.
#### Utilização
>>> cpf = CPF('abcdefghijk')
>>> ValidadorCpf.validar(cpf)
False
>>> ValidadorCpf.validar('123.456.789-00')
False
Foi criado um CPF válido, porém foi digitado um caractere de separação diferente dos caracteres esperados (.-/ ). Mesmo assim, o validador informa tratar-se de um CPF correto
>>> cpf = CPF('508,697,212-40')
>>> ValidadorCpf.validar(cpf)
True
### GeradorCpf
Classe responsável por gerar aleatoriamente um CPF válido.
#### Utilização
>>> cpf = GeradorCpf.gerar()
>>> cpf.isValid
True
### Cnpj
Classe usada para representar em código Pyhton um _Cadastro Nacional de Pessoa Jurídica_ (CNPJ); permitindo representá-lo textualmente, com a devida formatação e identificar a sua validade.
#### Utilização
>>> cnpj = Cnpj('abcdefghijklmn')
>>> cnpj.isValid
False
>>> cnpj = Cnpj('12345678901234')
>>> cnpj.isValid
False
>>> cnpj = Cnpj('19.658.147/0001-0O')
>>> cnpj.isValid
False
>>> cnpj = Cnpj('19.658.147/0001-00')
>>> cnpj.isValid
True
> Independente do conteúdo passado ao se criar uma instância de CNPJ, **sempre** obter-se-á uma instância deste. Caberá consultar a propriedade __isValid__ de uma instância de CNPJ para verificar se esta é válida ou não.
> A representação textual de uma instância de CNPJ só será exibida caso esta instância contenha um número válido de CNPJ; ao contrário será exibida a _string_ utilizada para criá-la.
> Para obter a _string_ utilizada ao instanciar um CNPJ, basta acessar a propriedade **rawValue** da instância criada.
### ValidadorCnpj
Classe responsável por validar uma instância de CNPJ ou uma _string_ contendo a representação numérica de um CNPJ.
#### Utilização
>>> cnpj = Cnpj('abcdefghijklmn')
>>> ValidadorCnpj.validar(cnpj)
False
>>> cnpj = Cnpj('19.658.147/0001-0O')
>>>ValidadorCnpj.validar(cnpj)
False
>>> ValidadorCnpj.validar('12345678901234')
False
>>> cnpj = Cnpj('34 633 423,0001/60')
>>> ValidadorCnpj.validar(cnpj)
True
>>> ValidadorCnpj.validar('05.692.744/0001-38')
True
### GeradorCnpj
Classe responsável por gerar aleatoriamente um CNPJ válido.
#### Utilização
>>> cnpj = GeradorCnpj.gerar()
>>> cnpj.isValid
True
### InscricaoSuframa
Representa o número de inscrição na Superintendência da Zona Franca de Manaus (SUFRAMA)
> A SUFRAMA mantém controle sobre as empresas com insentivo fiscal, identificando-as através do número de _Inscrição SUFRAMA_.
A composição deste indicador é: _SS.NNNN.LLD_, onde:
**SS** representa o __código do setor de atividade__ da empresa, conforme exemplo abaixo:
| Código | Descrição |
| :----: | :---------------------------|
| 01 e 02 | Cooperativa |
| 10 e 11 | Comércio |
| 20 | Indústria com projeto pleno |
| 60 | Serviços |
**NNNN** número sequencial
**LL** representa o código da licalidade da Unidade Administrativa da Suframa que habilitou a empresa, conforme exemplo abaixo:
| Código | Descrição |
| :----: | :-----------|
| 01 | Manaus |
| 10 | Boa Vista |
| 30 | Porto Velho |
**D** dígito verificador
#### Validação
* Campo numérico com 9 posições (incluindo o dígito verificador).
* Pode iniciar por 0 (zero), mas não pode iniciar por 00.
* Dígito verificador calculado por [__módulo 11__](https://pt.wikipedia.org/wiki/D%C3%ADgito_verificador#Módulo_11 "Método de cálculo do dígito verificador usando Módulo 11"), pesos 2 a 9.
#### Utilização
>>> x = InscricaoSuframa('01.1234.129')
>>> x.rawValue
'011234129'
>>> print(x)
01.1234.129
>>> x.isValid
False
>>> x = InscricaoSuframa('101580100')
>>> x.rawValue
'101580100'
>>> print(x)
10.1580.100
>>> x.isValid
True
>>> x = InscricaoSuframa('1015801OO')
>>> x.rawValue
'1015801OO'
>>> print(x)
1015801OO
>>> x.isValid
False
### ValidadorSuframa
Valida uma instância de InscricaoSuframa ou uma _string_ contendo a representação numérica de uma Inscrição Suframa.
#### Utilização
# Validação de uma _string_ representando uma Inscrição Suframa:
>>> ValidadorSuframa.validar('101580100')
True
# Validação de uma _string_ representando uma Inscrição Suframa inválida (contendo caracteres não numéricos):
>>> ValidadorSuframa.validar('1015801OO')
False
# Validação de uma instância de InscriçãoSuframa:
>>> x = InscricaoSuframa('01.1234.129')
>>> ValidadorSuframa.validar(x)
False
### GeradorSuframa
Gera aleatoriamente uma Inscrição Suframa válida
>>> x = GeradorSuframa.gerar()
>>> x.isValid
True
> **IMPORTANTE**: O __GeradorSuframa__ tem por objetivo ajudar estudantes, programadores, analistas de sistemas e testadores de código a gerar Inscrições Suframa válidas visando auxiliar as rotinas de testes de softwares em desenvolvimento.
> A má utilização dos dados gerados pelo __GeradorSuframa__ é de **total responsabilidade do usuário** desta biblioteca.
> As inscrições são geradas de forma aleatória, respeitando as leis de formação estabelecidas pela SUFRAMA.
### InscricaoEstadual
Representa, em código Pyhton, uma _Inscrição Estadual_ (IE), ou o registro do contribuinte no cadastro do ICMS mantido pela Receita Estadual; permitindo representá-lo textualmente, com a devida formatação e identificar a sua validade.
#### Utilização
>>> ie = InscricaoEstadual('613.855.219.926', 'SP')
>>> ie.isValid
True
>>> ie.rawValue
'613855219926'
>>> ie.UF
'SP'
>>> print(ie)
613.855.219.926
### ValidadorInscricaoEstadual
Valida a consistência de uma instância de InscricaoEstadual ou uma _string_ contendo a representação numérica de uma Inscrição Estadual para uma determinada Unidade da Federação, informada juntamente com a representação numérica da IE a qual se deseja validar.
> A validação da Inscrição Estadual para cada Unidade da Federação brasileira, leva em consideração o disposto no [__Convênio 57/59__](http://www.sintegra.gov.br/conv_5795.html "ConvênioICMS 57/59"), como também as orientações e especificidades contidas na página [Conferências de Inscrições Estaduais](http://www.sintegra.gov.br/insc_est.html "Conferência de Inscrições Estaduais") do SINTEGRA.
#### Utilização
>>> ie = InscricaoEstadual('613.855.219.926', 'SP')
>>> ValidadorInscricaoEstadual.validar(ie)
True
>>> ValidadorInscricaoEstadual.validarStr('207653461', 'RN')
True
>>> ValidadorInscricaoEstadual.validarStr('209564598', 'TO')
False
> **NOTA**: Caso não se deseje utilizar o __ValidadorInscricaoEstadual__, pode-se utilizar o validador específico para uma determinada Unidade da Federação.
Cada Unidade da Federação brasileira possui o seu próprio validador, definido por: **Validador**XX, onde _XX_ deve ser substituído pela sigla da Unidade da Federação desejada.
O Exemplo a seguir mostra como utilizar somente o validador específico para o Ceará, visando validar uma Inscrição Estadual deste Estado:
>>> from bradocs4py.validadoresie import ValidadorCE
>>> ValidadorCE.validar('1234567')
False
>>> ValidadorCE.validar('50374156-6')
True
> **IMPORTANTE**: Ao contrário de ValidadorInscricaoEstadual, os validadores específicos de cada UF validam somente uma cadeia de caracteres (_string_) contendo o número representativo da Inscrição Estadual a ser validada.
### ChaveAcessoNFe
Representa a **Chave de Acesso** de uma Nota Fiscal Eletrônica.
#### Lei de formação de uma Chave de Acesso de NF-e
A Chave de Acesso da Nota Fiscal Eletrônica é representada por uma sequência de 44 caracteres numéricos, devendo ser composta pelos seguintes campos que se encontram dispersos no Layout da NF-e:
* UF - Código da UF do emitente do Documento Fiscal
* AAMM - Ano e mês da emissão da NF-e
* CNPJ - CNPJ do emitente do Documento Fiscal
* Modelo - Modelo do Documento Fiscal
* Série - Série do Documento Fiscal
* Número - Número do Documento Fiscal
* Forma Emissão - Forma de emissão do Documento Fiscal
* Código Numérico - Código numérico que compõe a Chave de Acesso
* DV - Dígito verificados
| Código | UF | AAMM | CNPJ | Modelo | Série | Número | Forma Emissão | Código Numérico | DV |
| :--------:|:----:|:----:|:----:|:------:|:-----:|:------:|:-------------:|:---------------:|:----:|
|Quantidade de caracteres |02 |04 |14 |02 |03 |09 |01 |08 |01 |
#### Utilização
>>> ca = ChaveAcessoNFe('23 1811 06850713000120 55 001 001766829 1 11103011 2')
>>> ca
>>> print(ca)
2318 1106 8507 1300 0120 5500 1001 7668 2911 1103 0112
>>> ca.rawValue
'23181106850713000120550010017668291111030112'
>>> ca.isValid
True
### ValidadorChaveAcessoNFe
Valida a consistência e a integridade de uma instância de [ChaveAcessoNFe](#chave) ou uma _string_ contendo a representação numérica de uma Chave de Acesso, através do cálculo de seu _dígito verificador_.
> O **Dígito Verificador** (DV) visa garantir a integridade da Chave de Acesso, protegendo-a principalmente contra digitações erradas.
#### Utilização
>>> chave = ChaveAcessoNFe(35181298957205000164667451830925015791400679)
>>> validarChaveAcessoNFe(chave)
True
>>> ValidadorChaveAcessoNFe.validar(52060433009911002506550120000007800267301615)
True
>>> ValidadorChaveAcessoNFe.validar('52060433009911002506550120000007800267301615')
True
>>> ValidadorChaveAcessoNFe.validar('52060433009911002506550120000007800267301625')
False
ou
>>> validarChaveAcessoNFe(52060433009911002506550120000007800267301615)
True
>>> validarChaveAcessoNFe('52060433009911002506550120000007800267301615')
True
>>> validarChaveAcessoNFe('52060433009911002506550120000007800267301625')
False
>>> validarChaveAcessoNFe(chave)
True
#### Cálculo do dígito verificador
O dígito verificador da chave de acesso da NF-e é baseado em um cálculo do módulo 11. O módulo 11 de um número é calculado multiplicando-se cada algarismo pela sequência de multiplicadores 2,3,4,5,6,7,8,9,2,3, ..., posicionados da direita para a esquerda.
A somatória dos resultados das ponderações dos algarismos é dividida por 11 e o DV (dígito verificador) será a diferença entre o divisor (11) e o resto da divisão:
DV = 11 - (resto da divisão)
> Quando o resto da divisão for 0 (zero) ou 1 (um), o DV deverá ser igual a 0 (zero).
Exemplo: consideremos a seguinte chave de acesso: _52060433009911002506550120000007800267301615_
Isolando o _dígito verificador_, temos: _5206043300991100250655012000000780026730161_
|**Chave** | 5 | 2 | 0 | 6 | 0 | 4 | 3 | 3 | 0 | 0 | 9 | 9 | 1 | 1 | 0 | 0 | 2 | 5 | 0 | 6 | 5 | 5 | 0 | 1 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 7 | 8 | 0 | 0 | 2 | 6 | 7 | 3 | 0 | 1 | 6 | 1 |
|:------------------------|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|**Pesos** | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 |
|**Ponderação** |20 | 6 | 0 |54 | 0 |28 |18 |15 | 0 | 0 |18 |81 | 8 | 7 | 0 | 0 | 8 |15 | 0 |54 |40 |35 | 0 | 5 | 8 | 0 | 0 | 0 | 0 | 0 | 0 |35 |32 | 0 | 0 |18 |48 |49 |18 | 0 | 4 |18 | 2 |
**Somatório das ponderações**: _644_
Dividindo o somatório das ponderações por **11**, temos: 644/11 = 58, restando **6**
Como o dígito verificador (DV) = 11 - (resto da divisão), temos: **11 - 6 = 5**
Neste caso o DV da chave de acesso da NF-e é igual a "5".
#### Verificação da _consistência_ da Chave de Acesso
Por ter uma [lei de formação](#lfchave) peculiar, o _[ValidadorChaveAcessoNFe](#vchave)_ verifica a consistência de uma determinada chave de acesso, observando:
* se os dois primeiros dígitos correspondem ao código, segundo o IBGE, de uma Unidade da Federação Brasileira;
* Se a data de emissão (**mês** e **ano**) *ano* de emissão não é **posterior** à data (mês e ano) atual;
* Se o *mês* de emissão, que corresponde ao terceiro par de dígitos, corresponde ao valor de um dos meses do ano;
* Se o *CNPJ* do emitente corresponde a um número de CNPJ válido.
> Desta forma, para que uma chave de acesso de NF-e seja válida, esta deverá passar pelo cálculo do Dígito Verificador e pelo teste de consistência.
### GeradorChaveAcessoNFe
Gera uma [Chave de Acesso de NF-e](#chave) válida.
A chave gerada pelo [GeradorChaveAcessoNFe](#gchave) obedece às [regras de consistência](#consistenciachave) anteriormente citadas.
#### Utilização
>>> chave = GeradorChaveAcessoNFe.gerar()
>>> chave
>>> print(chave)
2518 1230 1738 3400 0160 6512 2705 9459 8418 3830 0521
>>> chave.rawValue
'25181230173834000160651227059459841838300521'
>>> chave.isValid
True
OU
>>> chave = gerarChaveAcessoNFe
>>> chave
>>> print(chave)
1118 1205 0017 0900 0125 6504 2852 2143 4939 5680 0409
>>> chave.rawValue
'11181205001709000125650428522143493956800409'
>>> chave.isValid
True
É possível passar para o gerador qualquer um dos seguintes parâmetros, ou combinação deles:
* UF - [Gera de uma chave de acesso para uma determinada Unidade da Federação](#gchaveUF) Brasileira
* anoEmissao - [Gera uma chave de acesso para um determinado ano de emissão](#gchaveAno)
* mesEmissao - [Gera uma chave de acesso para um determinado mês de emissão](#gchaveMes)
* cnpjEmitente - [Gera uma chave de acesso informando o CNPJ do emitente](#gchaveCNPJ)
* modelo - [Gera uma chame de acesso informando o modelo do documento fiscal](#gchaveModelo)
* serie - [Gera uma chave de acesso informando a série do Documento Fiscal](#gchaveSerie)
* numero - [Gera uma chave de acesso informando o núemro do Documento Fiscal](#gchaveNumero)
* formaEmissao - [Gera uma chave de acesso informando o tipo de emissão da NF-e](#gchaveEmissao)
##### Gerar uma chave de acesso para uma determinada Unidade da Federação (23 - Ceará):
>>> chave = GeradorChaveAcessoNFe.gerar(UF=23)
>>> chave.rawValue
'23181200840039000117652898295631409915000755'
##### Gerar uma chave de acesso para um determinado ano:
>>> chave = GeradorChaveAcessoNFe.gerar(anoEmissao=2015)
>>> chave.rawValue
'23151289106950000109651490922639616463100456'
##### Gerar uma chave de acesso para um determinado mês:
>>> chave = GeradorChaveAcessoNFe.gerar(mesEmissao=8)
>>> chave.rawValue
'15180853477826000102655678711686215463600041'
##### Gerar uma chave de acesso para uma determinada data (mês e ano) de emissão:
>>> chave = GeradorChaveAcessoNFe.gerar(anoEmissao=2015, mesEmissao=1)
>>> chave.rawValue
'29150139480855000100653317092547617382300904'
##### Gerar uma chave de acesso informando o CNPJ do emitente:
>>> chave = GeradorChaveAcessoNFe.gerar(cnpjEmitente='64802611000136')
>>> chave.rawValue
'13181264802611000136651456599176257515300837'
##### Gerar uma chave de acesso de uma NF-e, utilizada nas operações de venda no varejo (modelo de documento fiscal = 55)
>>> chave = GeradorChaveAcessoNFe.gerar(modelo=55)
>>> chave.rawValue
'27181282761929000106555079534095503558300935'
##### Gerar uma chave de acesso para uma NF-e que não possui série:
>>> chave = GeradorChaveAcessoNFe.gerar(serie=0)
>>> chave.rawValue
'13181202699369000160650006987155021599900654'
> Nota: A série também pode ser informada como uma cadeia de caracteres numéricos. No exemplo acima, poderia ter sido informado **'000'** para _serie_.
##### Gerar uma chave de acesso informando o número do documento fiscal:
>>> chave = GeradorChaveAcessoNFe.gerar(numero=1766829)
>>> chave.rawValue
'23181241761925000132652850017668297691400378'
##### Gerar uma chave de acesso para uma NF-e emitida com Contingência FS-IA, com impressão do DANFE em formulário de segurança (Tipo de emissã0 = 2)
>>> chave = GeradorChaveAcessoNFe.gerar(formaEmissao=2)
>>> chave.rawValue
'51181278981604000153656457693627102018200143'
Isto posto, desejando-se criar uma chave de acesso emitida no Ceará (Código IBGE=23) em Maio de 2016, para o CNPJ 64802611/0001-36, teríamos:
>>> chave = GeradorChaveAcessoNFe.gerar(formaEmissao=2, UF=23, anoEmissao=2016, mesEmissao=5, cnpjEmitente=64802611000136)
>>> chave.rawValue
'23160564802611000136554038699639442073100081'
>>> chave.isValid
True
> **Atenção**: a forma abreviada do gerador _(gerarChaveAcessoNFe)_ não permite a passagem de parâmetros.
### GTIN
Representa um Número Global do Item Comercial - Global Trade Item Number (GTIN)
O GTIN é um identificador para itens comerciais desenvolvido e controlado pela [GS1][gs1], antiga EAN/UCC. Os GTINs,
anteriormente chamados de códigos EAN, são atribuídos para qualquer item (produto ou serviço) que pode ser
precificado, pedido ou faturado em qualquer ponto da cadeia de suprimentos. O GTIN é utilizado para recuperar
informação pré-definida e abrange desde as matérias primas até produtos acabados. GTIN é um termo “guarda-chuva”
para descrever toda a família de identificação das estruturas de dados GS1 para itens comerciais (produtos e serviços).
Os GTINs podem ter o tamanho de 8, 12, 13 ou 14 dígitos e podem ser construídos utilizando qualquer uma das quatro
estruturas de numeração dependendo da aplicação. O GTIN-8 é codificado no código de barras EAN-8. O GTIN-12 é mais
utilizado no código de barras UPC-A, o GTIN-13 é codificado no EAN-13 e o GTIN-14 no ITF-14.
#### Utilização
##### Criando uma instância de [GTIN](#gtin) a partir de um inteiro
>>> gtin = GTIN(6291041500213)
>>> gtin
>>> gtin.rawValue
'6291041500213'
>>> gtin.isValid
True
##### Criando uma instância de [GTIN](#gtin) a partir de uma cadeia de caracteres numéricos
>>> gtin = GTIN('35723189')
>>> gtin
>>> gtin.rawValue
'35723189'
>>> gtin.isValid
True
### ValidadorGTIN
Valida uma instância de GTIN, um inteiro ou uma cadeia de caracteres numéricos que representa um GTIN, a partir do [cálculo de seu dígito verificador][calculo-digito-gtin], o qual assegura a sua integridade.
> Nota: Muito embora o ValidadorGTIN valide uma instância de GTIN, a validação desta instância pode ser verificada através da sua propriedade _isValid_, conforme exemplos acima.
#### Utilização
>>> gtin = GTIN('35723189')
>>> ValidadorGTIN.validar(gtin)
True
>>> ValidadorGTIN.validar('3572318')
False
>>> ValidadorGTIN.validar('35723189')
True
>>> ValidadorGTIN.validar(6291041500213)
True
>>> ValidadorGTIN.validar('62910415OO213')
False
**OU**
>>> gtin = GTIN('35723189')
>>> validar_gtin(gtin)
True
>>> validar_gtin('3572318')
False
>>> validar_gtin('35723189')
True
>>> validar_gtin(6291041500213)
True
>>> validar_gtin('62910415OO213')
False
### GeradorGTIN
Gera uma instância de um [GTIN](#gtin) válido.
>IMPORTANTE: Este gerador de GTIN tem como intenção ajudar estudantes, programadores, analistas e testadores de sistemas computacionais a gerar GTINs válidas. Normalmente necessárias parar testar seus softwares em desenvolvimento. A má utilização dos dados aqui gerados é de total responsabilidade do usuário. Os números são gerados de forma aleatória, respeitando as regras de criação de um GTIN.
#### Utilização
>>> gtin = GeradorGTIN.gerar()
>>> gtin
**ou**
>>> gtin = gerar_gtin()
>>> gtin
É possível informar ao gerador o tipo de GTIN que se deseja gerar. Para isso, deve-se passar o _GeradorGTIN.TipoGTIN_ desejado.
##### Para gerar um GTIN-8
>>> gtin = GeradorGTIN.gerar(GeradorGTIN.TipoGTIN.GTIN8)
>>> gtin
Também é possível gerar GTINs chamando diretamente _gerar_gtin_:
>>> gtin = gerar_gtin(GeradorGTIN.TipoGTIN.GTIN13)
>>> gtin
Utilize:
* GeradorGTIN.TipoGTIN.GTIN8 para gerar GTIN-8
* GeradorGTIN.TipoGTIN.GTIN12 para gerar GTIN-12
* GeradorGTIN.TipoGTIN.GTIN13 para gerar GTIN-13, ou
* GeradorGTIN.TipoGTIN.GTIN14 para gerar GTIN-14
> Se não for passado nenhum tipo para o gerador, este gerará sempre um GTIN-8.
[gs1]: https://www.gs1br.org
[calculo-digito-gtin]: https://www.gs1.org/services/how-calculate-check-digit-manually
%prep
%autosetup -n bradocs4py-1.3.1.0
%build
%py3_build
%install
%py3_install
install -d -m755 %{buildroot}/%{_pkgdocdir}
if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
pushd %{buildroot}
if [ -d usr/lib ]; then
find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/lib64 ]; then
find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/bin ]; then
find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/sbin ]; then
find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
fi
touch doclist.lst
if [ -d usr/share/man ]; then
find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
fi
popd
mv %{buildroot}/filelist.lst .
mv %{buildroot}/doclist.lst .
%files -n python3-bradocs4py -f filelist.lst
%dir %{python3_sitelib}/*
%files help -f doclist.lst
%{_docdir}/*
%changelog
* Tue May 30 2023 Python_Bot - 1.3.1.0-1
- Package Spec generated