Registrando contablemente los descuentos

Gustavo Orrillo
- 05/28/2022 - 2 min. de lectura

Odoo no registra los descuentos otorgados u obtenidos. Cuando en una factura uno ingresa el descuento, registra la operación con el descuento otorgado u obtenido. El único rastro que existe es la columna discount en el campo invoice_line_ids del modelo account.move. Ahora, hay veces que nos piden que Odoo automaticamente registre en la contabilidad el descuento. Supongamos; para una factura de ventas por un total de $90 que tuvo un descuento de $10, tendríamos el siguiente asiento para registrar el descuento:


CuentaDébitoCrédito
Ventas10
Descuentos otorgados
10

Como verán, se debita el campo de ventas (indicando que se vendió por un monto mayor al de la factura) y se acredita la cuenta de descuentos otorgados que es una cuenta de pérdidas.

Para resolver este problema, creamos el modulo account_discount el cual resuelve este problema para facturas de clientes y proveedores. La instalación es bastante sencillo, se instala como cualquier otro módulo y solo requiere que esté configurada la contabilidad. Solo se necesita configurar en el diario de ventas el diario en el cual se registrará el movimiento de descuentos y la cuenta de pérdidas


Y al momento de validar la factura del cliente, si la misma tiene descuentos se genera un movimiento contable con el descuento.





La misma lógica se aplica para las facturas de proveedor. Tengan en cuenta que los movimientos por los descuentos se los valida automaticamente. Por último, decidimos no incluir este movimiento dentro de la factura debido a que es más prolijo mantener los movimientos separados.

Anexo técnico

Vamos a analizar el módulo account_discount, cual es su diseño y que se puede aprender de el. La idea del mismo es; despues validarse la factura de cliente o proveedor (método action_post del modelo account.move), debemos crear un nuevo asiento. Para ello extendemos el método action_post de la siguiente forma;  

def action_post(self):
    res = super(AccountMove, self).action_post()
    # creamos el asiento
    return res

Esto es una forma bastante común de agregar funcionalidad a Odoo. 

Por otra parte se agrega un mensaje interno (con traducción) al momento de crearse y validarse el asiento

rec.message_post(body=_(('Discount move %s created and validated')%(move_id.name)))

Lo que postea en el chatter de la factura el mensaje de creación del asiento de descuento


El mensaje se va a traducir a medida que se agreguen traducciones al módulo.

Algo para siempre tener en cuenta, el contexto check_move_validity en False. Dicho contexto es necesario para crear apuntes contables de a uno, sino Odoo va a dar un error indicando que el asiento contable se encuentra desbalanceado.

debit_id = self.env['account.move.line'].with_context({'check_move_validity': False}).create(vals_debit)

Operaciones sobre los recordsets; algo que no estoy muy acostumbrado a usar, pero que tengo que hacer más seguido. En este caso el método filtered:

discount_lines = rec.invoice_line_ids.filtered(lambda l: l.discount)

Devuelve un recordset con las líneas que cumplen la condición (en este caso un valor mayor a 0 para el campo discount).

Por último, con respecto a la vista, utilizo xpath para agregar al final una página del notebook los campos a las vistas de account.move y account.journal. Afortunadamente dichas páginas tienen un nombre y un id, lo que resulta facil de localizar con xpath

<xpath expr="//page[@id='other_tab']" position="inside">
Esto agrega los contenidos que necesitamos dentro de la página seleccionada.
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.