l10n-brazil icon indicating copy to clipboard operation
l10n-brazil copied to clipboard

[12.0][REF] l10n_br_nfe: fiscal document module integration standard document line

Open renatonlima opened this issue 3 years ago • 3 comments

Pessoal,

Recentemente eu havia feito um PR #1924 para padronizar a integração entre os campos dos objetos de negócio e os objetos da NF-e, Eu estou criando esse PR para fazer a mesma padronização no objeto que integra a linha do documento fiscal com a linha da NF-e.

Basicamente Esse PR implementa a mesma padronização:

class NFeLine():
    # class metadata

    ##########################
    # NF-e spec related fields
    ##########################

    ######################################
    # NF-e tag: prod
    # Grupo I. Produtos e Serviços da NF-e
    ######################################

    # nfe40_cProd = fields.Char(related="product_id.default_code")

    nfe40_cEAN = fields.Char(related="product_id.barcode")

    # nfe40_xProd = fields.Char(related="name") TODO

    nfe40_NCM = fields.Char(related="ncm_id.code_unmasked")

    # NVE TODO

    nfe40_CEST = fields.Char(related="cest_id.code_unmasked")

    # indEscala TODO

    # CNPJFab TODO

    # cBenef TODO

    ##########################
    # NF-e tag: prod
    # Compute Methods
    ##########################

    def _compute_nfe40_prod(self, xsd_fields, class_obj, export_dict):
        ...

    ##########################
    # NF-e tag: id
    # Inverse Methods
    ##########################

    def _inverse_nfe40_prod(self):
        ...


    ################################
    # Framework Spec model's methods
    ################################
 
    def _export_fields_nfe_40_prod(self, xsd_fields, class_obj, export_dict):
        ...

   ################################
    # Business Model Methods
    ################################

    def _onchange_product_id_fiscal(self):
        ...

Alterações

A mudança considerável neste PR foi o refatoramento dos métodos _export_fields e _export_field que são método utilizados para remover tags e alterar os valores de algumas tags. Esses métodos estavam muito grandes o que iria gerar uma dificuldade em mante-los futuramente, hoje basicamente esses métodos são responsáveis:

  • _export_fields: controlar o fluxo das tags a ser removidas ou substituídas em determinadas condições.
  • _export_field: Atribuir ou remover valores das tags de dados.

Para melhorar esse implementação eu removi o método _export_field pois apesar de ser util esse método teria algumas limitações para reutiliza-lo através de outros métodos. Como o objeto da linha da NF-e tem uma complexidade maior o método que deveria ser utilizado seria o _export_fields pois com esse método é possível controlar o fluxo das tags exportadas e atribuir ou remover valores de qualquer tag. Eu defini uma convenção para quebrar a lógica dentro desses métodos em outros método menores, nessa convenção caso você queria alterar algum valor de alguma tag você deve criar um método com a mesma assinatura do _export_fields mas com o nome _export_fields_CLASS_SPEC, por exemplo: se quiser alterar algum valor dentro da tag prod representada pelo objeto nfe.40.prod, você deve criar um método:

def _export_fields_nfe_40_prod(self, xsd_fields, class_obj, export_dict):

Para implementar essa convenção eu implementei a seguinte lógica no método método herdado pelo spec model:

def _export_fields(self, xsd_fields, class_obj, export_dict):
    """Método utilizado para mapear os campos do documento fiscal com as
    tags da NF-e. Esse método"""

    xsd_fields = [i for i in xsd_fields]
    try:
        class_name = class_obj._name.replace(".", "_")
        export_method_name = "_export_fields_%s" % class_name
        if hasattr(self, export_method_name):
            export_method = getattr(self, export_method_name)
            export_method(xsd_fields, class_obj, export_dict)
    except AttributeError:
        pass

    return super()._export_fields(xsd_fields, class_obj, export_dict)

Eu diria que essa funcionalidade poderia ser transferida para o spec_model no spec_driven_model adicionando neste método essa lógica.

Outras alterações em andamento

  • Organização das tags na sequencia que são definidas no XSD do schema da NF-e;
  • Criar linhas de NF-e sem o produto (product_id) apenas preenchendo o código (cProd) e descrição (xProd);
  • Adicionado mapeamento para os campos vSeg;
  • Adicionado mapeamento para os campos vOutro;
  • Adicionar testes.

Devido a arquitetura da localização por essas alterações serem feitas no módulo l10n_br_nfe essas mudanças serão facilmente portadas para a versão 14.0 para mante-las compatíveis. Com o tempo a P&D vai naturalmente ser focada nas versões 14.0, 15.0 e 16.0.

renatonlima avatar Jun 29 '22 21:06 renatonlima

@rvalyi

Seria bom melhorar a mensagem desse log:

image

Poderia trazer o nome do objeto, o nome campo, o comodel_name do campo (caso seja relacional) e o valor que esta sendo importado para esse campo (os valores dos campos _nfe_search_keys) ou o domínio que foi utilizado na busca, para ficar mais clara a mensagem.

renatonlima avatar Jul 19 '22 15:07 renatonlima

@rvalyi,

Um caso que me deparei também foi com esse método na classe NFeLine:

def _export_float_monetary(self, field_name, member_spec, class_obj, xsd_required):
        if not self[field_name] and not xsd_required:
            if not (
                class_obj._name == "nfe.40.imposto" and field_name == "nfe40_vTotTrib"
            ) and not (class_obj._name == "nfe.40.fat"):
                self[field_name] = False
                return False
        return super()._export_float_monetary(
            field_name, member_spec, class_obj, xsd_required
        )

Os campos moeda por padrão no Odoo não ficam nulos tendo o valor padrão 0,00 esse método _export_float_monetary remove as tags que tenha xsd_required=False e não seja campos dos objetos: nfe.40.imposto, nfe.40.fat.

Eu removi esse método e tive alguns erros de validação no XML, porque o valor de alguns campos era 0.00 e esse campo era xsd_required=False e esse campo foi exportado para a tag da NF-e

Na minha opinião no método _export_float_monetary do módulo spec_driven_model deveria ter essa lógica, porque por exemplo, eu vi em alguns XMLs de NF-e geradas que existem tags que estão zeradas que não precisaria ser informada, por exemplo:

A tag vICMSUFRemet esta definida no XSD como xsd_required=False mas esta sendo exportada no XML:

image

Esse campo assim como os: vICMSDeson, vFCPUFDest, vICMSUFDest não precisariam ser exportados, só ocupa espaço de armazenamento, apesar de ser pouco, mas levando em consideração milhares de NF-es geradas gera um impacto considerável.

renatonlima avatar Jul 19 '22 15:07 renatonlima

Apenas para deixar explicito, com o PR atual, temos 2 esses diffs em duas NFe's de teste. Na esquerda como ficou com o PR e na direita como deveria ser: 2022-10-09_17-33 2022-10-09_17-33_1

rvalyi avatar Oct 09 '22 20:10 rvalyi

This PR has the approved label and has been created more than 5 days ago. It should therefore be ready to merge by a maintainer (or a PSC member if the concerned addon has no declared maintainer). 🤖

OCA-git-bot avatar Jan 06 '23 15:01 OCA-git-bot

/ocabot merge major

rvalyi avatar Jan 06 '23 15:01 rvalyi

This PR looks fantastic, let's merge it! Prepared branch 12.0-ocabot-merge-pr-2000-by-rvalyi-bump-major, awaiting test results.

OCA-git-bot avatar Jan 06 '23 15:01 OCA-git-bot

@rvalyi your merge command was aborted due to failed check(s), which you can inspect on this commit of 12.0-ocabot-merge-pr-2000-by-rvalyi-bump-major.

After fixing the problem, you can re-issue a merge command. Please refrain from merging manually as it will most probably make the target branch red.

OCA-git-bot avatar Jan 06 '23 16:01 OCA-git-bot

/ocabot merge major

rvalyi avatar Jan 06 '23 21:01 rvalyi

Hey, thanks for contributing! Proceeding to merge this for you. Prepared branch 12.0-ocabot-merge-pr-2000-by-rvalyi-bump-major, awaiting test results.

OCA-git-bot avatar Jan 06 '23 21:01 OCA-git-bot

Congratulations, your PR was merged at ca2b008fbfe08a65f057394a6baf7dc39c021844. Thanks a lot for contributing to OCA. ❤️

OCA-git-bot avatar Jan 06 '23 21:01 OCA-git-bot