Registrando contablemente los descuentos

1 de agosto de 2023 por
Gustavo Orrillo
| Sin comentarios aún
 

Odoo no registra los descuentos otorgados u obtenidos (tampoco lo hace a nivel pedido de ventas, lo cual para pricing analytics es una catástrofe). Que es lo que hace Odoo? cuando en una factura (ya sea de compras o de ventas) uno ingresa el descuento, Odoo registra la operación con el descuento otorgado u obtenido. El único rastro que existe del descuento otorgado es la columna discount en el campo invoice_line_ids del modelo account.move (lo cual hace que su análisis sea catastrófico). Ahora, hay veces (muchas veces por normativas contables locales) que nos piden que Odoo automaticamente registre en la contabilidad el descuento. Entonces supongamos a modo de ejemplo; 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:


Como pueden ver, se debita la cuenta contable Ventas (indicando que se vendió por un monto menor al de la factura) y se acredita la cuenta de descuentos otorgados que es una cuenta de pérdidas (todo descuento otorgado es una pérdida de ingresos, por eso una de las primeras medidas para mejorar la rentabilidad de un negocio es revisar su política de descuentos).

Para resolver este problema, desarrollamos el modulo account_discount el cual resuelve este problema para facturas de clientes y proveedores. Como la mayoría de los módulos, su instalación es bastante sencillo, no requiere dependencias, se instala como cualquier otro módulo y solo requiere que esté configurada la contabilidad. Solo se debe configurar en el diario de ventas el diario en el cual se registrará el movimiento de descuentos y la cuenta de pérdidas.


Y cuando se confirma la factura del cliente, si la misma tiene descuentos se genera un movimiento contable con el descuento.





La misma lógica que estamos observando en las facturas de ventas 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. Y se podría agregar el producto que originó el descuento, lo cual podría ayudar a analizar las perdidas sufridas (debido a la política de descuentos) por producto.

Anexo técnico

El módulo account_discount, despues de validar 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. Además 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 que deben tener en cuenta (y siempre se olvida), deben setear 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.



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


Otro punto más... las operaciones sobre los recordsets. En este caso usamos el método filtered para filtrar las líneas con descuento:

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

Esta línea devuelve un recordset con las líneas que cumplen la condición (en este caso que la línea de la factura tenga un descuento aplicado).

Con respecto a la vista de la factura, usamos 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.

Gustavo Orrillo 1 de agosto de 2023
Compartir
Archivar
Identificarse dejar un comentario