Valuando movimientos de stock

20 de julio de 2023 por
Gustavo Orrillo
| Sin comentarios aún
 

Antes que nada quiero aclarar que este enfoque solo sirve para los productos que tienen tracking, ya sea por número de serie o lotes. La idea es valuar los ingresos de stock, porque así lo necesita el usuario. Y la realidad es que los movimientos de stock se pueden valuar siempre y cuando el producto que ingresa tiene un costo (por lo general en USD) o tiene relacionada una orden de compra (como ilustra este post). Este post les va a dar una idea de la potencia de Odoo para ser extendido, y como hacerlo. En este caso vamos a agregar el costo de la mercadería ingresada una vez que el usuario confirma la recepción de mercadería.

Primero hay que extender la clase stock.move.line y agregar un campo llamado stock_valuation. 


class StockMoveLine(models.Model):
​_inherit = 'stock.move.line'

​stock_valuation = fields.Float('Valor Stock')

class StockPicking(models.Model):
_inherit = 'stock.picking'

def button_validate(self):
​ # ejecuta la transferencia misma
res = super(StockPicking, self).button_validate()
for rec in self:
​ # para cada picking que sea un ingreso de mercaderia
​ # y ademas tenga informacion del documento de origen
if rec.origin and rec.picking_type_code == 'incoming':
​ # busca orden de compra
purchase_order = self.env['purchase.order'].search([('name','=',rec.origin)])
if purchase_order:
​# para cada linea de la transferencia que recibio mercaderia​
for move_id in rec.move_ids_without_package.filtered(lambda l: l.quantity_done != 0):
​# lee la informacion de la linea de la orden de compra
​ purchase_line = move_id.purchase_line_id
for move_line in move_id.move_line_ids:
​if move_line.product_uom_id.id == purchase_line.product_uom.id:
​ ​
# si la unidad de medida de la transferencia es la misma
​ # a la unidad de medida de la PO
move_line.stock_valuation = purchase_line.price_unit * move_line.qty_done
else:
​ # convierte el precio unitario y la cantidad ordenada
​ # a la unidad de medida de la transferencia
qty_ordered = purchase_line.product_uom._compute_quantity(purchase_line.product_qty,move_line.product_uom_id)
price_unit = purchase_line.price_subtotal / qty_ordered
amount = price_unit * move_line.qty_done
move_line.stock_valuation = amount
return res


Luego se valua el stock cuando se confirma la transferencia. Para eso extendemos el método button_validate. Sigue el patrón clásico de extensión de un método en Odoo (que lo podemos observar por ejemplo, cuando validamos una factura con la factura electrónica)

def button_validate(self):
​res = super(MyObject, self).button_validate()
​# my code
​return res

Y cuando lo extendemos, le agregamos la funcionalidad que necesitamos. En este caso para los movimientos de ingreso de mercadería, buscamos si tiene una orden de compra relacionada (lo hacemos ya que un ingreso de mercadería puede ser una devolución de clientes, por ejemplo). Y acto seguido para cada producto recibido, procedemos a calcular su valor (tomando en cuenta las unidades de medida de los mismos, ya que estas pueden variar entre las transferencias y órdenes de compra)

Es un ejemplo sencillo, pero muestra como se puede extender Odoo. Tambien es util debido a que no es buena idea valuar los stocks en ARS sino hacerlo en USD, y en este ejemplo lo estamos haciendo. Odoo puede valuar el stock, pero lo hace en moneda local (lo cual no es una buena idea). 

Por último no estamos actualizando el stock, sino valuando los ingresos. Igualmente no es dificil extender este concepto para la valuación de los inventarios (con el modelo stock.quant). En este caso estaríamos actualizando el stock con el costo de reposición.


Gustavo Orrillo 20 de julio de 2023
Compartir
Archivar
Identificarse dejar un comentario