143 lines
5.5 KiB
PL/PgSQL
143 lines
5.5 KiB
PL/PgSQL
-- SQL para agregar funcionalidad de préstamos al sistema de inventario
|
|
-- PostgreSQL
|
|
|
|
-- 1. Agregar el nuevo tipo de movimiento PRESTAMO al enum existente
|
|
-- Nota: PostgreSQL no tiene ALTER ENUM, así que necesitamos recrear el enum
|
|
-- Primero creamos el nuevo enum
|
|
|
|
CREATE TYPE tipo_movimiento_new AS ENUM (
|
|
'ENTRADA',
|
|
'SALIDA',
|
|
'TRASLADO',
|
|
'BAJA',
|
|
'REPARACION',
|
|
'AJUSTE',
|
|
'CAMBIO_ESTADO',
|
|
'PRESTAMO'
|
|
);
|
|
|
|
-- Convertimos los datos existentes al nuevo enum
|
|
ALTER TABLE movimientos_inventario
|
|
ALTER COLUMN tipo_movimiento TYPE tipo_movimiento_new
|
|
USING tipo_movimiento::text::tipo_movimiento_new;
|
|
|
|
-- Eliminamos el enum viejo y renombramos el nuevo
|
|
DROP TYPE tipo_movimiento;
|
|
ALTER TYPE tipo_movimiento_new RENAME TO tipo_movimiento;
|
|
|
|
-- 2. Crear tabla de préstamos
|
|
CREATE TABLE prestamos (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
articulo_id INTEGER NOT NULL,
|
|
cantidad INTEGER NOT NULL,
|
|
persona_nombre VARCHAR(200) NOT NULL,
|
|
persona_identificacion VARCHAR(50),
|
|
fecha_prestamo TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
fecha_devolucion_estimada TIMESTAMP WITH TIME ZONE,
|
|
fecha_devolucion_real TIMESTAMP WITH TIME ZONE,
|
|
estado VARCHAR(20) NOT NULL DEFAULT 'ACTIVO',
|
|
observacion VARCHAR(500),
|
|
usuario_id VARCHAR(100),
|
|
CONSTRAINT fk_prestamos_articulos FOREIGN KEY (articulo_id) REFERENCES articulos(id) ON DELETE CASCADE
|
|
);
|
|
|
|
-- 3. Crear tabla de detalles de préstamo (para códigos individuales)
|
|
CREATE TABLE prestamo_detalles (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
prestamo_id BIGINT NOT NULL,
|
|
codigo_articulo_individual VARCHAR(100) NOT NULL,
|
|
estado VARCHAR(20) NOT NULL DEFAULT 'PRESTADO',
|
|
fecha_devolucion TIMESTAMP WITH TIME ZONE,
|
|
observacion VARCHAR(300),
|
|
CONSTRAINT fk_prestamo_detalles_prestamo FOREIGN KEY (prestamo_id) REFERENCES prestamos(id) ON DELETE CASCADE
|
|
);
|
|
|
|
-- 4. Crear índices para mejor rendimiento
|
|
CREATE INDEX idx_prestamos_articulo_id ON prestamos(articulo_id);
|
|
CREATE INDEX idx_prestamos_estado ON prestamos(estado);
|
|
CREATE INDEX idx_prestamos_fecha_prestamo ON prestamos(fecha_prestamo);
|
|
CREATE INDEX idx_prestamo_detalles_prestamo_id ON prestamo_detalles(prestamo_id);
|
|
CREATE INDEX idx_prestamo_detalles_codigo ON prestamo_detalles(codigo_articulo_individual);
|
|
|
|
-- 5. Crear función para generar códigos individuales automáticamente
|
|
CREATE OR REPLACE FUNCTION generar_codigo_individual(p_codigo_base VARCHAR, p_secuencia INTEGER)
|
|
RETURNS VARCHAR AS $$
|
|
BEGIN
|
|
RETURN p_codigo_base || '-' || LPAD(p_secuencia::TEXT, 3, '0');
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- 6. Crear trigger para actualizar estado de préstamo cuando todos los detalles están devueltos
|
|
CREATE OR REPLACE FUNCTION actualizar_estado_prestamo()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
-- Si se actualiza un detalle a DEVUELTO, verificar si todos están devueltos
|
|
IF NEW.estado = 'DEVUELTO' THEN
|
|
UPDATE prestamos
|
|
SET estado = CASE
|
|
WHEN NOT EXISTS (
|
|
SELECT 1 FROM prestamo_detalles
|
|
WHERE prestamo_id = NEW.prestamo_id AND estado != 'DEVUELTO'
|
|
) THEN 'DEVUELTO'
|
|
ELSE estado
|
|
END,
|
|
fecha_devolucion_real = CASE
|
|
WHEN NOT EXISTS (
|
|
SELECT 1 FROM prestamo_detalles
|
|
WHERE prestamo_id = NEW.prestamo_id AND estado != 'DEVUELTO'
|
|
) THEN CURRENT_TIMESTAMP
|
|
ELSE fecha_devolucion_real
|
|
END
|
|
WHERE id = NEW.prestamo_id;
|
|
END IF;
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- 7. Crear el trigger
|
|
CREATE TRIGGER trigger_actualizar_estado_prestamo
|
|
AFTER UPDATE ON prestamo_detalles
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION actualizar_estado_prestamo();
|
|
|
|
-- 8. Insertar datos de ejemplo (opcional)
|
|
-- INSERT INTO prestamos (articulo_id, cantidad, persona_nombre, persona_identificacion, fecha_devolucion_estimada, observacion, usuario_id)
|
|
-- VALUES (1, 2, 'Juan Pérez', '12345678', CURRENT_TIMESTAMP + INTERVAL '7 days', 'Préstamo para evento especial', 'admin');
|
|
|
|
-- Generar códigos individuales para el préstamo de ejemplo
|
|
-- INSERT INTO prestamo_detalles (prestamo_id, codigo_articulo_individual, estado)
|
|
-- VALUES
|
|
-- (1, generar_codigo_individual('sp-b20', 1), 'PRESTADO'),
|
|
-- (1, generar_codigo_individual('sp-b20', 2), 'PRESTADO');
|
|
|
|
-- 9. Crear vista para préstamos activos con detalles
|
|
CREATE OR REPLACE VIEW vista_prestamos_activos AS
|
|
SELECT
|
|
p.id,
|
|
p.articulo_id,
|
|
a.codigo as articulo_codigo,
|
|
a.nombre as articulo_nombre,
|
|
p.cantidad,
|
|
p.persona_nombre,
|
|
p.persona_identificacion,
|
|
p.fecha_prestamo,
|
|
p.fecha_devolucion_estimada,
|
|
p.estado,
|
|
p.observacion,
|
|
p.usuario_id,
|
|
COUNT(pd.id) as detalles_devueltos,
|
|
(p.cantidad - COUNT(pd.id)) as detalles_pendientes
|
|
FROM prestamos p
|
|
LEFT JOIN articulos a ON p.articulo_id = a.id
|
|
LEFT JOIN prestamo_detalles pd ON p.id = pd.prestamo_id AND pd.estado = 'DEVUELTO'
|
|
WHERE p.estado = 'ACTIVO'
|
|
GROUP BY p.id, p.articulo_id, a.codigo, a.nombre, p.cantidad, p.persona_nombre, p.persona_identificacion, p.fecha_prestamo, p.fecha_devolucion_estimada, p.estado, p.observacion, p.usuario_id;
|
|
|
|
-- 10. Conceder permisos (ajustar según tu usuario de base de datos)
|
|
-- GRANT SELECT, INSERT, UPDATE, DELETE ON prestamos TO tu_usuario;
|
|
-- GRANT SELECT, INSERT, UPDATE, DELETE ON prestamo_detalles TO tu_usuario;
|
|
-- GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO tu_usuario;
|
|
-- GRANT EXECUTE ON FUNCTION generar_codigo_individual TO tu_usuario;
|
|
-- GRANT EXECUTE ON FUNCTION actualizar_estado_prestamo TO tu_usuario;
|
|
-- GRANT SELECT ON vista_prestamos_activos TO tu_usuario; |