Skip to content

Commit

Permalink
[REF] Treatment of payment outside CNAB centralized in method reconci…
Browse files Browse the repository at this point in the history
…le at account.move.line .
  • Loading branch information
mbcosta committed Apr 8, 2021
1 parent 41d62eb commit 753557a
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 105 deletions.
93 changes: 0 additions & 93 deletions l10n_br_account_payment_order/models/account_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,59 +146,6 @@ def action_move_create(self):
self._pos_action_move_create()
return result

@api.multi
def create_payment_outside_cnab(self, amount_payment):
"""
Em caso de CNAB é preciso verificar e criar linha(s)
com Codigo de Instrução do Movimento de Baixa
ou de Alteração de Valor do Título quando existir.
:param amount_payment: Valor Pago
:return:
"""

# Identificar a Linha CNAB que vai ser dado Baixa ou
# terá o Valor do Titulo alterado devido a um pagamento parcial
applicable_lines = change_tittle_value_line = \
self.env['account.move.line']

lines_to_check = self.move_id.line_ids.filtered(
lambda x: x.debit > 0.0 and x.payment_situation in
('inicial', 'aberta')
)

# Valor Total, baixar todas as Parcelas em Aberto
if self.amount_total == amount_payment:
applicable_lines |= lines_to_check
else:
# Verificar se é o pagto de mais de uma parcela
# OBS.: A sequencia/order da alocação de valores e baixas/alteração
# de valor segue as Datas de Vencimento, porque não pode ser pago
# fora dessa ordem.
amount_value = 0.0
for line in lines_to_check:
applicable_lines |= line
amount_value += line.debit
if amount_value == amount_payment:
# Valor Pago corresponde as linhas já percorridas
break
if amount_value > amount_payment:
# Valor Pago ficou menor que as linhas de debito essa linha
# foi paga parcialmente e essa Parcela deverá ter seu valor
# alterado
change_tittle_value_line = line
break

reason_write_off = (
('Movement Instruction Code Updated for Request'
' to Write Off, because payment of %s done outside CNAB.')
% amount_payment)
payment_situation = 'baixa_liquidacao'
for line in applicable_lines:
if line == change_tittle_value_line:
line.create_cnab_change_tittle_value()
else:
line.create_cnab_write_off(reason_write_off, payment_situation)

@api.multi
def invoice_validate(self):
result = super().invoice_validate()
Expand All @@ -209,43 +156,3 @@ def invoice_validate(self):
if filtered_invoice_id.payment_mode_id.payment_order_ok:
filtered_invoice_id.create_account_payment_line()
return result

@api.multi
def assign_outstanding_credit(self, credit_aml_id):
self.ensure_one()
# TODO - Existe necessidade de ser feito algo nesse metodo ?
# O Metodo parece ser chamado apenas no modulo sale
# https://github.com/OCA/OCB/blob/12.0/addons/sale/
# models/account_invoice.py#L68
# if self.eval_situacao_pagamento in ['paga', 'liquidada',
# 'baixa_liquidacao']:
# raise UserError(
# _(
# 'Não é possível adicionar pagamentos em uma fatura que '
# 'já está paga.'
# )
# )
# if self.eval_state_cnab in ['accepted', 'exported', 'done']:
# raise UserError(
# _(
# 'Não é possível adicionar pagamentos em uma fatura já '
# 'exportada ou aceita no banco.'
# )
# )
return super().assign_outstanding_credit(credit_aml_id)

@api.multi
def register_payment(
self, payment_line, writeoff_acc_id=False, writeoff_journal_id=False
):
res = super().register_payment(
payment_line, writeoff_acc_id, writeoff_journal_id)

self._pos_action_move_create()

for inv in self:
inv._compute_financial()
receivable_id = inv.financial_move_line_ids
receivable_id.residual = inv.residual

return res
35 changes: 35 additions & 0 deletions l10n_br_account_payment_order/models/account_move_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,38 @@ def _compute_journal_payment_mode(self):
if record.payment_mode_id.fixed_journal_id:
record.journal_payment_mode_id =\
record.payment_mode_id.fixed_journal_id.id

@api.multi
def reconcile(self, writeoff_acc_id=False, writeoff_journal_id=False):

res = super().reconcile(writeoff_acc_id, writeoff_journal_id)
for record in self:
# Verificar Casos de CNAB
if (record.payment_mode_id.payment_method_code in
('240', '400', '500') and
record.payment_mode_id.payment_method_id.payment_type ==
'inbound'):
# Na importação do arquivo de retorno o metodo também é
# chamado no caso do modulo l10n_br_account_payment_brcobranca
# o contexto traz o campo 'file_name' que ao ser encontrado
# ignora o envio de alterações CNAB, outros modulos precisam
# validar isso
# Caso de Não Pagamento já está criando um Pedido de Baixa
if self.env.context.get('file_name') or\
self.env.context.get('not_payment'):
continue
if record.matched_credit_ids:
for l in record.matched_credit_ids:
if not l.already_send_cnab:
record.create_payment_outside_cnab(l.amount)
l.already_send_cnab = True

return res


class AccountPartialReconcile(models.Model):
_inherit = 'account.partial.reconcile'

# Evita que uma conciliação parcial seja
# considerada novamente em um pagamento
already_send_cnab = fields.Boolean(string='Already send CNAB')
14 changes: 3 additions & 11 deletions l10n_br_account_payment_order/models/account_payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ class AccountPayment(models.Model):
def post(self):

for record in self:
if record.payment_method_code in ('240', '400', '500'):
if record.payment_method_code in ('240', '400', '500') and\
record.payment_mode_id.payment_method_id.payment_type\
== 'inbound':
# TODO - Idealmente isso deveria ser resolvido com um
# domain=[('code', 'not in', ('400','240','500'))]
# no campo payment_method_id, mas mesmo adicionando isso na
Expand All @@ -31,13 +33,3 @@ def post(self):
' choose another one.'))

super().post()
for invoice in record.invoice_ids:
# Se é CNAB do tipo Recebiveis deve ser feita a validação
# se é possível e se necessário informar o Banco a respeito
# de Baixa ou Alteração do Valor no caso do Pagamento for
# Parcial e permitir esse tipo de instrução.
if (invoice.payment_mode_id.payment_method_code in
('240', '400', '500') and
invoice.payment_mode_id.payment_method_id.payment_type
== 'inbound'):
invoice.create_payment_outside_cnab(record.amount)
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ def _create_cnab_not_payment(self, payorder, new_payorder, reason):

move_line_to_reconcile = moves.filtered(
lambda m: m.credit > 0.0)
(self + move_line_to_reconcile).reconcile()
(self + move_line_to_reconcile).with_context(
not_payment=True).reconcile()

self.create_payment_line_from_move_line(payorder)
# Proceso CNAB encerrado
Expand Down Expand Up @@ -475,3 +476,16 @@ def _create_baixa(self, reason, **kwargs):
'last_change_reason': reason,
'payment_situation': 'baixa', # FIXME: Podem ser múltiplos motivos
})

def create_payment_outside_cnab(self, amount_payment):

if self.amount_residual == 0.0:
reason_write_off = (
('Movement Instruction Code Updated for'
' Request to Write Off, because payment'
' of %s done outside CNAB.') % amount_payment)
payment_situation = 'baixa_liquidacao'
self.create_cnab_write_off(
reason_write_off, payment_situation)
else:
self.create_cnab_change_tittle_value()
39 changes: 39 additions & 0 deletions l10n_br_account_payment_order/tests/test_payment_order_inbound.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,42 @@ def test_cancel_invoice_payment_order_draft(self):
self.assertEquals(len(payment_order.payment_line_ids), 0)
# Nesse caso a account.move deverá ter sido apagada
self.assertEquals(len(self.invoice_unicred.move_id), 0)

def test_payment_by_assign_outstanding_credit(self):
"""
Caso de Pagamento com CNAB usando o assign_outstanding_credit
"""
self.partner_akretion = self.env.ref(
'l10n_br_base.res_partner_akretion'
)
# I validate invoice by creating on
self.invoice_cef.action_invoice_open()

payment_order = self.env['account.payment.order'].search([
('payment_mode_id', '=', self.invoice_cef.payment_mode_id.id)
])
# Open payment order
payment_order.draft2open()
# Generate and upload
# payment_order.open2generated()
# payment_order.generated2uploaded()
# self.assertEquals(payment_order.state, 'done')

payment = self.env['account.payment'].create({
'payment_type': 'inbound',
'payment_method_id': self.env.ref(
'account.account_payment_method_manual_in').id,
'partner_type': 'customer',
'partner_id': self.partner_akretion.id,
'amount': 100,
'journal_id': self.journal_cash.id,
})
payment.post()
credit_aml = payment.move_line_ids.filtered('credit')

# Erro de ter uma Instrução CNAB Pendente, como não é possivel gerar a
# Ordem de Pagto o teste completo de pagamento via
# assign_outstanding_credit precisa ser feito no modulo que
# implementa biblioteca a ser usada.
with self.assertRaises(UserError):
self.invoice_cef.assign_outstanding_credit(credit_aml.id)

0 comments on commit 753557a

Please sign in to comment.