Fala ai Radizeiros e Radizeiras, tudo bem com vocês?
A nossa série de post de boas práticas em arquivos fiscais aqui do nosso blog não pára.
Hoje esse post tem como continuação do ultimo post que foi apresentado o padrão visitor, e nesse post terminamos com a criação das Interfaces desse padrão, e como precisamos de classes que implementam essas interfaces, nesse post estarei explicando não só a criação dessas classes, mas a especialização da mesma com as regras fiscais.
Para relembrar, temos nossa interface do padrão visitor que possui o visitante, representado pela interface iVisitor, e quem vai ser visitado, representado pela interface iVisitable, e claro minhas regras fiscais, iModelRegrasFiscais.
1234567891011121314iModelNFeRegras =
interface
[
'{F6D013E9-6CA6-4C6B-BA7C-9107D4311D7C}'
]
function
ProdutoImpostoICMS : iModelNFeRegras;
end
;
iVisitor =
interface
[
'{69285067-A966-4240-A17C-649C8EDFB148}'
]
function
Visit(Value : iModelFiscalNFe) : iModelNFeRegras;
end
;
iVisitable =
interface
[
'{3B18B734-8049-48BF-AFDB-602C8AB3E513}'
]
function
Accept(Value : iVisitor) : iModelNFeRegras;
end
;
Então vamos lá, quem eu quero que seja visitado para mexer no produto?
Quel eu quero que seja visitado para mexer no produto é minha classe de produto da nota fiscal, ela que irá precisar implementar nossa interface iVisitable, porque ela tem mudanças no comportamento, pois esse comportamento tem que ser alterado de acordo com a regra fiscal.
Então teremos que alterar nosso comando de produto, onde iremos implementar essa interface iVisitable; ele vai estar aberto para ser visitado por uma regra fiscal.
1234567891011121314...
private
FParent : iModelFiscalNFe;
FVisitor : iVisitor;
public
...
function
Accept(Value : iVisitor) : iModelNFeRegras;
end
;
...
function
TModelFiscalNFeCommandProd
.
Accept(Value: iVisitor): iModelNFeRegras;
begin
FVisitor := Value;
Result := FVisitor
.
Visit(FParent);
end
;
Observe no código acima, como implementamos a interface em nossa classe, precisamos também implementar o método dessa interface, e esse método pede um parâmetro do tipo iVisitor, foi ai que precisamos criar uma variável privada do tipo iVisitor, que é o visitante.
Na implementação do método Accept passo para a variável que foi criada o visitante, parâmetro de entrada do método, e o retorno desse método pede as regras fiscais, e para retornar essas regras nós chamamos o visitante, ele precisa recebe na hora da visita uma iModelFiscalNFe, e se você observar que a variavel FParent é essa visita que precisamos passar para ele, ou seja, eu estou passando minha classe mãe de nota fiscal, porque ele irá precisar dela para trabalhar, para mudar o comportamento, ele precisa dela, e na imagem abaixo você pode ver que é retornado a regra fiscal.
Agora essa classe de produto já está recebendo o visitante.
Agora iremos mexer no comportamento dela, para que ela execute o que o visitante quiser, mas para isso vamos ter que preparar o visitante, preparar a regra fiscal.
Nesse primeiro momento deixamos ela pronta para receber as regras, mas como ainda não tem ninguém para visitar ela, então vamos criar o cara que irá visitar essa nossa classe.
Obs.: Você pode criar a especialização que você quiser, e o que precisar, para tratar as regras fiscais da nota.
Para esse nosso exemplo, iremos criar a seguinte classe Blog.Model.Fiscal.NFe.RegrasFiscais.ICMS.RegimeNormal.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758type
TModelFiscalNFeRegrasFiscaisICMSRegimeNormal =
class
(TInterfacedObject, iModelNFeRegras, iVisitor)
private
FParent : iModelFiscalNFe;
public
constructor
Create;
destructor
Destroy; override;
class
function
New : iModelNFeRegras;
function
ProdutoImpostoICMS : iModelNFeRegras;
function
Visit(Value : iModelFiscalNFe) : iModelNFeRegras;
end
;
implementation
uses
pcnConversao;
{ TModelFiscalNFeRegrasFiscaisICMSRegimeNormal }
constructor
TModelFiscalNFeRegrasFiscaisICMSRegimeNormal
.
Create;
begin
end
;
destructor
TModelFiscalNFeRegrasFiscaisICMSRegimeNormal
.
Destroy;
begin
inherited
;
end
;
class
function
TModelFiscalNFeRegrasFiscaisICMSRegimeNormal
.
New: iModelNFeRegras;
begin
Result := Self
.
Create
end
;
function
TModelFiscalNFeRegrasFiscaisICMSRegimeNormal
.
ProdutoImpostoICMS: iModelNFeRegras;
begin
Result := Self;
FParent
.
Component
.
Produto
.
Imposto
.
vTotTrib :=
0
;
FParent
.
Component
.
Produto
.
Imposto
.
ICMS
.
CST := cst00;
FParent
.
Component
.
Produto
.
Imposto
.
ICMS
.
orig := oeNacional;
FParent
.
Component
.
Produto
.
Imposto
.
ICMS
.
modBC := dbiValorOperacao;
FParent
.
Component
.
Produto
.
Imposto
.
ICMS
.
vBC :=
100
;
FParent
.
Component
.
Produto
.
Imposto
.
ICMS
.
pICMS :=
18
;
FParent
.
Component
.
Produto
.
Imposto
.
ICMS
.
vICMS :=
18
;
FParent
.
Component
.
Produto
.
Imposto
.
ICMS
.
modBCST := dbisMargemValorAgregado;
FParent
.
Component
.
Produto
.
Imposto
.
ICMS
.
pMVAST :=
0
;
FParent
.
Component
.
Produto
.
Imposto
.
ICMS
.
pRedBCST:=
0
;
FParent
.
Component
.
Produto
.
Imposto
.
ICMS
.
vBCST :=
0
;
FParent
.
Component
.
Produto
.
Imposto
.
ICMS
.
pICMSST :=
0
;
FParent
.
Component
.
Produto
.
Imposto
.
ICMS
.
vICMSST :=
0
;
FParent
.
Component
.
Produto
.
Imposto
.
ICMS
.
pRedBC :=
0
;
end
;
function
TModelFiscalNFeRegrasFiscaisICMSRegimeNormal
.
Visit(
Value: iModelFiscalNFe): iModelNFeRegras;
begin
Result := Self;
FParent := Value;
end
;
Vamos dizer que essa minha classe de visitante só vai tratar ICMS para o regime normal, tudo que for referente ao regime normal será tratado nessa nossa classe.
Viu como é importante a nomenclatura das classes?
Essa nossa classe que acabamos de criar ela pode parecer grande mas ela está dizendo o que e para que ela serve, qualquer pessoa que ler irá saber que esta classe trata as regras fiscais do ICMS do regime normal para a nota fiscal eletrônica, sem abreviação.
Essa minha classe está implementando primeiro a nossa interface iModelNFeRegras, que é as nossas regras fiscais, ela vai ser a classe que irá visitar os outros, sendo assim ela também implementa a interface iVisitor.
Quando essa classe é visitada, recebe por injeção de dependência a interface iModelFiscalNFe.
E você pode observar que o nosso método ProdutoImpostoICMS tem um comportamento diferenciado, ele que trata todas as questões fiscais do ICMS dos produtos, sendo assim o comando de produto não terá mais os ICMS lá e sim essa nossa classe visitor.
Esse tratamento é retirado do comando de produto porque ele é mutável, ele sofre alterações de acordo com um monte de fatores, e quem fica como responsável por esse tratamento do ICMS é a nossa classe visitor.
E no método Execute do nosso comando de produto chamamos esse nosso método de ProdutoImpostoICMS.
123456...
function
TModelFiscalNFeCommandProd
.
Execute: iCommand;
begin
...
FVisitor
.
Visit(FParent).ProdutoImpostoICMS;
...
Essa nossa classe de command ela só está apta a receber um visitante, então eu posso instanciar e mandar para ele, ICMSRegimeNormal, ICMSLucroPresumido, qualquer um dependendo do regime.
Ele só está pronto para que o cálculo do imposto seja feito por outra classe.
Viu como separando as coisas fica muito melhor?
Viu como vamos melhorando todo nosso código para implementação do ACBrNFe, esse é apenas o primeiro post da nossa série de Boas práticas para geração de arquivos fiscais com ACBr, este post foi extraído de um dos meus treinamentos que ensino todas as técnicas de boas práticas com clean code para geração de arquivos fiscais.
Com as técnicas aplicadas nesse treinamento, alem de aprender a aplicar na criação e emissão da NF-e, você pode também aplicar facilmente para o SPED e o SINTEGRA, ou seja, o que é problema para você hoje, depois desse treinamento você irá enxergar como oportunidade.
CLIQUE AQUI PARA SABER MAIS SOBRE O TREINAMENTO BOAS PRÁTICAS PARA GERAÇÃO DE ARQUIVOS DISCAIS COM ACBr