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

[14.0][FIX] l10n_br_account_payment_order: trigger CNAB info load on payment_mode_id change #3213

Open
wants to merge 1 commit into
base: 14.0
Choose a base branch
from

Conversation

kaynnan
Copy link
Contributor

@kaynnan kaynnan commented Jul 23, 2024

cc @marcelsavegnago @douglascstd

PR para corrigir um problema onde, ao alterar o Modo de Pagamento para um CNAB em uma fatura já postada, a visualização do PDF é impossibilitada devido às ações necessárias serem realizadas apenas no método _post ao chamar o load_cnab_info, resultando o erro ao tentar visualizar o PDF:

Odoo Server Error

Traceback (most recent call last):
  File "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_http.py", line 237, in _dispatch
    result = request.dispatch()
  File "/opt/odoo/custom/src/odoo/odoo/http.py", line 696, in dispatch
    result = self._call_function(**self.params)
  File "/opt/odoo/custom/src/odoo/odoo/http.py", line 370, in _call_function
    return checked_call(self.db, *args, **kwargs)
  File "/opt/odoo/custom/src/odoo/odoo/service/model.py", line 94, in wrapper
    return f(dbname, *args, **kwargs)
  File "/opt/odoo/custom/src/odoo/odoo/http.py", line 358, in checked_call
    result = self.endpoint(*a, **kw)
  File "/opt/odoo/custom/src/odoo/odoo/http.py", line 919, in call
    return self.method(*args, **kw)
  File "/opt/odoo/custom/src/odoo/odoo/http.py", line 544, in response_wrap
    response = f(*args, **kw)
  File "/opt/odoo/auto/addons/web/controllers/main.py", line 1374, in call_button
    action = self._call_kw(model, method, args, kwargs)
  File "/opt/odoo/auto/addons/web/controllers/main.py", line 1362, in _call_kw
    return call_kw(request.env[model], method, args, kwargs)
  File "/opt/odoo/custom/src/odoo/odoo/api.py", line 406, in call_kw
    result = _call_kw_multi(method, model, args, kwargs)
  File "/opt/odoo/custom/src/odoo/odoo/api.py", line 391, in _call_kw_multi
    result = method(recs, *args, **kwargs)
  File "/opt/odoo/auto/addons/l10n_br_account_payment_order/models/account_move.py", line 67, in view_boleto_pdf
    self.generate_boleto_pdf()
  File "/opt/odoo/auto/addons/l10n_br_account_payment_brcobranca/models/account_move.py", line 33, in generate_boleto_pdf
    boletos = receivable_ids.send_payment()
  File "/opt/odoo/auto/addons/l10n_br_account_payment_brcobranca/models/account_move_line.py", line 70, in send_payment
    "".join(i for i in move_line.own_number if i.isdigit())
Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/odoo/custom/src/odoo/odoo/http.py", line 652, in _handle_exception
    return super(JsonRequest, self)._handle_exception(exception)
  File "/opt/odoo/custom/src/odoo/odoo/http.py", line 317, in _handle_exception
    raise exception.with_traceback(None) from new_cause
TypeError: 'bool' object is not iterable

Realizei esse FIX no método write porque o onchange não era suficiente, resultando em um erro relacionado ao método hex() sendo chamado em um objeto NewId.

 File "/opt/odoo/auto/addons/account/models/account_move.py", line 1170, in onchange
    return super(AccountMove, self.with_context(recursive_onchanges=False)).onchange(values, field_name, field_onchange)
  File "/opt/odoo/custom/src/odoo/odoo/models.py", line 6305, in onchange
    record._onchange_eval(name, field_onchange[name], result)
  File "/opt/odoo/custom/src/odoo/odoo/models.py", line 6047, in _onchange_eval
    method_res = method(self)
  File "/opt/odoo/auto/addons/l10n_br_account_payment_order/models/account_move.py", line 99, in _onchange_payment_mode_id
    self.load_cnab_info()
  File "/opt/odoo/auto/addons/l10n_br_account_payment_order/models/account_move.py", line 131, in load_cnab_info
    interval.company_title_identification = hex(interval.id).upper()
Exception

@OCA-git-bot
Copy link
Contributor

Hi @mbcosta,
some modules you are maintaining are being modified, check this out!

@kaynnan kaynnan force-pushed the 14.0-fix-l10n_br_account_payment_order-payment_load_cnab branch 2 times, most recently from ea8839e to d0bb0ba Compare July 23, 2024 13:12
@rvalyi
Copy link
Member

rvalyi commented Jul 23, 2024

vale a pena dar uma pensada se não teria um fix mais limpo. Override do write é um pouco brutal...

@antoniospneto
Copy link
Contributor

pois é eu tava pensando o mesmo, será que não vale a pena fazer um pequeno wizard para alterar o método de pagamento de uma fatura já postada?

@marcelsavegnago
Copy link
Member

marcelsavegnago commented Jul 23, 2024

pois é eu tava pensando o mesmo, será que não vale a pena fazer um pequeno wizard para alterar o método de pagamento de uma fatura já postada?

gosto da ideia do wizard.

@kaynnan kaynnan force-pushed the 14.0-fix-l10n_br_account_payment_order-payment_load_cnab branch from d0bb0ba to 1c40371 Compare July 26, 2024 22:06
@kaynnan
Copy link
Contributor Author

kaynnan commented Jul 26, 2024

Pessoal, atualizei o commit incluindo o IMP para esse novo Wizard. Foquei no modo simples, conforme descrito.

@kaynnan kaynnan force-pushed the 14.0-fix-l10n_br_account_payment_order-payment_load_cnab branch 2 times, most recently from eea85fc to 183e4d2 Compare July 27, 2024 03:23
@antoniospneto
Copy link
Contributor

Eu acho que é uma função útil, mas não precisa ter um botão exclusivo para isso, pois ainda é um processo que é uma exeção, os usuários não iráo ficar fazendo isso toda hora, então minha sugestão é remover o botão e por a chamada do wizard no menu Action, mantendo assim a visão limpa:
image

@kaynnan kaynnan force-pushed the 14.0-fix-l10n_br_account_payment_order-payment_load_cnab branch from 183e4d2 to 9baed09 Compare July 28, 2024 20:32
@kaynnan
Copy link
Contributor Author

kaynnan commented Jul 28, 2024

Eu acho que é uma função útil, mas não precisa ter um botão exclusivo para isso, pois ainda é um processo que é uma exeção, os usuários não iráo ficar fazendo isso toda hora, então minha sugestão é remover o botão e por a chamada do wizard no menu Action, mantendo assim a visão limpa: image

Realizei a mudança aqui, valeu @antoniospneto bem melhor no menu de Ação

@kaynnan kaynnan force-pushed the 14.0-fix-l10n_br_account_payment_order-payment_load_cnab branch from 9baed09 to 2bda539 Compare July 28, 2024 20:50
@kaynnan
Copy link
Contributor Author

kaynnan commented Jul 28, 2024

Estou incluindo os testes unitários para cobrir o percentual desse novo wizard criado

@kaynnan kaynnan force-pushed the 14.0-fix-l10n_br_account_payment_order-payment_load_cnab branch 2 times, most recently from e8329fd to 552f3cc Compare July 28, 2024 21:14
@kaynnan kaynnan force-pushed the 14.0-fix-l10n_br_account_payment_order-payment_load_cnab branch from 552f3cc to 8da01be Compare July 28, 2024 21:31
@kaynnan kaynnan requested a review from rvalyi July 28, 2024 21:57
@renatonlima renatonlima requested a review from mbcosta July 30, 2024 12:40
Copy link
Contributor

@antoniospneto antoniospneto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Não cheguei a testar, mas pelo código me parece tudo Ok, valeu @kaynnan

@rvalyi
Copy link
Member

rvalyi commented Aug 13, 2024

@mbcosta ok para vc esse?

@mbcosta
Copy link
Contributor

mbcosta commented Aug 15, 2024

valeu @kaynnan eu procurei ver se era possível resolver com o onchange como você havia tentado, o erro do NewID acontece porque o onchange cria um objeto temporário que é esse que dava erro, mas é possível dentro do onchange obter o objeto real com um self._origin então é até possível resolver via onchange com algo como:

EDIT: Referencia https://www.odoo.com/pt_BR/forum/ajuda-1/obtain-the-id-of-a-self-onchange-odoo-101202

    @api.onchange("payment_mode_id")
    def _onchange_payment_mode_id(self):
        for record in self:
            if record.state == "posted":
                for line in record._origin.financial_move_line_ids:
                    line.payment_mode_id = record.payment_mode_id

                record.with_context(
                    payment_mode=record.payment_mode_id,
                )._origin.load_cnab_info()

    def load_cnab_info(self):
        payment_mode = self.payment_mode_id
        # Se não possui Modo de Pagto não há nada a ser feito
        if not payment_mode:
            if self.env.context.get("payment_mode"):
               payment_mode = self.env.context.get("payment_mode")
            else:
               return

Mas a criação das Linhas de Pagamentos ocorre logo em seguida, então caso o Usuário selecione um Modo de Pagamento errado acaba criando uma Ordem de Pagto/Linhas de Pagto errados gerando outro problema, talvez isso poderia ser resolvido com um pop-up de Warning pedindo a Confirmação do Modo de Pagto escolhido ao Usuário.

Com o Wizard que você fez também funciona, porém é preciso verificar se a partir disso o campo Modo de Pagamento deve estar readonly porque mesmo com esse PR se o Usuário selecionar o Modo de Pagto direto no campo ao invés de usar o Wizard vai ocorrer o mesmo erro que você inclui no começo do PR, quer dizer o erro inicial persiste.

Temos que avaliar se isso deve ser feito via Wizard, como foi feito porém tratando para não permitir o usuário selecionar o Modo de Pagto diretamente, ou via Onchange, talvez com menos código, o que seria melhor?

É bom dizer também que existe uma diferença entre Erros do Código, responsabilidade dos Desenvolvedores, de erros de Cadastro, responsabilidade do Usuário, no caso do Modo de Pagamento até é possível alterar o campo com a Fatura não estando em Provisório, e acredito que nesse casos não foi considerado voltar a Fatura para Provisório porque já gerou um Documento Fiscal, é isso? Porque se fosse outro campo como o "Termos de Pagamento"/payment.terms isso já não seria possível por gerar as Linhas Financeiras aí o processo seria outro que é o Usuário Cancelar a Nota e gerar novamente com os dados corretos, nos podemos incluir Avisos, Validações e idealmente não deve ter mensagens de erro sem tratamento mas determinados erros precisam ser classificados para definir responsabilidades e custos.

@mbcosta
Copy link
Contributor

mbcosta commented Aug 15, 2024

Talvez outra possível solução ao selecionar o campo pelo campo Modo de Pagto o método onchange chamar o Wizard criado com o valor já preenchido apenas para Confirmação

@kaynnan
Copy link
Contributor Author

kaynnan commented Aug 15, 2024

valeu @kaynnan eu procurei ver se era possível resolver com o onchange como você havia tentado, o erro do NewID acontece porque o onchange cria um objeto temporário que é esse que dava erro, mas é possível dentro do onchange obter o objeto real com um self._origin então é até possível resolver via onchange com algo como:

EDIT: Referencia https://www.odoo.com/pt_BR/forum/ajuda-1/obtain-the-id-of-a-self-onchange-odoo-101202

    @api.onchange("payment_mode_id")

    def _onchange_payment_mode_id(self):

        for record in self:

            if record.state == "posted":

                for line in record._origin.financial_move_line_ids:

                    line.payment_mode_id = record.payment_mode_id



                record.with_context(

                    payment_mode=record.payment_mode_id,

                )._origin.load_cnab_info()



    def load_cnab_info(self):

        payment_mode = self.payment_mode_id

        # Se não possui Modo de Pagto não há nada a ser feito

        if not payment_mode:

            if self.env.context.get("payment_mode"):

               payment_mode = self.env.context.get("payment_mode")

            else:

               return


Mas a criação das Linhas de Pagamentos ocorre logo em seguida, então caso o Usuário selecione um Modo de Pagamento errado acaba criando uma Ordem de Pagto/Linhas de Pagto errados gerando outro problema, talvez isso poderia ser resolvido com um pop-up de Warning pedindo a Confirmação do Modo de Pagto escolhido ao Usuário.

Com o Wizard que você fez também funciona, porém é preciso verificar se a partir disso o campo Modo de Pagamento deve estar readonly porque mesmo com esse PR se o Usuário selecionar o Modo de Pagto direto no campo ao invés de usar o Wizard vai ocorrer o mesmo erro que você inclui no começo do PR, quer dizer o erro inicial persiste.

Temos que avaliar se isso deve ser feito via Wizard, como foi feito porém tratando para não permitir o usuário selecionar o Modo de Pagto diretamente, ou via Onchange, talvez com menos código, o que seria melhor?

É bom dizer também que existe uma diferença entre Erros do Código, responsabilidade dos Desenvolvedores, de erros de Cadastro, responsabilidade do Usuário, no caso do Modo de Pagamento até é possível alterar o campo com a Fatura não estando em Provisório, e acredito que nesse casos não foi considerado voltar a Fatura para Provisório porque já gerou um Documento Fiscal, é isso? Porque se fosse outro campo como o "Termos de Pagamento"/payment.terms isso já não seria possível por gerar as Linhas Financeiras aí o processo seria outro que é o Usuário Cancelar a Nota e gerar novamente com os dados corretos, nos podemos incluir Avisos, Validações e idealmente não deve ter mensagens de erro sem tratamento mas determinados erros precisam ser classificados para definir responsabilidades e custos.

Obrigado, @mbcosta, pela explicação. Enfrentamos o problema com um cliente que, após a postagem da fatura precisava alterar o modo de pagamento para o CNAB, porem esse processo do CNAB somente ocorre na ação do _post, cheguei a tentar uma solução pelo onchange mas me deparei com o mesmo erro de NewID, dessa maneira optei pelo Wizard. Qual caminho acha mais seguro/ideal para essa questão?

@mbcosta
Copy link
Contributor

mbcosta commented Aug 15, 2024

@kaynnan pode ser pelo wizard mesmo apenas adiciona o metodo onchange no Modo Pagamento para no caso do state Posted e CNAB apagar o valor informado, quer dizer não permitir o preenchimento alterando o valor para False mas retornando um Warning orientando sobre o como alterar via Wizard, isso já deve evitar o erro do caso onde o usuário tenta informar o campo com um CNAB diretamente pelo campo ao invés de usar o wizard.

Eu tentei ver se era possível chamar o wizard via onchange, porém existe apenas um modulo da OCA ainda na versão 8.0 OCA/web#579 que busca implementar isso.

@mileo
Copy link
Member

mileo commented Oct 15, 2024

Pessoal não seria melhor fazer isso por linha de lançamento? Trabalhando no account.move.line e no wizard já existente?

https://github.com/OCA/l10n-brazil/blob/14.0/l10n_br_account_payment_order/wizards/account_move_line_change.py

E ai já trabalhar os fluxos necessários, troca de banco, troca de forma de pagamento e etc?

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

Successfully merging this pull request may close these issues.

7 participants