Skip to main content

Overview

The Inventory module manages materials, spare parts, and consumables across multiple warehouse locations with complete traceability of stock movements.

Key Features

Multi-Warehouse

Manage stock across multiple physical locations

Material Catalog

Comprehensive material master data

Stock Tracking

Real-time stock levels and movements

Shopping Cart

Material request workflow for technicians

Data Model

Material

inventarios/models.py
class Material(models.Model):
    codigo = models.CharField(max_length=50, unique=True)
    nombre = models.CharField(max_length=255)
    descripcion = models.TextField()
    
    categoria = models.ForeignKey('CategoriaMaterial', on_delete=models.SET_NULL)
    unidad_medida = models.CharField(max_length=20)
    
    precio_estimado = models.DecimalField(max_digits=10, decimal_places=2)
    foto = models.ImageField(upload_to='materiales/', blank=True)

StockRecord

inventarios/models.py
class StockRecord(models.Model):
    material = models.ForeignKey('Material', on_delete=models.CASCADE)
    ubicacion = models.ForeignKey('activos.Ubicacion', on_delete=models.CASCADE)
    
    cantidad = models.DecimalField(max_digits=10, decimal_places=2)
    cantidad_reservada = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    
    @property
    def cantidad_disponible(self):
        return self.cantidad - self.cantidad_reservada

MovimientoInventario

inventarios/models.py
class MovimientoInventario(models.Model):
    TIPOS = [
        ('ENTRADA', 'Entrada'),
        ('SALIDA', 'Salida'),
        ('TRANSFERENCIA', 'Transferencia'),
        ('AJUSTE', 'Ajuste'),
    ]
    
    tipo = models.CharField(max_length=20, choices=TIPOS)
    material = models.ForeignKey('Material', on_delete=models.PROTECT)
    cantidad = models.DecimalField(max_digits=10, decimal_places=2)
    
    ubicacion_origen = models.ForeignKey('activos.Ubicacion', 
                                        on_delete=models.PROTECT,
                                        related_name='movimientos_salida')
    ubicacion_destino = models.ForeignKey('activos.Ubicacion',
                                         on_delete=models.PROTECT,
                                         related_name='movimientos_entrada')
    
    fecha = models.DateTimeField(auto_now_add=True)
    usuario = models.ForeignKey(User, on_delete=models.SET_NULL)
    referencia = models.CharField(max_length=100)  # Work order, etc.

Stock Operations

Material Request

Technicians request materials via shopping cart:
inventarios/views.py
def agregar_carrito(request):
    material_id = request.POST.get('material_id')
    cantidad = Decimal(request.POST.get('cantidad'))
    
    # Get or create cart
    cart_key = f'cart_{request.user.id}'
    cart = cache.get(cart_key, [])
    
    # Add item
    cart.append({
        'material_id': material_id,
        'cantidad': cantidad
    })
    
    cache.set(cart_key, cart, timeout=3600)
    
    return JsonResponse({'status': 'ok'})

Checkout Process

1

Select Materials

Add materials to shopping cart
2

Validate Stock

System checks availability
3

Create Request

SolicitudMaterial record created
4

Approval

Warehouse manager approves
5

Dispatch

Stock movement recorded

API Endpoints

Material Search

Search materials with pagination and filtering

Stock Management

Query and update stock levels

Maintenance

Consume materials on work orders

Assets

Link materials to equipment

Budgets

Track material costs

Build docs developers (and LLMs) love