Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TODO-pablo-waldir] libpitangusnfe #5

Open
silvioprog opened this issue Aug 28, 2017 · 7 comments
Open

[TODO-pablo-waldir] libpitangusnfe #5

silvioprog opened this issue Aug 28, 2017 · 7 comments
Assignees

Comments

@silvioprog
Copy link
Member

Definir e criar biblioteca para geração de XML de NF-e.

(obs: o nome no título é sugestivo e pode ser alterado)

@pablogallardo
Copy link
Member

Como a biblioteca gerará diversos documentos SPED, provavelmente será libpitangussped. Provavelmente este item será iniciado após #4.

@silvioprog
Copy link
Member Author

Acho que libpitangussped fica muito genérico, pois SPED é todo o eco sistema de serviços eletrônicos do Estado. Definindo como libpitangusnfe fica mais específica, pois tratará especificamente de NF-e. Talvez a próxima lib a ser criada será a libpitangusesocial, especificamente para e-Social, e assim por diante. O @waldirpaim pode nos orientar melhor sobre isso.

@pablogallardo
Copy link
Member

pablogallardo commented Aug 29, 2017 via email

@silvioprog
Copy link
Member Author

silvioprog commented Aug 29, 2017

Entendi. Não sei como você pretende gerenciar a memória dessa struct, mas posso deduzir que você usará unions. Veja, vamos supor que a struct SPED tenha 10 sub structs (NF-e, e-Social etc.), porém um usuário queira apenas a parte de NF-e para criar uma aplicação Raspberry, ou seja, naturalmente ele não poderá abusar do uso de memória, então uma struct gigante sem unions afetaria drasticamente a performance da aplicação dele. A union permitirá que ele linke apenas a struct de NF-e. Você tem algum "layout" em mente de como será essa estrutura?

@icaroraci
Copy link
Member

icaroraci commented Aug 30, 2017 via email

@silvioprog
Copy link
Member Author

Caros. Há outro detalhe que não atentamos: test-case.

Eu ouvi alguns áudios do Pablo e creio que entendi um pouco o que ele pretende fazer. Seria uma espécie de estrutura abstrata para conseguir um pouco de herança. Bem, OO não é standard em C. Há a lib GLib que oferece uma estrutura que lembra OO, mas a portabilidade dela não é muito tranquila. :-/

Mas acredito que se seguirmos as standards alcançaremos bons resultados sem precisar criar estruturas muito aninhadas. Vejam um exemplo bem simples:

https://github.com/silvioprog/microsped/blob/master/exemplos/status_servico.c#L78

na linha 78 deste exemplo é criado o objeto cfg, que contém todas as definições comum (ambiente, tipo de documento, estado etc.) para a maioria das funções, daí na linha 83 ele é passado como primeiro parâmetro na função que consulta o status do serviço:

https://github.com/silvioprog/microsped/blob/master/exemplos/status_servico.c#L83

Este mesmo objeto cfg é usando também em um outro exemplo:

https://github.com/silvioprog/microsped/blob/master/exemplos/evento_cce.c#L129

e reaproveitado nesta outra chamada, passado também como primeiro parâmetro, porém na função de envio de carta de correção:

https://github.com/silvioprog/microsped/blob/master/exemplos/evento_cce.c#L138

Essa estrutura é desacoplada e 100% testável, pois cada parte pode ser testada isoladamente. E reaproveitável, mesmo sem usar qualquer variante de OO. A ideia dela foi inspirada em algumas libs Linux que seguem as standards C. Creio que podemos extrair algumas ideias de lá para criarmos estruturas "compactas" e testáveis.

@pablogallardo
Copy link
Member

pablogallardo commented Aug 30, 2017

Prezados,

Bom, vou aproveitar para explicar aqui o que eu penso fazer:

Segundo os padrões de C ANSI:

C1x §6.7.2.1.13: "A pointer to a structure object, suitably converted, points to its initial member ... and vice versa. There may be unnamed padding within as structure object, but not at its beginning.")

Um ponteiro a uma struct é, na verdade, um ponteiro ao primeiro elemento. Isto é parte do padrão C e todos os compiladores que usam o padrão o respeitam.

Então hoje temos a struct NFE:

typedef struct {
	EMITENTE *emitente;
	//... outros membros
} NFE;

A Ideia seria criar a struct SPED:

typedef struct {
	char *xml;
	tipoSPED tipo;
	tAmbiente ambiente;
	//... outros membros
} SPED;

E adicionar em cada struct específico o membro SPED como primeiro membro:

typedef struct {
	SPED sped;
	EMITENTE *emitente;
	//... outros membros
} NFE;

Então, na verdade quando chamamos NFE *new_nfe() teríamos um ponteiro NFE que também pode ser usado como SPED:

NFE *nfe = new_nfe();
SPED *sped = (SPED *)nfe;
char *xml = sped->xml; //Usando o XML do SPED que foi criado como NFE

A grande vantagem de usar isso é que não teremos várias funções com o mesmo objetivo só porque trata-se de documentos SPED diferentes. E não estou falando isto só pelo envio, este foi só um exemplo. Eu estava lendo os manuais de outros documentos SPED, parece que todos tem eventos vinculáveis. Portanto, se não implementarmos deste jeito, seria terrível se organizar, teríamos que ter as funções add_evento_nfe(NFE *, EVENTO_NFE *), add_evento_esocial(ESOCIAL *, EVENTO_ESOCIAL *), etc. Com esta forma de abstração, teremos uma função só que cuida de todos os documentos da mesma maneira add_evento(SPED *, EVENTO *).

Eu tenho certeza que na implementação encontraremos mais detalhes como este. E se não começamos deste jeito, eu acho que vamos nos arrepender no futuro.

Vou responder citando algumas das respostas acima:

Toda essa complexidade irá diminuir ao existir structs para cada documentos eletrônico diferente.

@icaroraci, pelo contrário, termos structs diferentes aumentará a complexidade, e será difícil de manter. Imagina o esforço para implementar documentos SPED diferentes, sem reaproveitar nada. Estaríamos repetindo muito código.

OO não é standard em C

@silvioprog, embora C não tem orientação a objetos, podemos usar algumas coisas muito boas deste paradigma e C permite este uso, o uso do POO está presente inclusive no kernel, nas estruturas para criação de drivers.

sem precisar criar estruturas muito aninhadas.

Na verdade, não acho que as estruturas seriam aninhadas, porque assim como teremos o documento SPED, também poderemos usar cada estrutura por separado (NFE, CTE, ESOCIAL).

Espero ter explicado da melhor maneira isto. Realmente acho que esta é uma maneira bem organizada para abstrair estes documentos.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants