-- ═══════════════════════════════════════════════════════════════════════
-- 2026-10-24_01 · Módulo "Facturación y Caja"
-- ═══════════════════════════════════════════════════════════════════════
-- Facturación (módulo 7) y Contabilidad (módulo 8) se unen en un solo
-- módulo, como "Inventario y Bodega". Cuentas por cobrar y caja chica pasan
-- a /caja/...; Contabilidad queda inactivo.
--
-- Cuentas de fondos: caja general (efectivo) y cuentas bancarias, con un
-- libro de movimientos (cuenta_movimiento) que es la única fuente del saldo:
--   + cobro         cada pago de factura dice a qué cuenta entró
--   − reposicion    el reembolso de una reposición de caja chica
--   ± transferencia entre cuentas (dos filas con el mismo id_transferencia)
--   + ingreso / − egreso  movimientos manuales
-- Los pagos que ya existían se asignan a "Caja general" (efectivo) o a
-- "Cuenta bancaria principal" (el resto); ajustarlas en Caja y bancos.
--
-- Respaldo: backups/tinsa_db_pre-facturacion-y-caja_2026-10-24.sql
-- Reversa:  database/rollback/2026-10-24_01_facturacion_y_caja.down.sql
-- ═══════════════════════════════════════════════════════════════════════

USE tinsa_db;

-- ── Módulo y pestañas ──────────────────────────────────────────────────
UPDATE modulos SET nombre = 'Facturación y Caja', icono = 'fa-cash-register' WHERE id = 7;
UPDATE modulos SET estado = 0 WHERE id = 8;

UPDATE pestanas SET ruta = '/caja/cuentas-por-cobrar', orden = 6 WHERE ruta = '/facturacion/cuentas-por-cobrar';
UPDATE pestanas SET id_modulo = 7, ruta = '/caja/caja-chica',    orden = 9  WHERE ruta = '/contabilidad/caja-chica';
UPDATE pestanas SET id_modulo = 7, ruta = '/caja/reposiciones',  orden = 10 WHERE ruta = '/contabilidad/reposiciones';
UPDATE pestanas SET id_modulo = 7, ruta = '/caja/cajas-chicas', nombre = 'Cajas chicas', orden = 11 WHERE ruta = '/contabilidad/cajas';
UPDATE pestanas SET orden = 4 WHERE ruta = '/facturacion/libros-iva';
UPDATE pestanas SET orden = 5 WHERE ruta = '/facturacion/configuracion';

INSERT INTO pestanas (id_modulo, nombre, ruta, icono, orden, estado) VALUES
  (7, 'Cobros registrados', '/caja/cobros',  'fa-money-bill-wave',    7, 1),
  (7, 'Caja y bancos',      '/caja/cuentas', 'fa-building-columns',   8, 1);

-- Las pestañas nuevas heredan los permisos de Cuentas por cobrar (por rol y por usuario)
INSERT INTO permisos_roles (id_rol, id_pestana, puede_leer, puede_escribir, puede_eliminar, puede_ver_historial)
SELECT pr.id_rol, n.id, pr.puede_leer, pr.puede_escribir, pr.puede_eliminar, pr.puede_ver_historial
  FROM permisos_roles pr
  JOIN pestanas cxc ON cxc.id = pr.id_pestana AND cxc.ruta = '/caja/cuentas-por-cobrar'
  JOIN pestanas n ON n.ruta IN ('/caja/cobros', '/caja/cuentas');
INSERT INTO permisos (id_usuario, id_pestana, puede_leer, puede_escribir, puede_eliminar, puede_ver_historial)
SELECT p.id_usuario, n.id, p.puede_leer, p.puede_escribir, p.puede_eliminar, p.puede_ver_historial
  FROM permisos p
  JOIN pestanas cxc ON cxc.id = p.id_pestana AND cxc.ruta = '/caja/cuentas-por-cobrar'
  JOIN pestanas n ON n.ruta IN ('/caja/cobros', '/caja/cuentas');

-- Enlaces guardados (notificaciones y bitácora) apuntan a las rutas nuevas
UPDATE notificacion SET ruta = REPLACE(ruta, '/facturacion/cuentas-por-cobrar', '/caja/cuentas-por-cobrar') WHERE ruta LIKE '/facturacion/cuentas-por-cobrar%';
UPDATE notificacion SET ruta = REPLACE(ruta, '/contabilidad/cajas', '/caja/cajas-chicas') WHERE ruta LIKE '/contabilidad/cajas%';
UPDATE notificacion SET ruta = REPLACE(ruta, '/contabilidad/', '/caja/') WHERE ruta LIKE '/contabilidad/%';
UPDATE bitacora SET ruta_pestana = '/caja/cuentas-por-cobrar' WHERE ruta_pestana = '/facturacion/cuentas-por-cobrar';
UPDATE bitacora SET ruta_pestana = '/caja/cajas-chicas' WHERE ruta_pestana = '/contabilidad/cajas';
UPDATE bitacora SET ruta_pestana = REPLACE(ruta_pestana, '/contabilidad/', '/caja/') WHERE ruta_pestana LIKE '/contabilidad/%';

-- ── Cuentas de fondos ──────────────────────────────────────────────────
CREATE TABLE cuenta_fondos (
  id                  INT UNSIGNED NOT NULL AUTO_INCREMENT,
  nombre              VARCHAR(120) NOT NULL,
  tipo                ENUM('efectivo','banco') NOT NULL,
  banco               VARCHAR(80)  DEFAULT NULL,
  numero_cuenta       VARCHAR(40)  DEFAULT NULL,
  tipo_cuenta         ENUM('corriente','ahorro') DEFAULT NULL,
  id_sucursal         INT UNSIGNED DEFAULT NULL,
  saldo_inicial       DECIMAL(14,2) NOT NULL DEFAULT 0 COMMENT 'saldo a la fecha_saldo_inicial, antes de los movimientos',
  fecha_saldo_inicial DATE NOT NULL,
  activo              TINYINT(1) NOT NULL DEFAULT 1,
  usuario_modifico    INT UNSIGNED DEFAULT NULL,
  created_at          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id),
  UNIQUE KEY uq_cuenta_fondos_nombre (nombre),
  KEY fk_cuenta_fondos_sucursal (id_sucursal),
  KEY fk_cuenta_fondos_usuario (usuario_modifico),
  CONSTRAINT fk_cuenta_fondos_sucursal FOREIGN KEY (id_sucursal) REFERENCES sucursal (id) ON DELETE SET NULL ON UPDATE CASCADE,
  CONSTRAINT fk_cuenta_fondos_usuario FOREIGN KEY (usuario_modifico) REFERENCES usuarios (id_usuario) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Caja general y cuentas bancarias';

CREATE TABLE cuenta_movimiento (
  id               INT UNSIGNED NOT NULL AUTO_INCREMENT,
  id_cuenta        INT UNSIGNED NOT NULL,
  fecha            DATE NOT NULL,
  tipo             ENUM('cobro','reposicion','transferencia','ingreso','egreso') NOT NULL,
  monto            DECIMAL(14,2) NOT NULL COMMENT 'con signo: + entra, − sale',
  concepto         VARCHAR(255) NOT NULL,
  referencia       VARCHAR(100) DEFAULT NULL,
  id_factura_pago  INT UNSIGNED DEFAULT NULL,
  id_reposicion    INT UNSIGNED DEFAULT NULL,
  id_transferencia INT UNSIGNED DEFAULT NULL COMMENT 'mismo valor en las dos filas de una transferencia',
  id_usuario       INT UNSIGNED DEFAULT NULL,
  created_at       TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (id),
  UNIQUE KEY uq_movimiento_pago (id_factura_pago),
  KEY idx_movimiento_cuenta_fecha (id_cuenta, fecha),
  KEY idx_movimiento_transferencia (id_transferencia),
  KEY fk_movimiento_reposicion (id_reposicion),
  KEY fk_movimiento_usuario (id_usuario),
  CONSTRAINT fk_movimiento_cuenta FOREIGN KEY (id_cuenta) REFERENCES cuenta_fondos (id) ON UPDATE CASCADE,
  CONSTRAINT fk_movimiento_pago FOREIGN KEY (id_factura_pago) REFERENCES factura_pago (id) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT fk_movimiento_reposicion FOREIGN KEY (id_reposicion) REFERENCES caja_chica_reposicion (id) ON UPDATE CASCADE,
  CONSTRAINT fk_movimiento_usuario FOREIGN KEY (id_usuario) REFERENCES usuarios (id_usuario) ON DELETE SET NULL ON UPDATE CASCADE,
  CONSTRAINT chk_movimiento_monto CHECK (monto <> 0),
  CONSTRAINT chk_movimiento_signo CHECK ((tipo IN ('cobro','ingreso') AND monto > 0) OR (tipo IN ('reposicion','egreso') AND monto < 0) OR tipo = 'transferencia')
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Libro de cada cuenta de fondos: el saldo es saldo_inicial + SUM(monto)';

-- Cuentas iniciales y los pagos que ya había
INSERT INTO cuenta_fondos (nombre, tipo, saldo_inicial, fecha_saldo_inicial) VALUES
  ('Caja general', 'efectivo', 0, '2026-10-01'),
  ('Cuenta bancaria principal', 'banco', 0, '2026-10-01');

INSERT INTO cuenta_movimiento (id_cuenta, fecha, tipo, monto, concepto, referencia, id_factura_pago, id_usuario, created_at)
SELECT c.id, p.fecha, 'cobro', p.monto, CONCAT('Cobro ', f.numero_control, ' · ', f.receptor_nombre), p.referencia, p.id, p.id_usuario, p.created_at
  FROM factura_pago p
  JOIN factura f ON f.id = p.id_factura
  JOIN cuenta_fondos c ON c.nombre = IF(p.forma_pago = 'efectivo', 'Caja general', 'Cuenta bancaria principal');
