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.
iModelNFeRegras = 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.
... 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.
type 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.
... 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