diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e9bdf33a0490..1f104d65ef1f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,6 +7,7 @@ exclude: | ^l10n_br_mdfe_spec/models/v3_0/| # (don't reformat generated code) ^spec_driven_model/tests/| # (tests include generated code) ^l10n_br_nfse_ginfes/tests/nfse/| # (skip reformat in test data) + ^l10n_br_account_payment_brcobranca/tests/data/| # (don't reformat test data) # Files and folders generated by bots, to avoid loops ^setup/|/static/description/index\.html$| # We don't want to mess with tool-generated files diff --git a/l10n_br_account_payment_brcobranca/constants/br_cobranca.py b/l10n_br_account_payment_brcobranca/constants/br_cobranca.py index c7185c8136f2..dc611c3730a2 100644 --- a/l10n_br_account_payment_brcobranca/constants/br_cobranca.py +++ b/l10n_br_account_payment_brcobranca/constants/br_cobranca.py @@ -22,7 +22,7 @@ "001": BankRecord("banco_brasil", retorno=["400"], remessa=["240", "400"]), "004": BankRecord("banco_nordeste", retorno=["400"], remessa=["400"]), "021": BankRecord("banestes", retorno=[], remessa=[]), - "033": BankRecord("santander", retorno=["240"], remessa=["400"]), + "033": BankRecord("santander", retorno=["400", "240"], remessa=["400", "240"]), "041": BankRecord("banrisul", retorno=["400"], remessa=["400"]), "070": BankRecord("banco_brasilia", retorno=[], remessa=["400"]), "085": BankRecord("ailos", retorno=["240"], remessa=["240"]), diff --git a/l10n_br_account_payment_brcobranca/demo/account_payment_mode.xml b/l10n_br_account_payment_brcobranca/demo/account_payment_mode.xml index 3efbb2286de0..a2d25b15485c 100644 --- a/l10n_br_account_payment_brcobranca/demo/account_payment_mode.xml +++ b/l10n_br_account_payment_brcobranca/demo/account_payment_mode.xml @@ -97,4 +97,20 @@ brcobranca + + + brcobranca + + + + + brcobranca + + diff --git a/l10n_br_account_payment_brcobranca/models/account_move_line.py b/l10n_br_account_payment_brcobranca/models/account_move_line.py index 419632054c12..31e57049f0e7 100644 --- a/l10n_br_account_payment_brcobranca/models/account_move_line.py +++ b/l10n_br_account_payment_brcobranca/models/account_move_line.py @@ -29,7 +29,9 @@ class AccountMoveLine(models.Model): # brcobranca/boleto/itau_spec.rb def send_payment(self): - # super(AccountMoveLine, self).send_payment() + # Desnecessario chamar o super aqui o metodo + # que esta chamando já verifica isso. + wrapped_boleto_list = [] for move_line in self: @@ -58,7 +60,7 @@ def send_payment(self): "sacado_documento": move_line.partner_id.cnpj_cpf, "agencia": bank_account_id.bra_number, "conta_corrente": bank_account_id.acc_number, - "convenio": move_line.payment_mode_id.code_convetion, + "convenio": move_line.payment_mode_id.cnab_company_bank_code, "carteira": str(move_line.payment_mode_id.boleto_wallet), "nosso_numero": int( "".join(i for i in move_line.own_number if i.isdigit()) @@ -86,14 +88,6 @@ def send_payment(self): "instrucao1": move_line.payment_mode_id.instructions or "", } - # No Santander a carteira impressa no boleto é diferente da remessa. - if bank_account_id.bank_id.code_bc in ("033"): - boleto_cnab_api_data.update( - { - "carteira": str(move_line.payment_mode_id.boleto_wallet2), - } - ) - # Instrução de Juros if move_line.payment_mode_id.boleto_interest_perc > 0.0: valor_juros = move_line.currency_id.round( @@ -158,6 +152,10 @@ def send_payment(self): ) bank_account = move_line.payment_mode_id.fixed_journal_id.bank_account_id + # Abaixo Campos Especificos de cada caso + + # 021 - BANCO DO ESTADO DO ESPIRITO SANTO + # 004 - BANCO INTER if bank_account_id.bank_id.code_bc in ("021", "004"): boleto_cnab_api_data.update( { @@ -181,6 +179,18 @@ def send_payment(self): } ) + # Campo Santander + if bank_account_id.bank_id.code_bc == "033": + # Caso Santander possui: + # Codigo de Transmissao tamanho 20 no 400 no 240 e 15 + # Codigo do Convenio tamanho 7 + # no boleto é usado o convenio + boleto_cnab_api_data.update( + { + "convenio": move_line.payment_mode_id.convention_code, + } + ) + wrapped_boleto_list.append(boleto_cnab_api_data) return wrapped_boleto_list diff --git a/l10n_br_account_payment_brcobranca/models/account_payment_line.py b/l10n_br_account_payment_brcobranca/models/account_payment_line.py index 82a107991dea..e83d53b3fd4f 100644 --- a/l10n_br_account_payment_brcobranca/models/account_payment_line.py +++ b/l10n_br_account_payment_brcobranca/models/account_payment_line.py @@ -74,6 +74,51 @@ def _prepare_bank_line_banco_brasil(self, payment_mode_id, linhas_pagamentos): payment_mode_id.boleto_protest_code or "00" ) + # Caso Santander 400 precisa enviar o Nosso Numero com DV isso não acontece no + # 240, por enquanto é o único caso mapeado. + # Houve um PR https://github.com/kivanio/brcobranca/pull/236 na lib buscando + # resolver isso e foi apontando a contradição em ter para esse mesmo banco no + # caso do 400 a necessidade de informar o DV mas não precisar no 240, + # mas o mantedor da biblioteca não aceito a alteração. + # A melhor solução talvez seja ver a possibilidade de incluir ou fazer algo + # semelhante ao git-aggregator https://github.com/acsone/git-aggregator + # na API e com isso incluir um commit de outro repositorio que faça essa + # simples alteração porém mantendo a API ligada diretamente ao repo pricipal + # do BRcobranca, já que não existe o interesse em manter um Fork e um simples + # commit resolve o problema, por enquanto o calculo esta sendo feito aqui, se + # necessário ou isso for útil para outros casos pode ser visto de migrar esse + # calculo do modulo11 para um lugar genereico e facilitar seu uso exemplo + # l10n_br_account_payment_order/tools.py + def modulo11(self, num, base=9, r=0): + soma = 0 + fator = 2 + for c in reversed(num): + soma += int(c) * fator + if fator == base: + fator = 1 + fator += 1 + if r == 0: + soma = soma * 10 + digito = soma % 11 + if digito == 10: + digito = 0 + return digito + if r == 1: + resto = soma % 11 + return resto + + def _prepare_bank_line_santander(self, payment_mode_id, linhas_pagamentos): + if payment_mode_id.payment_method_code == "400": + nosso_numero = linhas_pagamentos["nosso_numero"] + # O campo deve ter tamanho 7 caso a Sequencia não esteja configurada + # corretamente é tratado aqui, talvez deva ser feito na validação + if len(nosso_numero) > 7: + start_point = len(nosso_numero) - 7 + nosso_numero = nosso_numero[start_point : len(nosso_numero)] + + dv = self.modulo11(nosso_numero, 9, 0) + linhas_pagamentos["nosso_numero"] = str(nosso_numero) + str(dv) + def prepare_bank_payment_line(self, bank_name_brcobranca): payment_mode_id = self.order_id.payment_mode_id linhas_pagamentos = self._prepare_boleto_line_vals() diff --git a/l10n_br_account_payment_brcobranca/models/account_payment_order.py b/l10n_br_account_payment_brcobranca/models/account_payment_order.py index a4e40e73c766..86d48eee2292 100644 --- a/l10n_br_account_payment_brcobranca/models/account_payment_order.py +++ b/l10n_br_account_payment_brcobranca/models/account_payment_order.py @@ -26,47 +26,49 @@ class PaymentOrder(models.Model): _inherit = "account.payment.order" - def _prepare_remessa_banco_brasil_400(self, remessa_values): + def _prepare_remessa_banco_brasil(self, remessa_values, cnab_type): remessa_values.update( { - "convenio": int(self.payment_mode_id.code_convetion), + "convenio": int(self.payment_mode_id.cnab_company_bank_code), "variacao_carteira": self.payment_mode_id.boleto_variation.zfill(3), - "convenio_lider": self.payment_mode_id.code_convenio_lider.zfill(7), + "convenio_lider": self.payment_mode_id.convention_code.zfill(7), "carteira": str(self.payment_mode_id.boleto_wallet).zfill(2), } ) - def _prepare_remessa_santander_400(self, remessa_values): + def _prepare_remessa_santander(self, remessa_values, cnab_type): remessa_values.update( { - "codigo_carteira": str(self.payment_mode_id.boleto_wallet), - "codigo_transmissao": self.payment_mode_id.transmission_code, + "codigo_carteira": self.payment_mode_id.boleto_wallet_code_id.code, + "codigo_transmissao": self.payment_mode_id.cnab_company_bank_code, "conta_corrente": misc.punctuation_rm( self.journal_id.bank_account_id.acc_number ), } ) - def _prepare_remessa_caixa_240(self, remessa_values): + def _prepare_remessa_caixa(self, remessa_values, cnab_type): remessa_values.update( { - "convenio": int(self.payment_mode_id.code_convetion), + "convenio": int(self.payment_mode_id.cnab_company_bank_code), "digito_agencia": self.journal_id.bank_account_id.bra_number_dig, } ) - def _prepare_remessa_ailos_240(self, remessa_values): + def _prepare_remessa_ailos(self, remessa_values, cnab_type): remessa_values.update( { - "convenio": int(self.payment_mode_id.code_convetion), + "convenio": int(self.payment_mode_id.cnab_company_bank_code), "digito_agencia": self.journal_id.bank_account_id.bra_number_dig, } ) - def _prepare_remessa_unicred_400(self, remessa_values): - remessa_values["codigo_beneficiario"] = int(self.payment_mode_id.code_convetion) + def _prepare_remessa_unicred(self, remessa_values, cnab_type): + remessa_values["codigo_beneficiario"] = int( + self.payment_mode_id.cnab_company_bank_code + ) - def _prepare_remessa_sicredi_240(self, remessa_values): + def _prepare_remessa_sicredi(self, remessa_values, cnab_type): bank_account_id = self.journal_id.bank_account_id remessa_values.update( { @@ -78,8 +80,10 @@ def _prepare_remessa_sicredi_240(self, remessa_values): } ) - def _prepare_remessa_bradesco_400(self, remessa_values): - remessa_values["codigo_empresa"] = int(self.payment_mode_id.code_convetion) + def _prepare_remessa_bradesco(self, remessa_values, cnab_type): + remessa_values["codigo_empresa"] = int( + self.payment_mode_id.cnab_company_bank_code + ) def get_file_name(self, cnab_type): context_today = fields.Date.context_today(self) @@ -159,10 +163,10 @@ def generate_payment_file(self): try: bank_method = getattr( - self, "_prepare_remessa_{}_{}".format(bank_brcobranca.name, cnab_type) + self, "_prepare_remessa_{}".format(bank_brcobranca.name) ) if bank_method: - bank_method(remessa_values) + bank_method(remessa_values, cnab_type) except Exception: pass diff --git a/l10n_br_account_payment_brcobranca/tests/data/boleto_teste_santander240.pdf b/l10n_br_account_payment_brcobranca/tests/data/boleto_teste_santander240.pdf new file mode 100644 index 000000000000..090d74ae1b16 Binary files /dev/null and b/l10n_br_account_payment_brcobranca/tests/data/boleto_teste_santander240.pdf differ diff --git a/l10n_br_account_payment_brcobranca/tests/data/boleto_teste_santander400.pdf b/l10n_br_account_payment_brcobranca/tests/data/boleto_teste_santander400.pdf new file mode 100644 index 000000000000..ee54c524c142 Binary files /dev/null and b/l10n_br_account_payment_brcobranca/tests/data/boleto_teste_santander400.pdf differ diff --git a/l10n_br_account_payment_brcobranca/tests/data/teste_remessa_santander240.REM b/l10n_br_account_payment_brcobranca/tests/data/teste_remessa_santander240.REM new file mode 100644 index 000000000000..0449bd6ba01c --- /dev/null +++ b/l10n_br_account_payment_brcobranca/tests/data/teste_remessa_santander240.REM @@ -0,0 +1,10 @@ +03300000 2097231608000169123456789012345 SUA EMPRESA LTDA BANCO SANTANDER 126022024 000001040 +03300011R01 030 2097231608000169 123456789012345 SUA EMPRESA LTDA 000000012602202400000000 +0330001300001P 010707200000133310000013331 0000000000019512 TESTE SANTANDER2602202400000000003000000000 02N26022024300000000000000000000000026022024000000000000300000000000000000000000000000000TESTE SANTANDER CNAB24001000300000 +0330001300002Q 012011034414000158AKRETION LTDA AVENIDA PAULISTA 807 CENTRO 01311915SAO PAULO SP0000000000000000 000000000000 +0330001300003R 01000000000000000000000000000000000000000000000000000000000000000000000000 +0330001300004P 010707200000133310000013331 0000000000027512 TESTE SANTANDER3103202400000000007000000000 02N26022024300000000000000000000000031032024000000000000700000000000000000000000000000000TESTE SANTANDER CNAB24002000300000 +0330001300005Q 012011034414000158AKRETION LTDA AVENIDA PAULISTA 807 CENTRO 01311915SAO PAULO SP0000000000000000 000000000000 +0330001300006R 01000000000000000000000000000000000000000000000000000000000000000000000000 +03300015 000008 +03399999 000001000010 diff --git a/l10n_br_account_payment_brcobranca/tests/data/teste_remessa_santander400.REM b/l10n_br_account_payment_brcobranca/tests/data/teste_remessa_santander400.REM new file mode 100644 index 000000000000..8f05aa361749 --- /dev/null +++ b/l10n_br_account_payment_brcobranca/tests/data/teste_remessa_santander400.REM @@ -0,0 +1,4 @@ +01REMESSA01COBRANCA 12345678901234567890SUA EMPRESA LTDA 033SANTANDER 2602240000000000000000 058000001 +1029723160800016912345678901234567890TESTE SANTANDER CNAB400/0100000019000000 00000000000000000000 000000501TESTE SANTANDER CNAB400/0126022400000000300000330000001N260224000000000000000002602240000000000300000000000000000000000000000211034414000158AKRETION LTDA AVENIDA PAULISTA 807 CENTRO 01311915SAO PAULO SP 00 000002 +1029723160800016912345678901234567890TESTE SANTANDER CNAB400/0200000027000000 00000000000000000000 000000501TESTE SANTANDER CNAB400/0231032400000000700000330000001N260224000000000000000003103240000000000700000000000000000000000000000211034414000158AKRETION LTDA AVENIDA PAULISTA 807 CENTRO 01311915SAO PAULO SP 00 000003 +9000004000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 diff --git a/l10n_br_account_payment_brcobranca/tests/test_payment_order.py b/l10n_br_account_payment_brcobranca/tests/test_payment_order.py index 6610ab5a61fd..2b2eae08761b 100644 --- a/l10n_br_account_payment_brcobranca/tests/test_payment_order.py +++ b/l10n_br_account_payment_brcobranca/tests/test_payment_order.py @@ -206,6 +206,28 @@ def test_banco_ailos_cnab_240(self): "teste_remessa_ailos240.REM", ) + def test_banco_santander_cnab_400(self): + """Teste Boleto e Remessa Banco Santander - CNAB 400""" + invoice_santander_cnab_400 = self.env.ref( + "l10n_br_account_payment_order.demo_invoice_payment_order_santander_cnab400" + ) + self._run_boleto_remessa( + invoice_santander_cnab_400, + "boleto_teste_santander400.pdf", + "teste_remessa_santander400.REM", + ) + + def test_banco_santander_cnab_240(self): + """Teste Boleto e Remessa Banco Santander - CNAB 240""" + invoice_santander_cnab_240 = self.env.ref( + "l10n_br_account_payment_order.demo_invoice_payment_order_santander_cnab240" + ) + self._run_boleto_remessa( + invoice_santander_cnab_240, + "boleto_teste_santander240.pdf", + "teste_remessa_santander240.REM", + ) + def test_bank_cnab_not_implement_brcobranca(self): """Test Bank CNAB not implemented in BRCobranca.""" invoice = self.env.ref( diff --git a/l10n_br_account_payment_order/__manifest__.py b/l10n_br_account_payment_order/__manifest__.py index a24d0b47173f..782c7c4b6663 100644 --- a/l10n_br_account_payment_order/__manifest__.py +++ b/l10n_br_account_payment_order/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Brazilian Payment Order", - "version": "14.0.3.5.0", + "version": "14.0.4.0.0", "license": "AGPL-3", "author": "KMEE, Akretion, Odoo Community Association (OCA)", "maintainers": ["mbcosta"], @@ -33,6 +33,9 @@ "data/cnab_codes/banco_unicred_cnab_240_400.xml", "data/cnab_codes/banco_ailos_cnab_240.xml", "data/cnab_codes/banco_santander_cnab_240_400.xml", + # Boleto Wallet Code + "data/cnab_codes/banco_santander_boleto_wallet_code.xml", + "data/cnab_codes/banco_bradesco_boleto_wallet_code.xml", # Wizards "wizards/account_payment_line_create_view.xml", "wizards/account_move_line_change.xml", @@ -47,6 +50,7 @@ "views/account_payment_views.xml", "views/l10n_br_cnab_mov_instruction_code_view.xml", "views/account_move_view.xml", + "views/l10n_br_cnab_boleto_wallet_code_view.xml", ], "demo": [ "demo/account_payment_method.xml", diff --git a/l10n_br_account_payment_order/data/cnab_codes/banco_bradesco_boleto_wallet_code.xml b/l10n_br_account_payment_order/data/cnab_codes/banco_bradesco_boleto_wallet_code.xml new file mode 100644 index 000000000000..90f297bc670e --- /dev/null +++ b/l10n_br_account_payment_order/data/cnab_codes/banco_bradesco_boleto_wallet_code.xml @@ -0,0 +1,73 @@ + + + + + + + Cobrança Simples + 1 + + + + + + Cobrança Vinculada + 2 + + + + + + Cobrança Caucionada + 3 + + + + + + Cobrança Descontada + 4 + + + + + + Cobrança Vendor + 5 + + + + + diff --git a/l10n_br_account_payment_order/data/cnab_codes/banco_santander_boleto_wallet_code.xml b/l10n_br_account_payment_order/data/cnab_codes/banco_santander_boleto_wallet_code.xml new file mode 100644 index 000000000000..3bc0b00c8497 --- /dev/null +++ b/l10n_br_account_payment_order/data/cnab_codes/banco_santander_boleto_wallet_code.xml @@ -0,0 +1,230 @@ + + + + + + + Cobrança Simples (Eletrônica com Registro) + 1 + + + + + + Cobrança Caucionada (Eletrônica com Registro) + 3 + + + + + + Cobrança Simples (Rápida com Registro) + 5 + + + + + + Cobrança Caucionada (Rápida com Registro) + 6 + + + + + + Cobrança Descontada (Eletrônica com Registro) + 7 + + + + + + Cobrança Cessão (Eletrônica com Registro)* + 8 + + + *Carteira específica para Cessão de Crédito, deverá ser utilizada somente a partir da contratação do produto SX Integra, que possibilitará a cessão eletrônica de recebíveis. + + + + + + Cobrança Simples (Sem Registro e Eletrônica com Registro) + 1 + + + + + + Cobrança Caucionada (Eletrônica com Registro e Convencional com Registro) + 3 + + + + + + Cobrança Descontada (Eletrônica com Registro) + 4 + + + + + + Cobrança Simples (Rápida com Registro)* + 5 + + + *Carteira específica para registro do Boleto com QR CODE. + + + + Cobrança Caucionada (Rápida com Registro) + 6 + + + + + + Transferência de Titularidade - Sem Devolução (Cobrança Simples - Eletrônica com Registro e Rápida com Registro)** + 7 + + + **Carteira específica para FIDC (Fundo de Direitos Creditórios) + + + + Cobrança Cessão (Eletrônica com Registro)**** + 8 + + + ****Carteira específica para Cessão de Crédito, deverá ser utilizada somente a partir da contratação do produto SX Integra, que possibilitará a cessão eletrônica de recebíveis. + + + + + Transferência de Titularidade - Com Devolução (Cobrança Simples - Eletrônica com Registro e Rápida com Registro) + 9 + + + + + + Cobrança Simples (Sem Registro sem pré-impresso e com pré-impresso)*** + B + + + ***Código específico para registrar boletos sem registro (linha com modalidade 102) ou cobrança rápida (101), com o fator de vencimento de valor zerados na linha digitavel/código de barras, Opção válida apenas para a entrada de Boletos, para maiores detalhes vide a vide Nota 46. + + + + diff --git a/l10n_br_account_payment_order/data/cnab_codes/banco_santander_cnab_240_400.xml b/l10n_br_account_payment_order/data/cnab_codes/banco_santander_cnab_240_400.xml index 23eec01d5604..b4e33da52cdc 100644 --- a/l10n_br_account_payment_order/data/cnab_codes/banco_santander_cnab_240_400.xml +++ b/l10n_br_account_payment_order/data/cnab_codes/banco_santander_cnab_240_400.xml @@ -1,1030 +1,1080 @@ - - + + - + - - Entrada de boleto - 01 - + Entrada de boleto + 01 + - - + + - - Pedido de baixa - 02 - + Pedido de baixa + 02 + - - + + - - Concessão de abatimento - 04 - + Concessão de abatimento + 04 + - - + + - - Cancelamento do abatimento - 05 - + Cancelamento do abatimento + 05 + - - + + - - Alteração do vencimento - 06 - + Alteração do vencimento + 06 + - - + + - - + Alteração da identificação do boleto na empresa (Controle Participante) - 07 - 07 + - - + + - - Alteração seu Número - 08 - + Alteração seu Número + 08 + - - + + - - Pedido de Protesto - 09 - + Pedido de Protesto + 09 + - - + + - - Concessão de Desconto - 10 - + Concessão de Desconto + 10 + - - + + - - Cancelamento de Desconto - 11 - + Cancelamento de Desconto + 11 + - - + + - - Transferência de Titularidade automática - 12 - + Transferência de Titularidade automática + 12 + - - + + - - Transferência da carteira Simples para Cessão** - 15 - + Transferência da carteira Simples para a carteira Cessão** + 15 + - - + + **O código movimento de remessa “15” é utilizado exclusivamente para transferência de boletos da carteira Simples para a carteira de Cessão, mediante a contratação do produto SX Integra que possibilita a cessão eletrônica de recebíveis. + + - - Baixa de Cessão por Descaracterização*** - 16 - + Baixa de Cessão por Descaracterização*** + 16 + - - + + *** Os códigos de movimento de remessa “16” e “17” só podem ser utilizadas para boletos já registrados na carteira de Cessão, mediante regras pré-determinadas na contratação do produto SX Integra. + + - - Baixa de Cessão por Pagamento*** - 17 - + Baixa de Cessão por Pagamento*** + 17 + - - + + *** Os códigos de movimento de remessa “16” e “17” só podem ser utilizadas para boletos já registrados na carteira de Cessão, mediante regras pré-determinadas na contratação do produto SX Integra. + + - - Pedido de Sustação de Protesto - 18 - + Pedido de Sustação de Protesto + 18 + - - + + - - Alteração de outros dados* - 31 - + Alteração de outros dados* + 31 + - - + + *O código movimento de remessa “31” – É utilizado para tratamento de Alterações de outros dados “Protesto”. Exemplo: “31” – Alteração de outros dados, atende apenas alteração dos campos: - Segmento “P” (016 – 017) – Alteração de outros dados - Segmento “P” (221 – 221) – Tipo de prazo para protesto (ex.: De Dias Uteis para Dias Corridos) - Segmento “P” (222 – 223) – Número de dias para protesto (ex.: de 10 dias para 05 dias) + + - - Alteração do valor nominal do boleto - 47 - + Alteração do valor nominal do boleto + 47 + - - + + - - Alteração do valor mínimo/percentual - 48 - + Alteração do valor mínimo/percentual + 48 + - - + + - - Alteração do valor máximo/percentual - 49 - + Alteração do valor máximo/percentual + 49 + - - + + - - Não Protestar (Antes de iniciar o ciclo de protesto) - 98 - + Não Protestar (Antes de iniciar o ciclo de protesto) + 98 + - - + + - + - - Entrada confirmada - 02 - + Entrada confirmada + 02 + - - + + - - Entrada rejeitada - 03 - + Entrada rejeitada + 03 + - - + + - - Transferência para carteira Simples - 04 - + Transferência para carteira Simples + 04 + - - + + - - + Transferência para Carteira Desconto/Penhor/Vendor/FIDC/Cessão - 05 - 05 + - - + + - - Liquidação - 06 - + Liquidação + 06 + - - + + - - Confirmação do Recebimento do Cancelamento do Desconto - 08 - + Confirmação do Recebimento do Cancelamento do Desconto + 08 + - - + + - - Baixa - 09 - + Baixa + 09 + - - + + - - Boletos em carteira (em ser) - 11 - + Boletos em carteira (em ser) + 11 + - - + + - - Confirmação recebimento instrução de abatimento - 12 - + Confirmação recebimento instrução de abatimento + 12 + - - + + - - + Confirmação recebimento instrução de cancelamento abatimento - 13 - 13 + - - + + - - Confirmação recebimento instrução alteração de vencimento - 14 - + Confirmação recebimento instrução alteração de vencimento + 14 + - - + + - - Liquidado após baixa ou liquidação boleto não registrado - 17 - + Liquidado após baixa ou liquidação boleto não registrado + 17 + - - + + - - Confirmação recebimento instrução de protesto - 19 - + Confirmação recebimento instrução de protesto + 19 + - - + + - - + Confirmação recebimento instrução de sustação/Não Protestar - 20 - 20 + - - + + - - Remessa a cartório (aponte em cartório) - 23 - + Remessa a cartório (aponte em cartório) + 23 + - - + + - - Retirada de cartório e manutenção em carteira - 24 - + Retirada de cartório e manutenção em carteira + 24 + - - + + - - Protestado e baixado (baixa por ter sido protestado) - 25 - + Protestado e baixado (baixa por ter sido protestado) + 25 + - - + + - - Instrução rejeitada - 26 - + Instrução rejeitada + 26 + - - + + - - Confirmação do pedido de alteração de outros dados - 27 - + Confirmação do pedido de alteração de outros dados + 27 + - - + + - - Debito de tarifas/custas - 28 - + Debito de tarifas/custas + 28 + - - + + - - Ocorrências do Pagador - 29 - + Ocorrências do Pagador + 29 + - - + + - - Alteração de dados rejeitada - 30 - + Alteração de dados rejeitada + 30 + - - + + - - Código de IOF inválido - 32 - + Código de IOF inválido + 32 + - - + + - - Boleto DDA reconhecido pelo Pagador - 51 - + Boleto DDA reconhecido pelo Pagador + 51 + - - + + - - Boleto DDA nâo reconhecido pelo Pagador - 52 - + Boleto DDA nâo reconhecido pelo Pagador + 52 + - - + + - - Boleto DDA recusado pela CIP - 53 - + Boleto DDA recusado pela CIP + 53 + - - + + - - Confirmação de Alteração do Valor Nominal do Boleto - 61 - + Confirmação de Alteração do Valor Nominal do Boleto + 61 + - - + + - - Confirmação de Alteração do Valor ou Percentual Mínimo - 91 - + Confirmação de Alteração do Valor ou Percentual Mínimo + 91 + - - + + - - Confirmação de Alteração do Valor ou Percentual Máximo - 92 - + Confirmação de Alteração do Valor ou Percentual Máximo + 92 + - - + + - - Baixa Operacional - 93 - + Baixa Operacional + 93 + - - + + - - Cancelamento da Baixa Operacional - 94 - + Cancelamento da Baixa Operacional + 94 + - - + + - - Pagador DDA - A4 - + Pagador DDA + A4 + - - + + - - + + - + - - Entrada de boleto - 01 - + Entrada de boleto + 01 + - - + + - - Baixa de boleto - 02 - + Baixa de boleto + 02 + - - + + - - Concessão de abatimento - 04 - + Concessão de abatimento + 04 + - - + + - - Cancelamento do abatimento - 05 - + Cancelamento do abatimento + 05 + - - + + - - Alteração do vencimento - 06 - + Alteração do vencimento + 06 + - - + + - - Alteração do número controle beneficiário - 07 - + Alteração do número controle beneficiário + 07 + - - + + - - Alteração do Seu Número - 08 - + Alteração do Seu Número + 08 + - - + + - - Protestar - 09 - + Protestar + 09 + - - + + - - Transferência da carteira Simples para Cessão* - 15 - + Transferência da carteira Simples para Cessão* + 15 + - - + + *O código movimento de remessa “15” é utilizado exclusivamente para transferência de boletos da carteira Simples para a carteira de Cessão, mediante a contratação do produto SX Integra que possibilita a cessão eletrônica de recebíveis. + + - - Baixa de Cessão por Descaracterização** - 16 - + Baixa de Cessão por Descaracterização** + 16 + - - + + **Os códigos de movimento de remessa “16” e “17” só podem ser utilizadas para boletos já registrados na carteira de Cessão, mediante regras pré-determinadas na contratação do produto SX Integra. + + - - Baixa de Cessão por Pagamento** - 17 - + Baixa de Cessão por Pagamento** + 17 + - - + + **Os códigos de movimento de remessa “16” e “17” só podem ser utilizadas para boletos já registrados na carteira de Cessão, mediante regras pré-determinadas na contratação do produto SX Integra. + + - - Sustar o protesto (Após início do ciclo de protesto) - 18 - + Sustar o protesto (Após início do ciclo de protesto) + 18 + - - + + - - Alteração do valor nominal do boleto - 47 - + Alteração do valor nominal do boleto + 47 + - - + + - - Alteração do valor mínimo/percentual - 48 - + Alteração do valor mínimo/percentual + 48 + - - + + - - Alteração do valor máximo/percentual - 49 - + Alteração do valor máximo/percentual + 49 + - - + + - + - - Boleto não existe - 01 - + Boleto não existe + 01 + - - + + - - Entrada boleto confirmada - 02 - + Entrada boleto confirmada + 02 + - - + + - - Entrada boleto rejeitada - 03 - + Entrada boleto rejeitada + 03 + - - + + - - Transferência para carteira Simples - 04 - + Transferência para carteira Simples + 04 + - - + + - - Transferência para Carteira Penhor/Desconto/Cessão - 05 - + Transferência para Carteira Penhor/Desconto/Cessão + 05 + - - + + - - Liquidação - 06 - + Liquidação + 06 + - - + + - - Liquidação por Conta - 07 - + Liquidação por Conta + 07 + - - + + - - Liquidação por Saldo - 08 - + Liquidação por Saldo + 08 + - - + + - - Baixa Automática - 09 - + Baixa Automática + 09 + - - + + - - Boleto Baixado Conforme Instrução - 10 - + Boleto Baixado Conforme Instrução + 10 + - - + + - - Boletos em carteira (em ser) - 11 - + Boletos em carteira (em ser) + 11 + - - + + - - Abatimento Concedido - 12 - + Abatimento Concedido + 12 + - - + + - - Abatimento Cancelado - 13 - + Abatimento Cancelado + 13 + - - + + - - Alteração de Vencimento - 14 - + Alteração de Vencimento + 14 + - - + + - - Confirmação de Protesto* - 15 - + Confirmação de Protesto* + 15 + - - + + O código 15 – Confirmação de Protesto, corresponde ao momento em que o tabelionato recebe o boleto para tratativa (intimação ao Pagador). O boleto ainda não está protestado neste cenário. Quando protestado, o código encaminhado é o 25 - Boleto Protestado. + + - - Boleto Baixado/Liquidado - 16 - + Boleto Baixado/Liquidado + 16 + - - + + - - Liquidado em Cartório - 17 - + Liquidado em Cartório + 17 + - - + + - - Boleto Enviado a Cartório - 21 - + Boleto Enviado a Cartório + 21 + - - + + - - Boleto Retirado do Cartório - 22 - + Boleto Retirado do Cartório + 22 + - - + + - - Custas de Cartório - 24 - + Custas de Cartório + 24 + - - + + - - Boleto Protestado - 25 - + Boleto Protestado + 25 + - - + + - - Sustar Protesto* - 26 - + Sustar Protesto* + 26 + - - + + O código 26 – Sustar Protesto, corresponde ao momento em que o boleto já está confirmado no tabelionato (código 15) e está em processo de intimação, mas não há desejo em prosseguir com o protesto. Diferente do código 38 - Não Protestar, utilizado para o cenário onde o boleto não iniciou o processo de cartório. + + - - Cancelar Boleto Protestado - 27 - + Cancelar Boleto Protestado + 27 + - - + + - - Boleto DDA Reconhecido pelo Pagador - 35 - + Boleto DDA Reconhecido pelo Pagador + 35 + - - + + - - Boleto DDA Não Reconhecido pelo Pagador - 36 - + Boleto DDA Não Reconhecido pelo Pagador + 36 + - - + + - - Boleto DDA Recusado pela CIP - 37 - + Boleto DDA Recusado pela CIP + 37 + - - + + - - Não Protestar (antes de iniciar o ciclo de protesto) - 38 - + Não Protestar (antes de iniciar o ciclo de protesto) + 38 + - - + + - - Espécie de Boleto não permite a instrução - 39 - + Espécie de Boleto não permite a instrução + 39 + - - - + + - - Confirmação de Alteração do Valor Nominal do Boleto - 61 - + Confirmação de Alteração do Valor Nominal do Boleto + 61 + - - + + - - Confirmação de Alteração do Valor ou Percentual mínimo - 62 - + Confirmação de Alteração do Valor ou Percentual mínimo + 62 + - - + + - - Confirmação de Alteração do Valor ou Percentual máximo - 63 - + Confirmação de Alteração do Valor ou Percentual máximo + 63 + - - + + - - Baixa Operacional Enviado pela CIP - 93 - + Baixa Operacional Enviado pela CIP + 93 + - - + + - - Cancelamento da Baixa Operacional Enviado pela Cip - 94 - + Cancelamento da Baixa Operacional Enviado pela Cip + 94 + - - - + + diff --git a/l10n_br_account_payment_order/demo/account_invoice.xml b/l10n_br_account_payment_order/demo/account_invoice.xml index f8b0244e7cb2..a3b46a560bbd 100644 --- a/l10n_br_account_payment_order/demo/account_invoice.xml +++ b/l10n_br_account_payment_order/demo/account_invoice.xml @@ -143,7 +143,6 @@ /> - Teste AILOS CNAB240 @@ -164,6 +163,47 @@ /> + + + + Teste Santander CNAB400 + + + out_invoice + + + TESTE Intruções Boleto + + + + + + Teste Santander CNAB240 + + + out_invoice + + + TESTE Intruções Boleto + + + + + + Banco Santander + bank + BNC7 + + + + + + Banco Teste Manual diff --git a/l10n_br_account_payment_order/demo/account_payment_mode.xml b/l10n_br_account_payment_order/demo/account_payment_mode.xml index 7f8f0fd0c6ca..7178cd04a9a4 100644 --- a/l10n_br_account_payment_order/demo/account_payment_mode.xml +++ b/l10n_br_account_payment_order/demo/account_payment_mode.xml @@ -8,7 +8,7 @@ False - 0001222130126 + 0001222130126 fixed True True @@ -83,7 +83,7 @@ False - 0001222130126 + 0001222130126 fixed True False @@ -162,7 +162,7 @@ ref="account.account_payment_method_manual_in" /> False - 0001222130126 + 0001222130126 fixed @@ -180,7 +180,7 @@ ref="account.account_payment_method_manual_in" /> False - 0001222130126 + 0001222130126 False - 0001222130126 + 0001222130126 False - 0001222130126 + 0001222130126 1 True 3 + DM 19 S @@ -299,7 +300,7 @@ name="not_payment_account_id" ref="1_account_template_32333_avoid_travis_error" /> - 0001222130126 + 0001222130126 - 92035760 + 92035760 2 5 - 72234050 + 72234050 False 3 5 - 101004 + 101004 False - 12345 + 12345 - 12345 + 12345 - 000122 + 000122 - 000122 + 000122 @@ -751,7 +752,7 @@ False - 12345 + 12345 2 1 @@ -840,8 +841,8 @@ ref="1_account_template_32333_avoid_travis_error" /> - 1234 - 7654321 + 1234 + 7654321 - 0001222130126 + 0001222130126 + + + + + + Cobrança Banco Santander 400 + + Pagavel em qualquer banco ate o vencimento + fixed + + True + True + + 101 + + DM + 35 + S + 1 + + + False + + + + + + + 12345678901234567890 + + 1234567 + + + + + + + + + + + + + + + + Cobrança Banco Santander 240 + + Pagavel em qualquer banco ate o vencimento + fixed + + True + True + + 101 + + DM + 35 + S + 1 + + + False + + + + + + + 123456789012345 + 1234567 + + + + + + + + + + + diff --git a/l10n_br_account_payment_order/demo/ir_sequence.xml b/l10n_br_account_payment_order/demo/ir_sequence.xml index 99034885db21..33124add9a6c 100644 --- a/l10n_br_account_payment_order/demo/ir_sequence.xml +++ b/l10n_br_account_payment_order/demo/ir_sequence.xml @@ -153,7 +153,6 @@ - Nosso número - Manual Test nosso.numero - Manual Test @@ -163,7 +162,6 @@ - Nosso número - Bradesco 400 nosso.numero - Bradesco 400 @@ -272,6 +270,41 @@ + + Nosso Número - Santander 400 + nosso.numero - Santander 400 + + + + + + + + + Nosso Número - Santander 240 + nosso.numero - Santander 240 + + + + + + + + Sequencia Arquivo CNAB - Santander 400 + Sequencia Arquivo CNAB - Santander 400 + + + + + + + Sequencia Arquivo CNAB - Santander 240 + Sequencia Arquivo CNAB - Santander 240 + + + + + Nosso número - Main Company nosso.numero - Main Company diff --git a/l10n_br_account_payment_order/migrations/14.0.4.0.0/pre-migration.py b/l10n_br_account_payment_order/migrations/14.0.4.0.0/pre-migration.py new file mode 100644 index 000000000000..90b837d05491 --- /dev/null +++ b/l10n_br_account_payment_order/migrations/14.0.4.0.0/pre-migration.py @@ -0,0 +1,31 @@ +# Copyright (C) 2024-Today - Akretion (). +# @author Magno Costa +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + +_column_renames = { + "account_payment_mode": [ + ("code_convetion", "cnab_company_bank_code"), + ("code_convenio_lider", "convention_code"), + ], +} + + +@openupgrade.migrate(use_env=True) +def migrate(env, version): + + # Apagando o objeto bank.payment.line + openupgrade.logged_query( + env.cr, + """ + DELETE FROM ir_model_fields WHERE model = 'bank.payment.line' + """, + ) + openupgrade.logged_query( + env.cr, + """ + DELETE FROM ir_model WHERE model = 'bank.payment.line' + """, + ) + openupgrade.rename_columns(env.cr, _column_renames) diff --git a/l10n_br_account_payment_order/models/__init__.py b/l10n_br_account_payment_order/models/__init__.py index 537d40af0748..618d71ee4c61 100644 --- a/l10n_br_account_payment_order/models/__init__.py +++ b/l10n_br_account_payment_order/models/__init__.py @@ -15,3 +15,4 @@ from . import l10n_br_cnab_data_abstract from . import l10n_br_cnab_return_move_code from . import l10n_br_cnab_mov_intruction_code +from . import l10n_br_cnab_boleto_wallet_code diff --git a/l10n_br_account_payment_order/models/account_payment_line.py b/l10n_br_account_payment_order/models/account_payment_line.py index be55285fc8ad..6a63ebd86a40 100644 --- a/l10n_br_account_payment_order/models/account_payment_line.py +++ b/l10n_br_account_payment_order/models/account_payment_line.py @@ -280,51 +280,3 @@ def _prepare_boleto_line_vals(self): # o campo Code do objeto. "identificacao_ocorrencia": self.mov_instruction_code_id.code, } - - -class BankPaymentLine(models.Model): - _name = "bank.payment.line" - _description = "Bank Payment Lines" - # TODO: Sem isso acontece o erro abaixo, por isso é preciso incluir o objeto - # bank.payment.line vazio e rodar um update, - # Em outro PR o objeto será removido e assim em um terceiro update vai - # limpar o Warning. Para evitar problemas o melhor será remover o objeto - # na migração de versão v15 ou v16. - # LOG com erro. - # Referencia https://github.com/odoo/odoo/issues/44767 - # - # 2023-03-10 21:15:22,323 72 INFO db odoo.addons.base.models.ir_model: - # Deleting 1622@ir.model.fields.selection ( - # l10n_br_account_payment_order. - # selection__bank_payment_line__last_cnab_state__done) - # 2023-03-10 21:15:22,326 72 WARNING db odoo.modules.loading: - # Transient module states were reset - # 2023-03-10 21:15:22,328 72 ERROR db odoo.modules.registry: - # Failed to load registry - # 2023-03-10 21:15:22,328 72 CRITICAL db odoo.service.server: - # Failed to initialize database `db`. - # Traceback (most recent call last): - # File "/odoo/src/odoo/service/server.py", line 1201, in preload_registries - # registry = Registry.new(dbname, update_module=update_module) - # File "/odoo/src/odoo/modules/registry.py", line 89, in new - # odoo.modules.load_modules(registry._db, force_demo, status, update_module) - # File "/odoo/src/odoo/modules/loading.py", line 505, in load_modules - # env['ir.model.data']._process_end(processed_modules) - # File "/odoo/src/odoo/addons/base/models/ir_model.py", - # line 2310, in _process_end - # self._process_end_unlink_record(record) - # File "/odoo/src/odoo/addons/base/models/ir_model.py", - # line 2233, in _process_end_unlink_record - # record.unlink() - # File "/odoo/src/odoo/addons/base/models/ir_model.py", - # line 1380, in unlink - # self._process_ondelete() - # File "/odoo/src/odoo/addons/base/models/ir_model.py", - # line 1418, in _process_ondelete - # Model = self.env[selection.field_id.model] - # File "/odoo/src/odoo/api.py", line 476, in __getitem__ - # return self.registry[model_name]._browse(self, (), ()) - # File "/odoo/src/odoo/modules/registry.py", - # line 177, in __getitem__ - # return self.models[model_name] - # KeyError: 'bank.payment.line' diff --git a/l10n_br_account_payment_order/models/account_payment_mode.py b/l10n_br_account_payment_order/models/account_payment_mode.py index 4e3939718a35..843652c0a374 100644 --- a/l10n_br_account_payment_order/models/account_payment_mode.py +++ b/l10n_br_account_payment_order/models/account_payment_mode.py @@ -99,7 +99,7 @@ def _selection_cnab_processor(self): ) @api.constrains( - "code_convetion", + "cnab_company_bank_code", "cnab_sequence_id", "fixed_journal_id", "boleto_wallet", diff --git a/l10n_br_account_payment_order/models/account_payment_order.py b/l10n_br_account_payment_order/models/account_payment_order.py index 4c36bf353e0a..d1c4165587fb 100644 --- a/l10n_br_account_payment_order/models/account_payment_order.py +++ b/l10n_br_account_payment_order/models/account_payment_order.py @@ -53,14 +53,11 @@ class AccountPaymentOrder(models.Model): help="Campo G029 do CNAB", ) - code_convetion = fields.Char( - related="payment_mode_id.code_convetion", - help="Campo G007 do CNAB", + cnab_company_bank_code = fields.Char( + related="payment_mode_id.cnab_company_bank_code", ) - code_convenio_lider = fields.Char( - string="Convênio Líder", related="payment_mode_id.code_convenio_lider" - ) + convention_code = fields.Char(related="payment_mode_id.convention_code") indicative_form_payment = fields.Selection( selection=INDICATIVO_FORMA_PAGAMENTO, diff --git a/l10n_br_account_payment_order/models/l10n_br_cnab_boleto_fields.py b/l10n_br_account_payment_order/models/l10n_br_cnab_boleto_fields.py index 7b16f50700ec..8f9301d471a6 100644 --- a/l10n_br_account_payment_order/models/l10n_br_cnab_boleto_fields.py +++ b/l10n_br_account_payment_order/models/l10n_br_cnab_boleto_fields.py @@ -18,17 +18,45 @@ class L10nBrCNABBoletoFields(models.AbstractModel): string="Instruções de cobrança", ) - code_convetion = fields.Char( - string="Código do Convênio no Banco", + # Devido a falta de padrão entre os Bancos/CNAB mesmo um campo que + # possui o objetivo de armazenar a mesma informação pode ter diferentes + # nomes Código da Empresa/Beneficiario/Convenio/Transmissão mas é + # possível identifica-lo como: + # Campo que tem o código que identifica a Empresa no Banco + # e que na maioria dos casos tem o tamanho 20 + # Para evitar criar campos duplicados porque todos contém a mesma + # informação, como nesse exemplo, foi usado apenas um e na visão + # está sendo alterado o atributo String de acordo com a nomenclatura + # usada por cada Banco + cnab_company_bank_code = fields.Char( + string="Código da Empresa no Banco", size=20, - help="Campo G007 do CNAB", - tracking=True, - ) - - code_convenio_lider = fields.Char( - string="Convênio Líder", + help="""Campo que tem o Código que identifica a Empresa no Banco e que + tem na maioria dos casos o tamanho 20, devido a falta de padrão entre + os Bancos e CNAB pode ter diferentes nomes Código da Empresa, Beneficiario, + Convenio, Transmissão, campo G007 e etc porém contém a mesma informação.""", + tracking=True, + ) + + # Em alguns casos além do 'Código da Empresa no Banco' pode existir + # outro campo com uma informação referente a: + # Um código com tamanho 7 que faz referencia a um + # Convenio ou contrato entre a empresa e o Banco + # Aqui entra a mesma questão do campo acima, devido a falta de + # nomenclatura dependendendo do Banco/CNAB o nome pode variar mas + # é importante identifica-lo para evitar a necessidade de criar um + # novo campo assim diminuindo a duplicação de campos. + # Por enquanto os casos mapeados são: + # - Banco do Brasil - chamado de Código do Convênio Líder + # - Banco Santander - chamado de Código do Convênio + convention_code = fields.Char( + string="Código do Convênio", size=7, - help="Código do Convênio Líder, exclusivo para o Banco do Brasil", + help="""Código do Convênio, campo com tamanho 7 usado em alguns casos + onde além do 'Código da Empresa tamanho 20' existe esse segundo campo, + casos mapeados hoje são Banco do Brasil como Código do Convênio Líder + e o Banco Santander como Código do Convênio. + """, tracking=True, ) @@ -51,21 +79,6 @@ class L10nBrCNABBoletoFields(models.AbstractModel): tracking=True, ) - boleto_wallet2 = fields.Char( - string="Carteira Boleto", - help="Código da carteira para ser impresso no boleto, " - "quando o mesmo for diferente do impresso na remessa.", - size=3, - tracking=True, - ) - - transmission_code = fields.Char( - string="Código de Transmissão", - help="Informação cedida pelo banco que identifica o arquivo remessa do cliente", - size=20, - tracking=True, - ) - boleto_modality = fields.Char( string="Modalidade", size=2, @@ -322,3 +335,12 @@ class L10nBrCNABBoletoFields(models.AbstractModel): " usado pelos bancos Sicred/Unicred e Sicoob.", tracking=True, ) + + # Código da Carteira ou Tipo de Cobrança usado por + # Santanter 400 e 240 + # Bradesco 240 + boleto_wallet_code_id = fields.Many2one( + comodel_name="l10n_br_cnab.boleto.wallet.code", + string="Boleto Wallet Code", + tracking=True, + ) diff --git a/l10n_br_account_payment_order/models/l10n_br_cnab_boleto_wallet_code.py b/l10n_br_account_payment_order/models/l10n_br_cnab_boleto_wallet_code.py new file mode 100644 index 000000000000..4f0597ea939c --- /dev/null +++ b/l10n_br_account_payment_order/models/l10n_br_cnab_boleto_wallet_code.py @@ -0,0 +1,58 @@ +# Copyright (C) 2024-Today - Akretion (). +# @author Magno Costa +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class L10nBrCNABBoletoWalletCode(models.Model): + _name = "l10n_br_cnab.boleto.wallet.code" + _inherit = ["l10n_br_cnab.data.abstract", "mail.thread"] + _description = "CNAB Boleto Wallet Code" + + bank_ids = fields.Many2many( + string="Banks", + comodel_name="res.bank", + relation="l10n_br_cnab_boleto_wallet_code_bank_rel", + column1="bank_id", + column2="l10n_br_cnab_boleto_wallet_code_id", + tracking=True, + ) + + payment_method_ids = fields.Many2many( + comodel_name="account.payment.method", + string="Payment Methods", + relation="l10n_br_cnab_boleto_wallet_code_payment_method_rel", + column1="payment_method_id", + column2="l10n_br_cnab_boleto_wallet_code_id", + tracking=True, + ) + + comment = fields.Text() + + # TODO: Forma encontrada para pode fazer o Group By, na v15 + # parece já ser possivel usar campos many2many. + # Também deve ser considerado em apagar o campo many2many e deixar + # apenas o many2one já que, por enquanto, não há bancos diferentes + # usando o mesmo conjunto de codigos apenas diferentes cnab( 240/400 ) + bank_id = fields.Many2one( + comodel_name="res.bank", compute="_compute_bank_id", store=True + ) # it is possible to search only among stored fields + + payment_method_id = fields.Many2one( + comodel_name="account.payment.method", + compute="_compute_payment_method_id", + store=True, + ) # it is possible to search only among stored fields + + @api.depends("bank_ids") + def _compute_bank_id(self): + for record in self: + record.bank_id = record.bank_ids and record.bank_ids[0] or False + + @api.depends("payment_method_ids") + def _compute_payment_method_id(self): + for record in self: + record.payment_method_id = ( + record.payment_method_ids and record.payment_method_ids[0] or False + ) diff --git a/l10n_br_account_payment_order/models/l10n_br_cnab_data_abstract.py b/l10n_br_account_payment_order/models/l10n_br_cnab_data_abstract.py index 560b417142f1..40389b456506 100644 --- a/l10n_br_account_payment_order/models/l10n_br_cnab_data_abstract.py +++ b/l10n_br_account_payment_order/models/l10n_br_cnab_data_abstract.py @@ -29,10 +29,6 @@ def name_get(self): @api.constrains("code") def check_code(self): for record in self: - # Tamanho do campo é padrão 2 p/ todos os codigos CNAB ? - if len(record.code) != 2: - raise ValidationError(_("The field Code should have two characters.")) - # Mesmo o record que está sendo alterado não ter sido ainda salvo # a pesquisa acaba trazendo ele, por isso o filtro 'id' code_already_exist = record.search( diff --git a/l10n_br_account_payment_order/models/l10n_br_cnab_mov_intruction_code.py b/l10n_br_account_payment_order/models/l10n_br_cnab_mov_intruction_code.py index f042503dba49..b06bfba8f9f9 100644 --- a/l10n_br_account_payment_order/models/l10n_br_cnab_mov_intruction_code.py +++ b/l10n_br_account_payment_order/models/l10n_br_cnab_mov_intruction_code.py @@ -2,7 +2,8 @@ # @author Magno Costa # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError class L10nBrCNABMovInstructionCode(models.Model): @@ -57,3 +58,12 @@ def _compute_payment_method_id(self): record.payment_method_id = ( record.payment_method_ids and record.payment_method_ids[0] or False ) + + @api.constrains("code") + def check_code(self): + for record in self: + # Tamanho do campo é padrão 2 p/ todos + # os codigos de Instrução CNAB ? + if len(record.code) != 2: + raise ValidationError(_("The field Code should have two characters.")) + return super().check_code() diff --git a/l10n_br_account_payment_order/models/l10n_br_cnab_return_move_code.py b/l10n_br_account_payment_order/models/l10n_br_cnab_return_move_code.py index 759174668fe0..81ae5aca491f 100644 --- a/l10n_br_account_payment_order/models/l10n_br_cnab_return_move_code.py +++ b/l10n_br_account_payment_order/models/l10n_br_cnab_return_move_code.py @@ -2,7 +2,8 @@ # @author Magno Costa # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError class L10nBrCNABReturnMoveCode(models.Model): @@ -28,6 +29,8 @@ class L10nBrCNABReturnMoveCode(models.Model): tracking=True, ) + comment = fields.Text() + # TODO: Forma encontrada para pode fazer o Group By, na v15 # parece já ser possivel usar campos many2many. # Também deve ser considerado apagar o campo many2many e deixar @@ -55,3 +58,12 @@ def _compute_payment_method_id(self): record.payment_method_id = ( record.payment_method_ids and record.payment_method_ids[0] or False ) + + @api.constrains("code") + def check_code(self): + for record in self: + # Tamanho do campo é padrão 2 p/ todos + # do os codigos de Retorno CNAB ? + if len(record.code) != 2: + raise ValidationError(_("The field Code should have two characters.")) + return super().check_code() diff --git a/l10n_br_account_payment_order/security/ir.model.access.csv b/l10n_br_account_payment_order/security/ir.model.access.csv index 13a76609da86..134583be1d17 100644 --- a/l10n_br_account_payment_order/security/ir.model.access.csv +++ b/l10n_br_account_payment_order/security/ir.model.access.csv @@ -16,3 +16,5 @@ access_l10n_br_cnab_boleto_fields_manager,l10n_br_cnab.boleto.fields manager,mod access_l10n_br_cnab_payment_fields_uinvoice,l10n_br_cnab.payment.fields invoice,model_l10n_br_cnab_payment_fields,account.group_account_invoice,1,1,1,1 access_l10n_br_cnab_payment_fields_manager,l10n_br_cnab.payment.fields manager,model_l10n_br_cnab_payment_fields,account.group_account_manager,1,0,0,0 access_account_move_line_cnab_change_user,access_account_move_line_cnab_change_user,model_account_move_line_cnab_change,group_cnab_user,1,1,1,1 +access_l10n_br_cnab_boleto_wallet_code_manager,access_l10n_br_cnab_boleto_wallet_code manager,model_l10n_br_cnab_boleto_wallet_code,group_cnab_manager,1,1,1,1 +access_l10n_br_cnab_boleto_wallet_code_user,access_l10n_br_cnab_boleto_wallet_code user,model_l10n_br_cnab_boleto_wallet_code,group_cnab_user,1,0,0,0 diff --git a/l10n_br_account_payment_order/tests/__init__.py b/l10n_br_account_payment_order/tests/__init__.py index e8fbe02888b7..e01a3af668d3 100644 --- a/l10n_br_account_payment_order/tests/__init__.py +++ b/l10n_br_account_payment_order/tests/__init__.py @@ -6,3 +6,4 @@ from . import test_invoice_manual_workflow from . import test_payment_mode from . import test_payment_order_outbound_pix +from . import test_cnab_codes diff --git a/l10n_br_account_payment_order/tests/test_cnab_codes.py b/l10n_br_account_payment_order/tests/test_cnab_codes.py new file mode 100644 index 000000000000..9ac53583822e --- /dev/null +++ b/l10n_br_account_payment_order/tests/test_cnab_codes.py @@ -0,0 +1,127 @@ +# Copyright (C) 2024-Today - Akretion (). +# @author Magno Costa +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.exceptions import ValidationError +from odoo.tests import Form, SavepointCase, tagged + + +@tagged("post_install", "-at_install") +class TestPaymentOrder(SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.instruction_unicred_01 = cls.env.ref( + "l10n_br_account_payment_order.unicred_240_400_instruction_01" + ) + + def test_cnab_code_abstract(self): + """Test CNAB Code Abstract Model""" + # Testa o name_get do objeto + self.instruction_unicred_01.name_get() + + def test_cnab_instruction_move_code(self): + """Test CNAB Instruction Move Code""" + instruction_code_form = Form(self.instruction_unicred_01) + + # Testa os campos compute + # TODO: Ver a questão do Group By a aprtir da v15 ou v16 + instruction_code_form.bank_ids.add(self.env.ref("l10n_br_base.res_bank_237")) + instruction_code_form.payment_method_ids.add( + self.env.ref("l10n_br_account_payment_order.payment_mode_type_cnab500") + ) + instruction_code_form.save() + + # Testa o caso do tamanho do campo 2 + instruction_code_form.code = "123" + with self.assertRaises(ValidationError): + instruction_code_form.save() + + # Testa o caso do Codigo Duplicado + instruction_code_new_form = Form( + self.env["l10n_br_cnab.mov.instruction.code"], + "l10n_br_account_payment_order.l10n_br_cnab_mov_instruction_code_form_view", + ) + + instruction_code_new_form.code = "01" + instruction_code_new_form.name = "Remessa*" + instruction_code_new_form.bank_ids.add( + self.env.ref("l10n_br_base.res_bank_136") + ) + instruction_code_new_form.payment_method_ids.add( + self.env.ref("l10n_br_account_payment_order.payment_mode_type_cnab400") + ) + with self.assertRaises(ValidationError): + instruction_code_new_form.save() + + def test_cnab_return_move_code(self): + """Test CNAB Return Move Code""" + # Caso campo deve ter o tamanho 2 + return_unicred_01 = self.env.ref( + "l10n_br_account_payment_order.unicred_240_400_return_01" + ) + return_code_form = Form(return_unicred_01) + + # Testa o caso dos campos compute + # TODO: Ver a questão do Group By a partir da v15 ou v16 + return_code_form.bank_ids.add(self.env.ref("l10n_br_base.res_bank_237")) + return_code_form.payment_method_ids.add( + self.env.ref("l10n_br_account_payment_order.payment_mode_type_cnab500") + ) + return_code_form.save() + + # Testa caso do tamanho ser 2 + return_code_form.code = "123" + with self.assertRaises(ValidationError): + return_code_form.save() + + # Caso Codigo Duplicado + return_move_code_new_form = Form( + self.env["l10n_br_cnab.return.move.code"], + "l10n_br_account_payment_order.l10n_br_cnab_return_move_code_form_view", + ) + + return_move_code_new_form.code = "01" + return_move_code_new_form.name = "Pago (Título protestado pago em cartório)" + return_move_code_new_form.bank_ids.add( + self.env.ref("l10n_br_base.res_bank_136") + ) + return_move_code_new_form.payment_method_ids.add( + self.env.ref("l10n_br_account_payment_order.payment_mode_type_cnab400") + ) + with self.assertRaises(ValidationError): + return_move_code_new_form.save() + + def test_cnab_boleto_wallet_code(self): + """Test CNAB Boleto Wallet Code""" + boleto_wallet_code_1 = self.env.ref( + "l10n_br_account_payment_order.santander_240_boleto_wallet_code_1" + ) + boleto_wallet_code_form = Form(boleto_wallet_code_1) + + # Testa o caso dos campos compute + # TODO: Ver a questão do Group By a partir da v15 ou v16 + boleto_wallet_code_form.bank_ids.add(self.env.ref("l10n_br_base.res_bank_136")) + boleto_wallet_code_form.payment_method_ids.add( + self.env.ref("l10n_br_account_payment_order.payment_mode_type_cnab500") + ) + boleto_wallet_code_form.save() + + # Caso Codigo Duplicado + boleto_wallet_code_new_form = Form( + self.env["l10n_br_cnab.boleto.wallet.code"], + "l10n_br_account_payment_order.l10n_br_cnab_boleto_wallet_code_form_view", + ) + + boleto_wallet_code_new_form.code = "1" + boleto_wallet_code_new_form.name = ( + "Cobrança Simples (Sem Registro e Eletrônica com Registro)" + ) + boleto_wallet_code_new_form.bank_ids.add( + self.env.ref("l10n_br_base.res_bank_033") + ) + boleto_wallet_code_new_form.payment_method_ids.add( + self.env.ref("l10n_br_account_payment_order.payment_mode_type_cnab400") + ) + with self.assertRaises(ValidationError): + boleto_wallet_code_new_form.save() diff --git a/l10n_br_account_payment_order/views/account_payment_mode.xml b/l10n_br_account_payment_order/views/account_payment_mode.xml index 37da9a2c1ed1..14721dc2a8ef 100644 --- a/l10n_br_account_payment_order/views/account_payment_mode.xml +++ b/l10n_br_account_payment_order/views/account_payment_mode.xml @@ -31,8 +31,39 @@ - - + + + + + + + + + + @@ -52,10 +83,8 @@ attrs="{'required': [('payment_method_code', 'in', ('240', '400', '500')), ('payment_type', '==', 'inbound')]}" /> - - @@ -82,10 +111,48 @@ - - + + + + + + + + + + + + + + + + + + l10n_br_cnab.boleto.wallet.code.tree + l10n_br_cnab.boleto.wallet.code + + + + + + + + + + + + l10n_br_cnab.boleto.wallet.code.search + l10n_br_cnab.boleto.wallet.code + + + + + + + + + + + + + + + + + + + l10n_br_cnab.boleto.wallet.code.form.view + l10n_br_cnab.boleto.wallet.code + +
+ + + + + + + + + +
+ +
+
+
+
+ + + CNAB Boleto Wallet Code + l10n_br_cnab.boleto.wallet.code + tree,form + {'group_by':['bank_id', 'payment_method_id']} + + + + +