- Add inventory.lots table (coherence with lot.entity.ts) - Add inventory.pickings table with ENUMs (coherence with picking.entity.ts) - Add partners.partner_tax_info table (coherence with partner-tax-info.entity.ts) - Add partners.partner_segments table (coherence with partner-segment.entity.ts) - Rename 21-fiscal-catalogs.sql to 26-fiscal-catalogs.sql (fix duplicate with 21-inventory.sql) - Remove duplicate 25-fiscal-catalogs.sql Gaps resolved: - GAP-P1-001: lots DDL added - GAP-P1-002: pickings DDL added - GAP-P1-006: partner_tax_info DDL added - GAP-P1-007: partner_segments DDL added - GAP-P1-008: DDL numbering fixed Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
429 lines
17 KiB
SQL
429 lines
17 KiB
SQL
-- =============================================================
|
|
-- ARCHIVO: 21-inventory.sql
|
|
-- DESCRIPCION: Niveles de stock y movimientos de inventario
|
|
-- VERSION: 1.0.0
|
|
-- PROYECTO: ERP-Core V2
|
|
-- FECHA: 2026-01-13
|
|
-- DEPENDE DE: 17-products.sql, 18-warehouses.sql
|
|
-- =============================================================
|
|
|
|
-- =====================
|
|
-- SCHEMA: inventory (ya creado en 18-warehouses.sql)
|
|
-- =====================
|
|
|
|
-- =====================
|
|
-- TABLA: stock_levels
|
|
-- Niveles de inventario por producto/almacen/ubicacion
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS inventory.stock_levels (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
product_id UUID NOT NULL REFERENCES products.products(id) ON DELETE CASCADE,
|
|
warehouse_id UUID NOT NULL REFERENCES inventory.warehouses(id) ON DELETE CASCADE,
|
|
location_id UUID REFERENCES inventory.warehouse_locations(id) ON DELETE SET NULL,
|
|
|
|
-- Cantidades
|
|
quantity_on_hand DECIMAL(15, 4) NOT NULL DEFAULT 0, -- Cantidad fisica disponible
|
|
quantity_reserved DECIMAL(15, 4) NOT NULL DEFAULT 0, -- Reservada para ordenes
|
|
quantity_available DECIMAL(15, 4) GENERATED ALWAYS AS (quantity_on_hand - quantity_reserved) STORED,
|
|
quantity_incoming DECIMAL(15, 4) NOT NULL DEFAULT 0, -- En transito/por recibir
|
|
quantity_outgoing DECIMAL(15, 4) NOT NULL DEFAULT 0, -- Por enviar
|
|
|
|
-- Lote y serie
|
|
lot_number VARCHAR(50),
|
|
serial_number VARCHAR(50),
|
|
expiry_date DATE,
|
|
|
|
-- Costo
|
|
unit_cost DECIMAL(15, 4),
|
|
total_cost DECIMAL(15, 4),
|
|
|
|
-- Ultima actividad
|
|
last_movement_at TIMESTAMPTZ,
|
|
last_count_at TIMESTAMPTZ,
|
|
|
|
-- Metadata
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
UNIQUE(product_id, warehouse_id, COALESCE(location_id, '00000000-0000-0000-0000-000000000000'::UUID), COALESCE(lot_number, ''), COALESCE(serial_number, ''))
|
|
);
|
|
|
|
-- Indices para stock_levels
|
|
CREATE INDEX IF NOT EXISTS idx_stock_levels_tenant ON inventory.stock_levels(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_levels_product ON inventory.stock_levels(product_id);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_levels_warehouse ON inventory.stock_levels(warehouse_id);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_levels_location ON inventory.stock_levels(location_id);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_levels_lot ON inventory.stock_levels(lot_number);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_levels_serial ON inventory.stock_levels(serial_number);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_levels_expiry ON inventory.stock_levels(expiry_date) WHERE expiry_date IS NOT NULL;
|
|
CREATE INDEX IF NOT EXISTS idx_stock_levels_low_stock ON inventory.stock_levels(quantity_on_hand) WHERE quantity_on_hand <= 0;
|
|
CREATE INDEX IF NOT EXISTS idx_stock_levels_available ON inventory.stock_levels(quantity_available);
|
|
|
|
-- =====================
|
|
-- TABLA: stock_movements
|
|
-- Movimientos de inventario (entradas, salidas, transferencias, ajustes)
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS inventory.stock_movements (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
|
|
-- Tipo de movimiento
|
|
movement_type VARCHAR(20) NOT NULL, -- receipt, shipment, transfer, adjustment, return, production, consumption
|
|
movement_number VARCHAR(30) NOT NULL, -- Numero secuencial
|
|
|
|
-- Producto
|
|
product_id UUID NOT NULL REFERENCES products.products(id) ON DELETE RESTRICT,
|
|
|
|
-- Origen y destino
|
|
source_warehouse_id UUID REFERENCES inventory.warehouses(id),
|
|
source_location_id UUID REFERENCES inventory.warehouse_locations(id),
|
|
dest_warehouse_id UUID REFERENCES inventory.warehouses(id),
|
|
dest_location_id UUID REFERENCES inventory.warehouse_locations(id),
|
|
|
|
-- Cantidad
|
|
quantity DECIMAL(15, 4) NOT NULL,
|
|
uom VARCHAR(20) DEFAULT 'PZA',
|
|
|
|
-- Lote y serie
|
|
lot_number VARCHAR(50),
|
|
serial_number VARCHAR(50),
|
|
expiry_date DATE,
|
|
|
|
-- Costo
|
|
unit_cost DECIMAL(15, 4),
|
|
total_cost DECIMAL(15, 4),
|
|
|
|
-- Referencia
|
|
reference_type VARCHAR(30), -- sales_order, purchase_order, transfer_order, adjustment, return
|
|
reference_id UUID,
|
|
reference_number VARCHAR(50),
|
|
|
|
-- Razon (para ajustes)
|
|
reason VARCHAR(100),
|
|
notes TEXT,
|
|
|
|
-- Estado
|
|
status VARCHAR(20) NOT NULL DEFAULT 'draft', -- draft, confirmed, cancelled
|
|
confirmed_at TIMESTAMPTZ,
|
|
confirmed_by UUID REFERENCES auth.users(id),
|
|
|
|
-- Metadata
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
-- Indices para stock_movements
|
|
CREATE INDEX IF NOT EXISTS idx_stock_movements_tenant ON inventory.stock_movements(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_movements_type ON inventory.stock_movements(movement_type);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_movements_number ON inventory.stock_movements(movement_number);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_movements_product ON inventory.stock_movements(product_id);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_movements_source ON inventory.stock_movements(source_warehouse_id);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_movements_dest ON inventory.stock_movements(dest_warehouse_id);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_movements_status ON inventory.stock_movements(status);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_movements_reference ON inventory.stock_movements(reference_type, reference_id);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_movements_date ON inventory.stock_movements(created_at);
|
|
CREATE INDEX IF NOT EXISTS idx_stock_movements_lot ON inventory.stock_movements(lot_number) WHERE lot_number IS NOT NULL;
|
|
|
|
-- =====================
|
|
-- TABLA: inventory_counts
|
|
-- Conteos fisicos de inventario
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS inventory.inventory_counts (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
warehouse_id UUID NOT NULL REFERENCES inventory.warehouses(id) ON DELETE CASCADE,
|
|
|
|
-- Identificacion
|
|
count_number VARCHAR(30) NOT NULL,
|
|
name VARCHAR(100),
|
|
|
|
-- Tipo de conteo
|
|
count_type VARCHAR(20) DEFAULT 'full', -- full, partial, cycle, spot
|
|
|
|
-- Fecha programada
|
|
scheduled_date DATE,
|
|
started_at TIMESTAMPTZ,
|
|
completed_at TIMESTAMPTZ,
|
|
|
|
-- Estado
|
|
status VARCHAR(20) NOT NULL DEFAULT 'draft', -- draft, in_progress, completed, cancelled
|
|
|
|
-- Responsable
|
|
assigned_to UUID REFERENCES auth.users(id),
|
|
|
|
-- Notas
|
|
notes TEXT,
|
|
|
|
-- Metadata
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Indices para inventory_counts
|
|
CREATE INDEX IF NOT EXISTS idx_inventory_counts_tenant ON inventory.inventory_counts(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_inventory_counts_warehouse ON inventory.inventory_counts(warehouse_id);
|
|
CREATE INDEX IF NOT EXISTS idx_inventory_counts_status ON inventory.inventory_counts(status);
|
|
CREATE INDEX IF NOT EXISTS idx_inventory_counts_date ON inventory.inventory_counts(scheduled_date);
|
|
|
|
-- =====================
|
|
-- TABLA: inventory_count_lines
|
|
-- Lineas de conteo de inventario
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS inventory.inventory_count_lines (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
count_id UUID NOT NULL REFERENCES inventory.inventory_counts(id) ON DELETE CASCADE,
|
|
product_id UUID NOT NULL REFERENCES products.products(id) ON DELETE RESTRICT,
|
|
location_id UUID REFERENCES inventory.warehouse_locations(id),
|
|
|
|
-- Cantidades
|
|
system_quantity DECIMAL(15, 4), -- Cantidad segun sistema
|
|
counted_quantity DECIMAL(15, 4), -- Cantidad contada
|
|
difference DECIMAL(15, 4) GENERATED ALWAYS AS (COALESCE(counted_quantity, 0) - COALESCE(system_quantity, 0)) STORED,
|
|
|
|
-- Lote y serie
|
|
lot_number VARCHAR(50),
|
|
serial_number VARCHAR(50),
|
|
|
|
-- Estado
|
|
is_counted BOOLEAN DEFAULT FALSE,
|
|
counted_at TIMESTAMPTZ,
|
|
counted_by UUID REFERENCES auth.users(id),
|
|
|
|
-- Notas
|
|
notes TEXT,
|
|
|
|
-- Metadata
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Indices para inventory_count_lines
|
|
CREATE INDEX IF NOT EXISTS idx_inventory_count_lines_count ON inventory.inventory_count_lines(count_id);
|
|
CREATE INDEX IF NOT EXISTS idx_inventory_count_lines_product ON inventory.inventory_count_lines(product_id);
|
|
CREATE INDEX IF NOT EXISTS idx_inventory_count_lines_location ON inventory.inventory_count_lines(location_id);
|
|
CREATE INDEX IF NOT EXISTS idx_inventory_count_lines_counted ON inventory.inventory_count_lines(is_counted);
|
|
|
|
-- =====================
|
|
-- TABLA: transfer_orders
|
|
-- Ordenes de transferencia entre almacenes
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS inventory.transfer_orders (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
|
|
-- Identificacion
|
|
transfer_number VARCHAR(30) NOT NULL,
|
|
|
|
-- Origen y destino
|
|
source_warehouse_id UUID NOT NULL REFERENCES inventory.warehouses(id),
|
|
dest_warehouse_id UUID NOT NULL REFERENCES inventory.warehouses(id),
|
|
|
|
-- Fechas
|
|
scheduled_date DATE,
|
|
shipped_at TIMESTAMPTZ,
|
|
received_at TIMESTAMPTZ,
|
|
|
|
-- Estado
|
|
status VARCHAR(20) NOT NULL DEFAULT 'draft', -- draft, confirmed, shipped, in_transit, received, cancelled
|
|
|
|
-- Notas
|
|
notes TEXT,
|
|
|
|
-- Metadata
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
deleted_at TIMESTAMPTZ,
|
|
|
|
UNIQUE(tenant_id, transfer_number)
|
|
);
|
|
|
|
-- Indices para transfer_orders
|
|
CREATE INDEX IF NOT EXISTS idx_transfer_orders_tenant ON inventory.transfer_orders(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_transfer_orders_source ON inventory.transfer_orders(source_warehouse_id);
|
|
CREATE INDEX IF NOT EXISTS idx_transfer_orders_dest ON inventory.transfer_orders(dest_warehouse_id);
|
|
CREATE INDEX IF NOT EXISTS idx_transfer_orders_status ON inventory.transfer_orders(status);
|
|
CREATE INDEX IF NOT EXISTS idx_transfer_orders_date ON inventory.transfer_orders(scheduled_date);
|
|
|
|
-- =====================
|
|
-- TABLA: transfer_order_lines
|
|
-- Lineas de orden de transferencia
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS inventory.transfer_order_lines (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
transfer_id UUID NOT NULL REFERENCES inventory.transfer_orders(id) ON DELETE CASCADE,
|
|
product_id UUID NOT NULL REFERENCES products.products(id) ON DELETE RESTRICT,
|
|
|
|
-- Ubicaciones especificas
|
|
source_location_id UUID REFERENCES inventory.warehouse_locations(id),
|
|
dest_location_id UUID REFERENCES inventory.warehouse_locations(id),
|
|
|
|
-- Cantidades
|
|
quantity_requested DECIMAL(15, 4) NOT NULL,
|
|
quantity_shipped DECIMAL(15, 4) DEFAULT 0,
|
|
quantity_received DECIMAL(15, 4) DEFAULT 0,
|
|
|
|
-- Lote y serie
|
|
lot_number VARCHAR(50),
|
|
serial_number VARCHAR(50),
|
|
|
|
-- Notas
|
|
notes TEXT,
|
|
|
|
-- Metadata
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Indices para transfer_order_lines
|
|
CREATE INDEX IF NOT EXISTS idx_transfer_order_lines_transfer ON inventory.transfer_order_lines(transfer_id);
|
|
CREATE INDEX IF NOT EXISTS idx_transfer_order_lines_product ON inventory.transfer_order_lines(product_id);
|
|
|
|
-- =====================
|
|
-- COMENTARIOS
|
|
-- =====================
|
|
COMMENT ON TABLE inventory.stock_levels IS 'Niveles actuales de inventario por producto/almacen/ubicacion';
|
|
COMMENT ON COLUMN inventory.stock_levels.quantity_on_hand IS 'Cantidad fisica disponible en el almacen';
|
|
COMMENT ON COLUMN inventory.stock_levels.quantity_reserved IS 'Cantidad reservada para ordenes pendientes';
|
|
COMMENT ON COLUMN inventory.stock_levels.quantity_available IS 'Cantidad disponible para venta (on_hand - reserved)';
|
|
COMMENT ON COLUMN inventory.stock_levels.quantity_incoming IS 'Cantidad en transito o por recibir';
|
|
|
|
COMMENT ON TABLE inventory.stock_movements IS 'Historial de movimientos de inventario';
|
|
COMMENT ON COLUMN inventory.stock_movements.movement_type IS 'Tipo: receipt (entrada), shipment (salida), transfer, adjustment, return, production, consumption';
|
|
COMMENT ON COLUMN inventory.stock_movements.status IS 'Estado: draft, confirmed, cancelled';
|
|
|
|
COMMENT ON TABLE inventory.inventory_counts IS 'Conteos fisicos de inventario para reconciliacion';
|
|
COMMENT ON COLUMN inventory.inventory_counts.count_type IS 'Tipo: full (completo), partial, cycle (ciclico), spot (aleatorio)';
|
|
|
|
COMMENT ON TABLE inventory.transfer_orders IS 'Ordenes de transferencia entre almacenes';
|
|
COMMENT ON COLUMN inventory.transfer_orders.status IS 'Estado: draft, confirmed, shipped, in_transit, received, cancelled';
|
|
|
|
-- =====================
|
|
-- TABLA: lots
|
|
-- Lotes de productos para trazabilidad y control de caducidad
|
|
-- Coherencia: lot.entity.ts
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS inventory.lots (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
product_id UUID NOT NULL REFERENCES products.products(id) ON DELETE CASCADE,
|
|
|
|
-- Identificacion
|
|
name VARCHAR(100) NOT NULL,
|
|
ref VARCHAR(100),
|
|
|
|
-- Fechas de control
|
|
manufacture_date DATE,
|
|
expiration_date DATE,
|
|
removal_date DATE,
|
|
alert_date DATE,
|
|
|
|
-- Notas
|
|
notes TEXT,
|
|
|
|
-- Metadata
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
|
|
UNIQUE(product_id, name)
|
|
);
|
|
|
|
-- Indices para lots
|
|
CREATE INDEX IF NOT EXISTS idx_lots_tenant ON inventory.lots(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_lots_product ON inventory.lots(product_id);
|
|
CREATE INDEX IF NOT EXISTS idx_lots_name_product ON inventory.lots(product_id, name);
|
|
CREATE INDEX IF NOT EXISTS idx_lots_expiration ON inventory.lots(expiration_date) WHERE expiration_date IS NOT NULL;
|
|
CREATE INDEX IF NOT EXISTS idx_lots_alert ON inventory.lots(alert_date) WHERE alert_date IS NOT NULL;
|
|
|
|
-- =====================
|
|
-- TIPO ENUM: picking_type
|
|
-- =====================
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'picking_type_enum') THEN
|
|
CREATE TYPE inventory.picking_type_enum AS ENUM ('incoming', 'outgoing', 'internal');
|
|
END IF;
|
|
END$$;
|
|
|
|
-- =====================
|
|
-- TIPO ENUM: move_status
|
|
-- =====================
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'move_status_enum') THEN
|
|
CREATE TYPE inventory.move_status_enum AS ENUM ('draft', 'waiting', 'confirmed', 'assigned', 'done', 'cancelled');
|
|
END IF;
|
|
END$$;
|
|
|
|
-- =====================
|
|
-- TABLA: pickings
|
|
-- Operaciones de recepcion, envio y movimientos internos
|
|
-- Coherencia: picking.entity.ts
|
|
-- =====================
|
|
CREATE TABLE IF NOT EXISTS inventory.pickings (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
company_id UUID NOT NULL REFERENCES auth.companies(id) ON DELETE CASCADE,
|
|
|
|
-- Identificacion
|
|
name VARCHAR(100) NOT NULL,
|
|
|
|
-- Tipo de operacion
|
|
picking_type inventory.picking_type_enum NOT NULL,
|
|
|
|
-- Ubicaciones
|
|
location_id UUID NOT NULL REFERENCES inventory.warehouse_locations(id),
|
|
location_dest_id UUID NOT NULL REFERENCES inventory.warehouse_locations(id),
|
|
|
|
-- Partner (proveedor/cliente)
|
|
partner_id UUID REFERENCES partners.partners(id),
|
|
|
|
-- Fechas
|
|
scheduled_date TIMESTAMPTZ,
|
|
date_done TIMESTAMPTZ,
|
|
|
|
-- Origen (referencia documento)
|
|
origin VARCHAR(255),
|
|
|
|
-- Estado
|
|
status inventory.move_status_enum NOT NULL DEFAULT 'draft',
|
|
|
|
-- Notas
|
|
notes TEXT,
|
|
|
|
-- Validacion
|
|
validated_at TIMESTAMPTZ,
|
|
validated_by UUID REFERENCES auth.users(id),
|
|
|
|
-- Metadata
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_by UUID REFERENCES auth.users(id)
|
|
);
|
|
|
|
-- Indices para pickings
|
|
CREATE INDEX IF NOT EXISTS idx_pickings_tenant ON inventory.pickings(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_pickings_company ON inventory.pickings(company_id);
|
|
CREATE INDEX IF NOT EXISTS idx_pickings_status ON inventory.pickings(status);
|
|
CREATE INDEX IF NOT EXISTS idx_pickings_partner ON inventory.pickings(partner_id) WHERE partner_id IS NOT NULL;
|
|
CREATE INDEX IF NOT EXISTS idx_pickings_scheduled ON inventory.pickings(scheduled_date);
|
|
CREATE INDEX IF NOT EXISTS idx_pickings_type ON inventory.pickings(picking_type);
|
|
|
|
-- =====================
|
|
-- COMENTARIOS ADICIONALES
|
|
-- =====================
|
|
COMMENT ON TABLE inventory.lots IS 'Lotes de productos para trazabilidad, control de caducidad y FIFO/FEFO';
|
|
COMMENT ON COLUMN inventory.lots.name IS 'Numero o nombre del lote (debe ser unico por producto)';
|
|
COMMENT ON COLUMN inventory.lots.expiration_date IS 'Fecha de caducidad del lote';
|
|
COMMENT ON COLUMN inventory.lots.alert_date IS 'Fecha para alerta previa a caducidad';
|
|
|
|
COMMENT ON TABLE inventory.pickings IS 'Operaciones de recepcion (incoming), envio (outgoing) y movimientos internos';
|
|
COMMENT ON COLUMN inventory.pickings.picking_type IS 'Tipo: incoming (recepcion), outgoing (envio), internal (transferencia interna)';
|
|
COMMENT ON COLUMN inventory.pickings.status IS 'Estado: draft, waiting, confirmed, assigned, done, cancelled';
|
|
COMMENT ON COLUMN inventory.pickings.origin IS 'Documento origen (ej: PO-2026-001, SO-2026-001)';
|