Ingreso ágil de recepciones - módulo easy_incoming_stock

Gustavo Orrillo
- 08/10/2022 - 2 min. de lectura

El ingreso de recepciones en Odoo no es ágil para los usuarios. Hace lo que tiene que hacer, que es controlar los ingresos, asegurarse que los usuarios no ingresan datos erroneos... pero no es precisamente ágil cuando uno debe ingresar lotes o números de serie. Muchas veces los usuarios se encuentran con la necesidad de crear decenas o cientos números de serie en un ingreso, y hacerlo mediante el form que provee Odoo out-of-the-box no es una buena opción. Honestamente pienso que la verdadera solución es procesar los ingresos mediante un lector de código de barras, pero por diferentes motivos los usuarios no lo aceptan. Es por eso que desarrollamos el módulo easy_incoming_stock para agilizar los ingresos.

El módulo se instala como cualquier otro módulo. Y crea en el ingreso un tab llamado Líneas


En el tab Líneas debemos ingresar las líneas con los números de serie a ingresar. Se lo debe hacer con el formato "código de producto, número de serie". De la misma manera que se ingresa un archivo de texto. Por ejemplo;


Al clickear el botón "Crear líneas" se crean los números de serie ingresados para los productos correspondientes. Y se actualiza el movimiento de stock del tab Operaciones


Seguidamente el usuario puede clickear "Validar" y el sistema procederá a crear una entrega parcial o no (si amerita la situación) y valida la transferencia



Y si se chequean los números de serie, verán como los mismos están creados con la información de trazabilidad respectiva.


Notas técnicas

La vista tiene un detalle interesante; crea un botón y un tab con un campo dentro. Esto se lo hace por medio del xpath. Xpath es una herramienta que merece un post aparte:

<xpath expr="//header" position="inside">     
    <button name="btn_create_move_lines" 
            type="object"
             string="Crear lineas"
             attrs="{'invisible': ['|',('picking_type_code','!=','incoming'),('state','not in',['draft','assigned'])]}" />     
</xpath> 
    <xpath expr="//notebook" position="inside"> 
        <page string="Lineas"> 
            <group> 
                <field name="lines_text" states="draft,assigned" /> 
            </group> 
        </page> 
</xpath>

En el modelo stock.picking se define un método (btn_create_move_lines) que procesa los contenidos del campo lines_text. Su contenido se procesa como si fuese un archivo de texto:

lines_text = self.lines_text
lines = lines_text.split('\n')
for line in lines:
    items = line.split(',')

Luego se controla que el producto exista en el catálogo de productos y en los movimientos de stock. Si el número de serie no existe, procedemos a crearlo.

vals_lot = {
    'product_id': product_id.id,
    'name': serial_number,
    'ref': serial_number,
    }
lot_id = self.env['stock.production.lot'].create(vals_lot)

Por último, creamos el movimiento de producto y lo asociamos al movimiento de stock del producto en la presente transferencia:

move_id = self.env['stock.move'].search([('picking_id','=',self.id),('product_id','=',product_id.id)])
if not move_id:
    raise ValidationError('Esta transferencia no va a procesar el producto %s'%(default_code))
vals = {
    'move_id': move_id.id,
    'product_id': product_id.id,
    'product_uom_id': product_id.uom_id.id,
    'lot_id': lot_id.id,
    'location_id': move_id.location_id.id,
    'location_dest_id': move_id.location_dest_id.id,
    'is_inventory': True,
    'picking_id': self.id,
    'state': move_id.state,
    'lot_name': lot_id.ref,
    'origin': self.origin,
    'picking_partner_id': self.partner_id.id,
    'qty_done': 1,
    }
picking_id = self.env['stock.move.line'].create(vals)

Finalmente, quiero aclarar que el valor de la cantidad es 1 debido a que estamos procesando números de serie. Si procesaramos lotes, la lógica sería un poco diferente.


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.