SELECT 1; /* MIGRACION 014: Crear tabla ventas + ALTER transacciones, comprobantes_transacciones, planes_pago | Fecha: 2026-02-02 | Plan: TABLA_VENTAS | Usa trigger_set_updated_at() existente */

CREATE TABLE IF NOT EXISTS ventas (
    id_venta            SERIAL PRIMARY KEY,
    business_id         VARCHAR(100) NOT NULL,
    sucursal            INTEGER[],
    id_cliente          INTEGER,
    cliente             VARCHAR(100),
    numero_telefono     BIGINT,
    empleado            VARCHAR(100),
    empleado_login_id   INTEGER,
    monto_total         NUMERIC(12,2) NOT NULL,
    tipo_pago           INTEGER,
    efectivo            JSONB,
    id_plan_pago        INTEGER,
    fecha_venta         TIMESTAMP WITH TIME ZONE NOT NULL,
    version_actual      INTEGER NOT NULL DEFAULT 1,
    historial_versiones JSONB NOT NULL DEFAULT '[]'::jsonb,
    created_at          TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
    created_by_login_id INTEGER NOT NULL,
    updated_at          TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
    updated_by_login_id INTEGER,
    soft_delete         BOOLEAN DEFAULT FALSE,
    soft_delete_date    TIMESTAMP WITH TIME ZONE
);

CREATE INDEX IF NOT EXISTS idx_ventas_business ON ventas(business_id);

CREATE INDEX IF NOT EXISTS idx_ventas_fecha ON ventas(fecha_venta);

CREATE INDEX IF NOT EXISTS idx_ventas_cliente ON ventas(id_cliente);

CREATE INDEX IF NOT EXISTS idx_ventas_sucursal ON ventas USING gin(sucursal);

CREATE INDEX IF NOT EXISTS idx_ventas_soft_delete ON ventas(soft_delete);

DROP INDEX IF EXISTS idx_ventas_plan_pago;

CREATE INDEX idx_ventas_plan_pago ON ventas(id_plan_pago) WHERE id_plan_pago IS NOT NULL;

DROP TRIGGER IF EXISTS trg_ventas_updated_at ON ventas;

CREATE TRIGGER trg_ventas_updated_at BEFORE UPDATE ON ventas FOR EACH ROW EXECUTE FUNCTION trigger_set_updated_at();

ALTER TABLE ventas DROP CONSTRAINT IF EXISTS fk_ventas_cliente;

ALTER TABLE ventas ADD CONSTRAINT fk_ventas_cliente FOREIGN KEY (id_cliente) REFERENCES clientes(id_cliente) ON DELETE SET NULL;

COMMENT ON TABLE ventas IS 'Tabla padre que agrupa transacciones individuales en una entidad de venta. Cada venta contiene 1+ transacciones.';

COMMENT ON COLUMN ventas.sucursal IS 'Array de IDs de sucursal. Por politica, contiene exactamente 1 valor.';

COMMENT ON COLUMN ventas.monto_total IS 'Suma de cobrado de todas las transacciones de la venta. Se recalcula al modificar/eliminar transacciones.';

COMMENT ON COLUMN ventas.efectivo IS 'Desglose de denominaciones JSONB: [[denominacion, cantidad], ...]. Centralizado, no duplicado por transaccion.';

COMMENT ON COLUMN ventas.tipo_pago IS '1=efectivo, 2=transferencia, 3=tarjeta.';

COMMENT ON COLUMN ventas.version_actual IS 'Contador de version. Se incrementa con cada modificacion a la venta o sus transacciones.';

COMMENT ON COLUMN ventas.historial_versiones IS 'Array JSONB de snapshots del estado anterior antes de cada modificacion.';

ALTER TABLE transacciones ADD COLUMN IF NOT EXISTS id_venta INTEGER;

ALTER TABLE transacciones DROP CONSTRAINT IF EXISTS fk_transacciones_venta;

ALTER TABLE transacciones ADD CONSTRAINT fk_transacciones_venta FOREIGN KEY (id_venta) REFERENCES ventas(id_venta) ON DELETE SET NULL;

DROP INDEX IF EXISTS idx_transacciones_venta;

CREATE INDEX idx_transacciones_venta ON transacciones(id_venta);

COMMENT ON COLUMN transacciones.id_venta IS 'FK a ventas: Si no es NULL, esta transaccion pertenece a una venta padre. NULL = transaccion legacy sin venta.';

ALTER TABLE comprobantes_transacciones ALTER COLUMN id_transaccion DROP NOT NULL;

ALTER TABLE comprobantes_transacciones ADD COLUMN IF NOT EXISTS id_venta INTEGER;

ALTER TABLE comprobantes_transacciones DROP CONSTRAINT IF EXISTS fk_comprobantes_venta;

ALTER TABLE comprobantes_transacciones ADD CONSTRAINT fk_comprobantes_venta FOREIGN KEY (id_venta) REFERENCES ventas(id_venta) ON DELETE SET NULL;

DROP INDEX IF EXISTS idx_comprobantes_venta;

CREATE INDEX idx_comprobantes_venta ON comprobantes_transacciones(id_venta);

ALTER TABLE comprobantes_transacciones DROP CONSTRAINT IF EXISTS chk_comprobante_vinculo;

ALTER TABLE comprobantes_transacciones ADD CONSTRAINT chk_comprobante_vinculo CHECK (id_transaccion IS NOT NULL OR id_venta IS NOT NULL);

COMMENT ON COLUMN comprobantes_transacciones.id_venta IS 'FK a ventas: Comprobante a nivel de venta completa. Alternativo a id_transaccion (nivel articulo individual).';

ALTER TABLE planes_pago ADD COLUMN IF NOT EXISTS id_venta INTEGER;

ALTER TABLE planes_pago DROP CONSTRAINT IF EXISTS fk_planes_pago_venta;

ALTER TABLE planes_pago ADD CONSTRAINT fk_planes_pago_venta FOREIGN KEY (id_venta) REFERENCES ventas(id_venta) ON DELETE SET NULL;

DROP INDEX IF EXISTS idx_planes_pago_venta;

CREATE INDEX idx_planes_pago_venta ON planes_pago(id_venta) WHERE id_venta IS NOT NULL;

COMMENT ON COLUMN planes_pago.id_venta IS 'FK a ventas: La venta que origino este plan de pago. Vinculo bidireccional con ventas.id_plan_pago.';

ALTER TABLE ventas DROP CONSTRAINT IF EXISTS fk_ventas_plan_pago;

ALTER TABLE ventas ADD CONSTRAINT fk_ventas_plan_pago FOREIGN KEY (id_plan_pago) REFERENCES planes_pago(id_plan) ON DELETE SET NULL;
