Fraccionando pagos (o cheques) en Odoo

Gustavo Orrillo
- 13/04/2021 - 2 min. de lectura

Para que fraccionar pagos en Odoo? Es sencillo, muchas veces nos pagan con un cheque... y necesitamos hacer que un monto determinado de un cheque pague la factura X y otro monto determinado pague la factura Y. Odoo naturalmente no lo soporta (porque es algo muy argentino, va contra el sentido comun del resto del planeta) y por esto tuvimos que hacer el módulo payment_split.

Lo que hace el módulo es en cada pago (no confundir con recibo, y aclaremos que un pago es un cheque) agrega un boton de "Fraccionar pago"


Al clickearse el boton, se mostrará un wizard que permite fraccionar el pago en múltiples pagos. 


Este fraccionamiento permitirá asignar montos arbitrarios del pago a cada factura

Anexo técnico

Lo primero que se ve es en el modelo de cheques (account.check) un botón que llama un wizard. Para ello se necesita retornar una acción desde un método, para ello se debe hacer lo siguiente:

wizard_id = self.env['payment.split.wizard'].create({'payment_id': self.id})
return {
    'name': _('Fraccionar pago'),
    'res_model': 'payment.split.wizard',
    'res_id': wizard_id.id,
    'view_mode': 'form',
    'type': 'ir.actions.act_window',
    'target': 'new',
}

Primero se crea un objeto del wizard (que es un modelo transitorio), y luego se retorna un diccionario con la información de la acción. Esto permite crear la ventana del wizard, que es donde ocurre toda la acción. 

Como se particiona un pago? Primero veamos como es el asiento contable de un cheque de $100 (el cual queremos fraccionar en dos pagos de $50);

CuentaDébitoCrédito
Valores a depositar (1)100
Deudores por venta (2)
100

Para fraccionar el pago, lo que se debe hacer es crear otro asiento en el que haya un apunte (apunte 3) que concilie la línea cobrable/pagable del asiento del cheque (apunte 2); y tantas líneas cobrables/pagables que se van a usar para conciliar la factura (apuntes 4 y 5)

CuentaDébitoCrédito
Deudores por Venta (3)100
Deudores por Venta (4)
50
Deudores por Venta (5)
50

Esto ocurre en el botón de confirmación del wizard.  En las siguientes líneas se puede ver como se crea un asiento contable con los apuntes como fueron detallados anteriormente;

vals_move = {
    'journal_id': self.journal_id.id,
    'type': 'entry',
    'ref': 'SPLIT ' + str(self.payment_id.display_name),
    }
move_id = self.env['account.move'].with_context(check_move_validity=False).create(vals_move)
vals_debit = {
    'split_payment_id': self.payment_id.id,
    'move_id': move_id.id,
    'debit': total_amount,
    'partner_id': self.payment_id.partner_id.id,
    'account_id': payment_move_line[0].account_id.id,
    'name': 'Particion pago DR %s'%(self.payment_id.display_name),
    }
debit_id = self.env['account.move.line'].with_context(check_move_validity=False).create(vals_debit)
for line_amount in self.line_ids:
    vals_credit = {
        'split_payment_id': self.payment_id.id,
        'move_id': move_id.id,
        'credit': line_amount.amount,
        'partner_id': self.payment_id.partner_id.id,
        'account_id': payment_move_line[0].account_id.id,
        'name': 'Particion pago CR %s'%(self.payment_id.display_name),
        }
    credit_id = self.env['account.move.line'].with_context(check_move_validity=False).create(vals_credit)
move_id.post()

Lo primero que se puede ver es que este código no funciona en Odoo 15 en adelante, ya que el campo type en el modelo account.move fue reemplazado por el campo move_type. Noten también el contexto check_move_validity seteado a False, así podemos crear asientos no balanceados.

El último paso es conciliar el apunte contable del cheque con el apunte contable del asiento que acabamos de crear. Para ello se debe primero determinar el apunte contable conciliable del cheque. Eso se hace encontrando la cuenta contable conciliable del cheque y agregandola a un recordset vacío del modelo account.move.line;

payment_move_line = self.env['account.move.line']
for move_line in self.payment_id.move_line_ids:
    if move_line.account_id.reconcile:
        payment_move_line += move_line 

Luego se debe conciliar dicha línea con el apunte contable (del asiento creado) que debita el total del monto del cheque (en el ejemplo el apunte contable 3)

payment_move_line += debit_id
payment_move_line.reconcile() 

Posteriormente en las facturas del cliente se podrán observar los apuntes del pago fraccionado. El mismo método se lo puede utilizar tambien para transferencias bancarias o pagos en efectivo, pero es común que ocurra con cheques. 

Acerca de:

Gustavo Orrillo

Passionate about programming, he has implemented Odoo for different types of businesses since 2010. In Moldeo Interactive he is a founding Partner and Programmer; In addition to writing on the Blog about different topics related to the developments he makes.