-
-
Notifications
You must be signed in to change notification settings - Fork 251
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
[14.0][FIX] l10n_br_sale: fix partner used to invoicing #3185
[14.0][FIX] l10n_br_sale: fix partner used to invoicing #3185
Conversation
Hi @renatonlima, |
1b64a44
to
bf7572a
Compare
This PR has the |
@marcelsavegnago eu também busquei resolver esse problema no começo do ano, mais especificamente em 16 de janeiro no PR #2864 houve uma revisão sua até mas infelizmente acabei não vendo e respondendo você na época, mas por esse PR aqui acredito que você também passou a ver o problema, a diferença entre os PRs é que no que fiz eu verifico se o partner_id do Dicionário Fiscal é diferente do mapeado pelo Dicionário do original. def _prepare_invoice(self):
self.ensure_one()
result = super()._prepare_invoice()
# TODO: O metodo prepare_br_fiscal_dict retorna o partner_id
# principal e não está considerando os casos do partner_invoice_id
# diferente do partner, deveria?
fiscal_values = self._prepare_br_fiscal_dict()
if fiscal_values.get("partner_id") != result.get("partner_id"):
# Usa o partner mapeado pelos metodos do modulo sale, sem isso
# o caso do partner_id ser diferente do partner_invoice_id a
# Fatura acabava sendo criada com o partner_id
fiscal_values["partner_id"] = result.get("partner_id")
result.update(fiscal_values) Mas tem uma questão de fundo mais complexa, o mapeamento dos Impostos hoje é feito sempre usando o partner_id do objeto, então hoje se for feita essa alteração talvez acabe ocorrendo inconsistências entre os Impostos mapeados no sale.order dos que são na account.move, eu vi que houveram tentativas de localizar essa questão pelo "Commercial Partner", mas pelo o código do Odoo estou deduzindo que existe uma diferença Fiscal entre o Brasil e a Europa, basicamente parece que na europa quando um Cliente tem um Contato definido como "Endereço de Faturamento ou de Entrega" a Identificação Fiscal/VAT é sempre referenciada ao res.partner principal porém no Brasil isso não se aplica já que essa Identificação Fiscal/CNPJ IE, talvez o Regime Tributário ( é preciso confimar ) estão diretamente ligados ao Endereço então no Brasil quando um Cliente tem esse tipo Contato esse terá diferentes CNPJ, IE o que pode causar um mapeamento de impostos diferentes, eu busquei confirmar essa situação mas ainda não encontrei uma documentação sobre isso, estou vendo se consigo confirmar com o pessoal da Akretion França. Eu tentei resolver esse problema de uma forma simples que é incluir um método para "obter o partner" e os objetos como o sale.order podem ter um "Partner para Faturamento" que é diferente do partner_id, o padrão, o objeto herda esse metodo é resolvemos esse problema, Commit especifico 4d844d4 l10n_br_fiscal/models/document_fiscal_line_mixin_methods.py def _get_partner_to_fiscal_operation(self):
"""
Metodo para ser herdado e permitir mapear o Partner para os casos onde
o objeto pode ter um Partner to Invoice diferente do Partner,
nesses casos é preciso usar o Partner to Invoice, isso acontece por
exemplo no Pedido de Vendas, Compras e Picking.
"""
self.ensure_one()
# Caso Fatura, o campo informado pelo usuário tem prioridade
# e não é considerado quando o address_get retorna um Contato
# definido como Tipo Invoice.
return self.partner_id Aí no sale.order b5bf2af l10n_br_sale/models/sale_order_line.py def _get_partner_to_fiscal_operation(self):
self.ensure_one()
partner = super()._get_partner_to_fiscal_operation()
# Caso Vendas, a prioridade é do campo informado pelo usuário, quando
# o Partner tem um contato definido como Tipo Invoice o campo
# partner_invoice_id é preenchido com esse valor automaticamente
if partner != self.order_id.partner_invoice_id:
partner = self.order_id.partner_invoice_id
return partner Talvez não seja a melhor forma de resolver o problema porém isso pode ser considerado como uma solução temporária, o PR mais completo está aqui #2849 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM: será que temos esse problema no purchase e em outros módulos tb?
@mbcosta eu ainda nao tive tempo de mergulhar no que vc me expliquou ontem, mas isso nao seria uma tentativa da Odoo SA de corrigir o problema que vc fala que apareceu na 14.0 sendo que esse PR eh da 15.0 mas que talvez isso eh apenas porque eles nao suportam mais a 14.0... odoo/odoo#174868 Nisso talvez vale a pena a gente olhar melhor esse PR com calma... |
eu nao analisei de forma suficente ainda, talvez o buraco eh mais fundo, ver odoo/odoo#174868
Aqui no Brasil pode ser comum utilizar o "endereço de cobrança" diferente do "endereço da nota fiscal", apenas para fins administrativos, para saber onde enviar a cobrança (normalmente boleto) que as vezes não é o mesmo que tá na nota fiscal. @marcelsavegnago qual seria o seu caso de uso com esse campos? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mbcosta pode revisar esse PR ? Parece ter relação com outros dois PRs que vc tem em aberto.
@mileo ele comentou aqui já: #3185 (comment) |
Puts não vi a citação dele.... Uma possibilidade para resolvermos isso é criar um 4º campo:
|
@marcelsavegnago será que este módulo pode ajudar? https://github.com/OCA/sale-workflow/tree/14.0/sale_commercial_partner |
Eu entendo que o correto é que seja considerado o partner_invoice_id que está no pedido de venda.. nativamente é este campo que é utilizado. O problema que na preparação dos dados o campo do prepare é partner_id com o valor de partner_invoice_id e ao chamar o fiscal_dict, o mesmo troca o partner não respeitando o que veio do prepare mas entendo o porque :D |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ainda nao analisei se sobra mais algum problema, mas entendo que ja melhora a situaçao para respeitar o que vem do partner_invoice_id, valeu pelas explicaçoes @marcelsavegnago
@mileo o lance do nosso modulo sale_commercial_partner eu acho que nao serve no caso: pois ele tragaria a entidade legal caso o partner_id do sale.order fosse apenas um contato ou um endereço sem ser a entidade legal. Mas no caso, no Brasil a entidade legal pros dados de documento fiscal tem que ser do partner_invoice_id mesmo e que devemos ter essa possibilidade de alterar.
Novamente, o Odoo foi pensado para paises como França ou Belgica que nao sao federaçoes e onde o endereço de entrega importa pouco para a fatura se for tudo no mesmo pais. Federeçoes tem soberania fiscal o que faz que existe tudo um mecanismo de contabilizaçao super importante dos estados de origem e destino das transaçoes (assim como existe para transaçoes entre paises da Europa). Por isso que eh super importante no Brasil e nem tanto la fora, mesmo se a Odoo aos poucos começa a se tocar sobre essas coisas, cria uma regressao numa versao X, corrige num PR numa versao X+n...
@marcelsavegnago eu concordo com seu fix, porem pros calculos de impostos ele continuaria usando os dados do order.partner_id que podem nao estar por examplo na devida UF onde deve ser feita a NFe... Que tal completar com esse PR Escodoo#60 pro mixin fiscal usar o order.partner_invoice_id tambem pros calculos fiscais exibidos no pedido, ate antes de criar o documento fiscal (seu PR atual arruma apenas a criaçao do documento fiscal). |
[FIX] l10n_br_sale: partner_invoice_id for taxes
perfeito.. mesclei a PR Escodoo#60 |
@marcelsavegnago @renatonlima @mbcosta @antoniospneto @felipemotter , uma coisa importante de considerar: quando começamos a localizaçao nas versoes 5 e 6 do Odoo, o partner_id nos documentos comerciais era a entidade legal. Porem, na versao 7.0 "sorry SAP", a Odoo começou essa coisa de querer fazer filhos nas costas com os investidores financeiros e para excitar eles começou a querer ostentar esse lado "social" onde houve uma mudança semantica que inicialmente nao foi devidamente assumdida. Resumei isso aqui na epoca: https://www.slideshare.net/slideshow/openerp-contact-id-solution-to-the-contacts-issue-in-v7/19052154 umas das grandes cagadas da Odoo da epoca que certamente participou de convencer a gente de criar a OCA (a gente menos pessoas pequenas que tavam se ajolhando de boa pra Odoo SA poder dar o golpe na epoca). Bem, nisso essa funçao dos campos partner_id ficou meio que mal definido entre contato e entidade legal. Tantamos dar o nosso jeito na v7 e v8 na localizaçao, porem continuando usando o campo partner_id (e as vezes outros campo quando a Odoo botava ourtros campos como aqui invoice_partner_id). Na v12 onde extraimos o modulo l10n_br_fiscal nao foi tao diferente, continuamos usando bastante o campo partner_id no modulo l10n_br_fiscal. Neste PR parece que tudo acaba ficando de boa. Mas a gente poderia imaginar que esses campos partner_id que temos nos mixins do documento fiscal e da linha de documento fiscal começa a conflitar com campos order_id nos objetos onde esses mixins sao injectados e onde esse partner_id na verdade significa contact_id... Nisso, talvez a gente poderia cogitar de renomear os campos partner_id dos mixins de documento fiscal e linha de documento fiscal para fiscal_partner_id para nunca conflitar. Sendo que onde os mixins seriam injectados a gente botaria um campo related para pegar o campo que na verder representa a entidade legal, assim como fizemos neste PR na sale.order.line. Bom, talvez ja funciona bastante bem e na v14 temos que ser conservadores com as mudanças, mas eh algo que podemos cogitar... Nao tenho preferencia no caso, apenas explico a coisa para a gente ficar de olho com isso. |
gosto da ideia |
Basicamente em cada modulo fariamos o mapeamento adequado. |
Sim. So que exigiria mudar bastante codigo e talvez scripts de migraçao, Nao sei se valeria a pena, ainda mais na v14, talvez a avaliaçao eh que com esses pequenos ajustes como esse deste PR, acaba funcionando da forma esperada. Empuramos isso com a barriga dessa maneira desde a v7 (ate tipo a v10 realmente tava mal definido, era capaz da Odoo SA voltar atras, ou ate dela quebrar tambem) e depois focamos em resgatar as coisas na v12, depois ainda voltar dos atrasos ate a v14... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eu não acho que essa solução resolve, o campo contato de faturamento é realmente para somente o faturamento e não para a parte fiscal.
Por exemplo: uma nota fiscal com destino ao estado de SP (endereço fiscal), faturada para a filial do RJ (endereço de faturamento), entregue em outro depósito em SP (endereço de entrega).
Seria melhor implementar o campo endereço fiscal e lidarmos com os problemas infelizmente.
se a gente pegar a entidade legal/commercial_id do partner_shipping_id pro partner_id do documento fiscal não resolveria 99% dos casos? (eu acho que apenas deixaria de fora o caso de vc entregar num endereço não ligado ao endereço fiscal, mas poderia ser feito num outro módulo). So nao analisei bem como a gente injectaria esse campo dentro do mixin da linha de documento fiscal pro calculo dos impostos no pedido (sem ser a geração da nota). |
Tem um outro caso de uso que eu esqueçi de comentar, em empresas grandes o faturamento muitas vezes é direcionado a alguém. Então teríamos essa divisão:
Isso seria simples de implementar no mixin do fiscal e funcionaria em casos mais simples com o contrato que só tem dois endereços (próximo ao header e o invoice na última aba) Em um caso extremo podemos até adicionar "fiscal" no selection do tipo do Parceiro. |
Para esta PR eu entendo que a solução proposta somando o commit do @rvalyi resolve o caso do pedido de vendas.. porém, no fiscal eu acho que já falamos disso, mas o campo commercial_partner_id como este parceiro para os calculos fiscais/contábeis e financeiros em tese resolveria.
|
acho que agrega somente na visualização dos dados.. |
Desculpem pelo tempo na resposta eu procurei rever tanto o PR que havia feito quanto a implementação, pelo o que vi tem duas questões principais: 1 - Mapeamento da Linha de Operação Fiscal e Impostos Por padrão o mapeamento da Linha de Operação Fiscal e consequentemente os Impostos são feitos usando o campo partner_id da Linha do Mix Fiscal e é usado no document_fiscal_line_mixin_methods.py nos metodos:
No caso dos objetos que herdam o Mix esse mapeamento está sendo feito sobreescrevendo o campo e usando o related:
Portanto o Mix Fiscal hoje está sobreescrevendo esse campo, quer dizer a colisão de campos já ocorre, então é melhor trocar para fiscal_partner_id ou avaliar alguma solução, para buscar entender melhor o problema podemos dizer que existem dois casos:
A diferença para ficar clara é que no segundo caso não tem um campo que está definindo o res.partner de Faturamento no objeto, nesses casos apenas usam o address_get para definir no dicionario no momento de criação da Fatura, então a solução apenas usando o related não atende todos os casos. As possibilidades de solução que vejo são
Acredito que a melhor solução é com menos código possível e com melhor tempo de processamento. Isso precisa ser feito para evitar erros devido os casos onde os Endereços de Entrega são Estados diferentes o que pode afetar os Impostos (empresas de um mesmo grupo podem ter Regimes Tributários diferentes? A confirmar)um caso de uso de exemplo:
2 - A forma de cadastro dos Endereços de Entrega e de Fatura/Cobrança atendem o Brasil? O padrão esperado pelo o Odoo é:
No caso Brasil, temos uma diferença que pode ser contornada que é o Contato definido como Endereço de Entrega ou Cobrança/Fatura deveriam estar como is_company=True porque quando a Empresa tem esses endereços isso significa outra Identificação/Entidade Fiscal porque possui outro CNPJ, IE e etc, aqui é minha dúvida quanto ao caso União Europeia um exemplo:
Pelo código estou deduzindo que são todos vistos como um único VAT ou Identificação/Entidade Fiscal, que representa tanto o Cliente Principal quanto seus Endereços de Entrega, é isso mesmo? No Brasil seria:
Porque todos possuem Identidades/Entidades Fiscais diferentes, hoje isso pode ser "contornado" e podemos "enganar" o cadastro deixando o is_company=False para funcionar da forma que o programa espera, mas não podemos fazer o que o Marcel recomendou aqui Essa alteração impediria o uso nos Casos Endereço de Cobrança/Faturamento, já que é preciso informar os Dados Fiscais, a Identificação/Entidade Fiscal é diferente do Cliente Principal, isso também pode acabar deixando "confuso" para o usuário final entender que apesar de não estar marcado como É uma empresa?'/is_company ali é o cadastro de um Endereço de Cobrança/Faturamento, na visão do usuário final o cadastro de Contatos teria duas possibilidades um é Contato Pessoa Física(caso que é o padrão e que funciona) e o outro é o caso Pessoa Jurídica que é uma Empresa, como nesse caso do Endereço de Cobrança/Faturamento. Hoje corrigindo o problema 1 e fazendo o Cadastro dos Endereços da forma como o Odoo espera restaria apenas um caso que é
A única forma que vejo para resolver esse problema é adicionar o campo partner_invoice_id no stock.picking trazendo o default pelo address_get mas permitindo alteração, é preciso avaliar. No PR #2849 tem dados de demonstração e testes, vou ver de separar os commits especificos para permitir o chery-pick para caso alguém queira testar alguma solução. Tem uma questão relacionada que é preciso avaliar e buscar um consenso Deve ser possível criar uma Fatura/account.move onde o res.partner informado no partner_id não seja o real de Faturamento? Por exemplo um Contato do Financeiro, "Fulano Financeiro, Empresa X" Acredito que não e que esse caso deve ser totalmente desconsiderado, os motivos:
Então acredito que é melhor definir que tanto o partner_id quanto o partner_shipping_id do account.move são iguais aos l10n_br_fiscal.document e que o res.partner definido no partner_id sempre é, e deve ser, o real de Faturamento que também é o que aparece nos Documentos Fiscais. |
parece que estamos perto de ter algo mais limpo do que foi feito neste PR
vou olhar ainda o PR do @mbcosta (eu acho que é um passo na boa direção so que talvez tem alguns detalhes para arrumar ainda). Mas enfim, so para compartilhar que o buraco esta mais em baixo com a Odoo SA: cc @renatonlima @antoniospneto @felipemotter @douglascstd @mileo Aqui vamos resolver assim como a gente sempre fez esses 15 anos, mas enfim boa sorte com Odoo Enterprise no Brasil neh galerinha... Vejo que o tom que eu usava para protestar contra o refator na v7 10 anos atras ainda esta bem apropriado... |
@marcelsavegnago achei a ideia boa! Só que, rodei uns testes aqui no próprio runboat do PR e vi que os impostos (na SO) estão estão sendo calculados em cima do partner_id. Na minha visão isso precisa ser alterado, veja as imagens: Contato e fatura no Brasil = Impostos BrasileirosContato e fatura no Exterior = Impostos ExteriorContato no Exterior e fatura no Brasil = Impostos Exterior ??? não podeTirando isso eu concordo que o partner_id que vai pra fatura deveria ser o partner_invoice_id da SO. Só acho que isso requer alguns cuidados. Tentei bolar uma descrição de como acho que ficaria top esse funcionamento, vejam se pode ajudar no entendimento e na discussão: Endereços venda/faturamentoSale OrderVisão Comercial: Um vendedor, utilizando o módulo de vendas, preenche os campos
Observações:No partner_id, o vendedor pode querer inserir o contato que ele tem dentro da empresa compradora, por exemplo: "Empresa123, Comprador João".
O termo "endereço de cobrança" utilizado muitas vezes aqui na discussão não necessariamente é a melhor descrição para o campo partner_invoice_id. É possível, por exemplo, utilizar ainda um outro partner_id em um account_payment e usar esse pagamento para pagar uma fatura. Veja que nesse caso o termo "endereço de cobrança", poderia melhor representar o partner_id do pagamento e não da fatura.
Sobre os impostos, acho importante ressaltar que precisam ser calculados com base no partner_id que será usado como destinatário na NFe no final do fluxo.
Achei interessante a ideia de adicionar o campo fiscal_partner_id pelos seguintes motivos:
Account Move
Observações:Embora redundante, aqui o partner_id precisa ser igual ao fiscal_partner_id. Stock pickingTalvez fuja um pouco do escopo do PR, mas ajuda no entendimento. Visão Operacional: Um operador de estoque cria uma transferência, marca para ser faturada e preenche os campos
Observações:Como o campo partner_invoice_id não existe nesse modelo, isso faz com que os impostos nesse ponto sejam calculados com base no parceiro da entrega.
Sobre o campo fiscal_partner_id, poderia ajudar na usabilidade e nos testes também. |
Para complementar o entendimento de qual parceiro deve ser utilizado, fiz um fluxo deste o CRM, considerando a criação dos parceiros dentro de uma empresa "Alimentos Saudáveis" 1o teste: Mantendo todos os campos conforme sugestão do Odooiniciando pelo CRMCriação de Cotação e Pedido de VendaValidação do Movimento de Estoque (Picking)Postando a FaturaDocumento FiscalNeste caso, o documento fiscal, utilizou o parceiro de Endereço Fiscal, mas os dados de Razão social e CNPJ ficaram vazios. 2o teste: Fluxo sem um endereço fiscal cadastradoCriação da Oportnidade no CRM para o contatoCriação da cotação e Pedido de VendaValidação do Movimento de Estoque (Picking)Postando a FaturaDocumento FiscalNeste caso, como é copiado parceiro (partner_id) para o endereço de faturameto (partner_invoice_id) já na cotação, a fatura e o documento fiscal assumem os dados da empresa. ObservaçãoUma utilização que conheço em uma aplicação em operação é quando é necessário enviar mercadoria por simples remessa para um cliente, no entanto o cabeçalho da NF deve ser a empresa (res_company). Mas se a orientação pelo parceiro nos lançamentos contábeis, imagino que deveria ser o res_partner "pai". |
@rvalyi busquei resolver da mesma forma que são mapeadas as Linhas, um método do Mix que pode ser herdado no objeto especifico mas que nesse caso retorna um res.partner, algo semelhante feito no modulo stock_picking_invoicing, estou considerando o caso de parametrização dos Endereços o padrão do Odoo v14, a forma que é esperado o resultado do address_get, os Testes de Dados de Demonstração estão separados para o caso de cherry-picks para poder testar outras soluções, sobre o caso EU e Europa do PR na v15 até onde entendi também é diferente do Brasil porque aqui se houver a necessidade de Faturar para um Endereço de entrega o usuário vai informar e não é uma questão de parametrização Fiscal, entendo a questão de prioridade e do uso do campo partner_id mas o problema aparece no caso stock.picking onde tem maior possibilidade de ser um Endereço de Entrega do que o Endereço Fiscal, mesmo hoje nos testes está sendo preciso tratar isso porque ao testar os onchanges do stock.move mapeia uma Linha de OP fiscal diferente do Pedido de Vendas https://github.com/OCA/l10n-brazil/blob/14.0/l10n_br_sale_stock/tests/test_sale_stock.py#L220 . |
valeu @marcelsavegnago @rvalyi , revendo o PR acabei percebendo que estava tratando apenas o problema nas Linhas do Mixin mas não no Cabeçalho/Corpo do objeto, busquei corrigir isso nos últimos commits, usei a mesma solução das Linhas, um outro ponto que tinha passado era alterar o related dos campos cnpj_cpf, legal_name e ie de related=partner_id.cnpj_cpf para related=partner_invoice_id.cnpj_cpf. |
@marcelsavegnago valeu pelo esforço. Mas estou propondo de fechar essa PR porque a principio isso foi resolvido pelo Magno aqui #2849. Fique a vontade para re-abrir se eu estiver errado. cc @douglascstd |
Por padrão, o valor do campo partner_id deve ser o mesmo do campo partner_invoice_id. O método _prepare_br_fiscal_dict() altera o valor de partner_id no resultado do super para o valor do campo partner_id do modelo sale.order.