-- ============================================================
-- SP_BuscarMovimientoCaja
--
-- Reemplaza la consulta sobre Caja.VWMovimientoCaja con tablas
-- temporales e índices para facilitar depuración por secciones.
--
-- Parámetros derivados de BuscarMovimientoCaja en MovimientoCajaBO.php
-- ============================================================

CREATE   PROCEDURE [Caja].[SP_BuscarMovimientoCaja]
    @IdProfesionalOrden         INT           = NULL,
    @IdProfesional              INT           = NULL,
    @IdTipoPrestacion           INT           = NULL,
    -- Valor especial -2: filtra PROCEDIMIENTOS (4) y CONSULTA (1)
    @IdTipoPrestacionMultiple   BIT           = 0,
    @IdMovimientoCaja           INT           = NULL,
    @IdPaciente                 INT           = NULL,
    @IdCicloCaja                INT           = NULL,
    @IdUsuarioCajero            INT           = NULL,
    @IdCaja                     INT           = NULL,
    @IdTipoModalidadPago        INT           = NULL,
    @IdTipoCopago               INT           = NULL,
    @Monto                      DECIMAL(18,2) = NULL,
    @FechaMovimientoDesde       DATETIME      = NULL,
    @FechaMovimientoHasta       DATETIME      = NULL,
    @Excedentes                 DECIMAL(18,2) = NULL,
    @FechaEmisionDesde          DATETIME      = NULL,
    @FechaEmisionHasta          DATETIME      = NULL,
    @FechaRecepcionDesde        DATETIME      = NULL,
    @FechaRecepcionHasta        DATETIME      = NULL,
    @MontoCopago                DECIMAL(18,2) = NULL,
    @MontoPagadoPrevision       DECIMAL(18,2) = NULL,
    @NroBono                    VARCHAR(200)  = NULL,
    @NroTransaccionTBK          VARCHAR(200)  = NULL,
    @OrigenBono                 VARCHAR(200)  = NULL,
    @Seguros                    VARCHAR(200)  = NULL,
    @SistemaSalud               VARCHAR(200)  = NULL,
    @TotalBono                  DECIMAL(18,2) = NULL,
    @IdBanco                    INT           = NULL,
    @NroCuentaCheque            VARCHAR(100)  = NULL,
    @NroSerieCheque             VARCHAR(100)  = NULL,
    @FechaEmisionChequeDesde    DATETIME      = NULL,
    @FechaEmisionChequeHasta    DATETIME      = NULL,
    @NumeroGarantia             VARCHAR(100)  = NULL,
    @IdCita                     INT           = NULL,
    @IdIsapre                   INT           = NULL,
    @IdTipoEstadoMovimientoCaja INT           = NULL,
    -- Valor especial -2: filtra Pagado (1) y ControlMedico (2)
    @IdTipoEstadoMultiple       BIT           = 0,
    @Top                        INT           = NULL
AS
BEGIN
    SET NOCOUNT ON
    -- Evita que SQL Server levante el warning SQLSTATE 01003 ("Null value is
    -- eliminated by an aggregate or other SET operation") cuando MAX()/STRING_AGG()
    -- procesan columnas con NULL (secciones 1 y 2). El framework (ExecuteDao.php)
    -- no distingue warnings de errores reales y aborta el request completo ante
    -- cualquier SQLSTATE distinto de éxito, así que este warning se debe evitar
    -- aquí en vez de solo suprimirlo en la app.
    SET ANSI_WARNINGS OFF

    DECLARE @TIPO_PRESTACION_CONSULTA INT 			= 1
    DECLARE @TIPO_PRESTACION_PROCEDIMIENTO INT 		= 4
    
    DECLARE @TIPO_ESTADO_MOVCAJA_PAGADO			INT = 1
    DECLARE @TIPO_ESTADO_MOVCAJA_CONTROL_MEDICO	INT = 3

    -- ============================================================
    -- SECCIÓN 1: Folios IMED concatenados por cita
    -- ============================================================
    CREATE TABLE #ImedFolios (
        IdCita               INT          NOT NULL,
        FoliosConcatenados   VARCHAR(MAX) NULL,
        PRIMARY KEY (IdCita)
    )

    INSERT INTO #ImedFolios (IdCita, FoliosConcatenados)
    SELECT
        IdCita,
        STRING_AGG(CAST(FolioBono AS VARCHAR(MAX)), ' | ')
    FROM (
        SELECT DISTINCT IdCita, FolioBono
        FROM [Imed].[VWListadoBonoInterfaz]
    ) t
    GROUP BY IdCita

    -- ============================================================
    -- SECCIÓN 2: Última ficha de evolución por cita
    -- ============================================================
    CREATE TABLE #CitaEvolucion (
        IdCita            INT NOT NULL,
        IdFichaEvolucion  INT NULL,
        PRIMARY KEY (IdCita)
    )

    INSERT INTO #CitaEvolucion (IdCita, IdFichaEvolucion)
    SELECT IdCita, MAX(IdFichaEvolucion)
    FROM Clinica.CitaFichaEvolucionExamen WITH (NOLOCK)
    GROUP BY IdCita

    -- ============================================================
    -- SECCIÓN 3: Profesional por presupuesto/cita (PresupuestoDetalle)
    -- ============================================================
    CREATE TABLE #ProfPresupuesto (
        IdPresupuesto    INT           NOT NULL,
        IdCita           INT           NOT NULL,
        MontoPrestacion  DECIMAL(18,2) NULL,
        IdProfesional    INT           NOT NULL
    )

    CREATE INDEX IX_ProfPresupuesto ON #ProfPresupuesto (IdPresupuesto, IdCita, MontoPrestacion)

    -- PresupuestoDetalle NO tiene restricción de unicidad sobre
    -- (IdPresupuesto, IdCita, MontoPrestacion): si dos ítems del mismo
    -- presupuesto/cita cuestan lo mismo, esa combinación se repite.
    -- Nos quedamos con un solo detalle por combinación (el de menor
    -- IdPresupuestoDetalle) para que el LEFT JOIN de la SECCIÓN 4 no
    -- multiplique filas y viole la PK de #BaseData.
    INSERT INTO #ProfPresupuesto (IdPresupuesto, IdCita, MontoPrestacion, IdProfesional)
    SELECT IdPresupuesto, IdCita, MontoPrestacion, IdProfesional
    FROM (
        SELECT
            IdPresupuesto, IdCita, MontoPrestacion, IdProfesional,
            ROW_NUMBER() OVER (
                PARTITION BY IdPresupuesto, IdCita, MontoPrestacion
                ORDER BY IdPresupuestoDetalle
            ) AS rn
        FROM Presupuesto.PresupuestoDetalle
        WHERE IdProfesional IS NOT NULL
    ) t
    WHERE t.rn = 1

    -- ============================================================
    -- SECCIÓN 4: BaseData — un registro por MovimientoCaja
    -- ============================================================
    CREATE TABLE #BaseData (
        IdMovimientoCaja              INT           NOT NULL,
        IdPresupuesto                 INT           NULL,
        IdCita                        INT           NULL,
        NroTransaccionTBK             VARCHAR(200)  NULL,
        NroBoleta                     VARCHAR(200)  NULL,
        NroBono                       VARCHAR(200)  NULL,
        OrigenBono                    VARCHAR(100)  NULL,
        Monto                         DECIMAL(18,2) NULL,
        MontoCopago                   DECIMAL(18,2) NULL,
        TotalBono                     DECIMAL(18,2) NULL,
        MontoPagadoPrevision          DECIMAL(18,2) NULL,
        FechaMovimiento               DATETIME      NULL,
        FechaEmision                  DATETIME      NULL,
        IdTipoEstadoMovimientoCaja    INT           NULL,
        SistemaSalud                  INT           NULL,
        IdIsapre                      INT           NULL,
        Seguros                       DECIMAL(18,2) NULL,
        Excendentes                   DECIMAL(18,2) NULL,
        Aprobado                      BIT           NULL,
        IdCaja                        INT           NULL,
        Caja                          VARCHAR(200)  NULL,
        IdTipoEstadoCaja              INT           NULL,
        IdCicloCaja                   INT           NULL,
        IdUsuarioCajero               INT           NULL,
        FechaApertura                 DATETIME      NULL,
        FechaCierre                   DATETIME      NULL,
        IdTipoModalidadPago           INT           NULL,
        ModalidadPagoDesc             VARCHAR(200)  NULL,
        IdTipoCopago                  INT           NULL,
        TipoCopagoDesc                VARCHAR(200)  NULL,
        TipoEstadoMovimientoCajaDesc  VARCHAR(200)  NULL,
        IdPaciente                    INT           NULL,
        RutPaciente                   VARCHAR(20)   NULL,
        NombrePaciente                VARCHAR(400)  NULL,
        SistemaSaludDesc              VARCHAR(200)  NULL,
        IsapreDesc                    VARCHAR(200)  NULL,
        Cajero                        VARCHAR(200)  NULL,
        CodigoXml                     VARCHAR(10)   NULL,
        IdProfesional                 INT           NULL,
        IdProfesionalExterno          INT           NULL,
        IdTipoPrestacion              INT           NULL,
        TipoPrestacionDesc            VARCHAR(200)  NULL,
        MtoBonAdicVw                  DECIMAL(18,2) NULL,
        -- Profesional titular de la cita
        RutProf                       VARCHAR(20)   NULL,
        NomProf                       VARCHAR(200)  NULL,
        ApeProf                       VARCHAR(200)  NULL,
        IdTipoOrigenProfesional       INT           NULL,
        -- Profesional externo
        IdProfExt                     INT           NULL,
        RutProfExt                    VARCHAR(20)   NULL,
        NomProfExt                    VARCHAR(200)  NULL,
        ApeProfExt                    VARCHAR(200)  NULL,
        -- Profesional de la ficha de evolución (origen)
        RutProfOri                    VARCHAR(20)   NULL,
        NomProfOri                    VARCHAR(200)  NULL,
        ApeProfOri                    VARCHAR(200)  NULL,
        -- Profesional de la ficha (profFicha)
        IdProfFicha                   INT           NULL,
        RutProfFicha                  VARCHAR(20)   NULL,
        NomProfFicha                  VARCHAR(200)  NULL,
        ApeProfFicha                  VARCHAR(200)  NULL,
        -- Folios IMED
        FoliosConcatenados            VARCHAR(MAX)  NULL,
        TieneBonoConMonto             BIT           NOT NULL DEFAULT 0,
        -- Profesional del presupuesto
        IdProfesionalPD               INT           NULL,
        RutProfesionalPD              VARCHAR(20)   NULL,
        NomProfesionalPD              VARCHAR(200)  NULL,
        ApeProfesionalPD              VARCHAR(200)  NULL,
        PRIMARY KEY (IdMovimientoCaja)
    )

    INSERT INTO #BaseData
    SELECT
        mc.IdMovimientoCaja, mc.IdPresupuesto, mc.IdCita, mc.NroTransaccionTBK, mc.NroBoleta, mc.NroBono,
        mc.OrigenBono, mc.Monto, mc.MontoCopago, mc.TotalBono, mc.MontoPagadoPrevision, mc.FechaMovimiento,
        mc.FechaEmision, mc.IdTipoEstadoMovimientoCaja, mc.SistemaSalud, mc.IdIsapre, mc.Seguros,
        mc.Excendentes, mc.Aprobado,
        c.IdCaja, c.Descripcion, c.IdTipoEstadoCaja,
        cc.IdCicloCaja, cc.IdUsuarioCajero, cc.FechaApertura, cc.FechaCierre,
        mp.IdTipoModalidadPago, mp.Descripcion,
        tc.IdTipoCopago, tc.Descripcion,
        temc.Descripcion,
        p.IdPaciente, p.Rut, p.Nombres + ' ' + p.Apellidos,
        ss.Descripcion, i.Descripcion,
        u.LoginName,
        '', cita.IdProfesional, cita.IdProfesionalExterno,
        prest.IdTipoPrestacion, prest.Descripcion,
        vwb.MtoBonAdic,
        prof.Rut, prof.Nombres, prof.Apellidos, prof.IdTipoOrigenProfesional,
        profExt.IdProfesional, profExt.Rut, profExt.Nombres, profExt.Apellidos,
        profOri.Rut, profOri.Nombres, profOri.Apellidos,
        profFicha.IdProfesional, profFicha.Rut, profFicha.Nombres, profFicha.Apellidos,
        imedF.FoliosConcatenados,
        CASE WHEN ISNULL(mc.NroBono, '') <> '' AND mc.Monto > 0 THEN 1 ELSE 0 END,
        pdProf.IdProfesional, profPD.Rut, profPD.Nombres, profPD.Apellidos
    FROM Caja.MovimientoCaja mc WITH (NOLOCK)
    INNER JOIN Caja.Caja c WITH (NOLOCK)
        ON mc.IdCaja = c.IdCaja
    INNER JOIN Caja.CicloCaja cc WITH (NOLOCK)
        ON mc.IdCicloCaja = cc.IdCicloCaja
    INNER JOIN Clinica.Cita cita WITH (NOLOCK)
        ON cita.IdCita = mc.IdCita
    INNER JOIN Clinica.Paciente p WITH (NOLOCK)
        ON p.IdPaciente = cita.IdPaciente
    INNER JOIN Clinica.SistemaSalud ss WITH (NOLOCK)
        ON ss.IdSistemaSalud = mc.SistemaSalud
    INNER JOIN Core.Usuario u WITH (NOLOCK)
        ON u.IdUsuario = cc.IdUsuarioCajero
    INNER JOIN Clinica.Prestacion prest WITH (NOLOCK)
        ON prest.IdPrestacion = cita.IdPrestacion
    INNER JOIN Caja.TipoEstadoMovimientoCaja temc WITH (NOLOCK)
        ON temc.IdTipoEstadoMovimientoCaja = mc.IdTipoEstadoMovimientoCaja
    LEFT JOIN Caja.TipoModalidadPago mp WITH (NOLOCK)
        ON mc.IdTipoModalidadPago = mp.IdTipoModalidadPago
    LEFT JOIN Caja.TipoCopago tc WITH (NOLOCK)
        ON mc.IdTipoCopago = tc.IdTipoCopago
    LEFT JOIN Clinica.Isapre i WITH (NOLOCK)
        ON i.IdIsapre = mc.IdIsapre
    LEFT JOIN [Imed].[VWBonoInterfaz] vwb
        ON vwb.IdCita = mc.IdCita
    LEFT JOIN Clinica.Profesional prof WITH (NOLOCK)
        ON prof.IdProfesional = cita.IdProfesional
    LEFT JOIN #CitaEvolucion ce
        ON ce.IdCita = cita.IdCita
    LEFT JOIN Ficha.FichaEvolucion fe WITH (NOLOCK)
        ON fe.IdFichaEvolucion = ce.IdFichaEvolucion
    LEFT JOIN Clinica.Profesional profOri WITH (NOLOCK)
        ON profOri.IdProfesional = fe.IdProfesional
    LEFT JOIN Clinica.Profesional profExt WITH (NOLOCK)
        ON profExt.IdProfesional = cita.IdProfesionalExterno
    LEFT JOIN Clinica.Profesional profFicha WITH (NOLOCK)
        ON profFicha.IdProfesional = fe.IdProfesional
    LEFT JOIN #ImedFolios imedF
        ON imedF.IdCita = mc.IdCita
    LEFT JOIN #ProfPresupuesto pdProf
        ON  pdProf.IdPresupuesto   = mc.IdPresupuesto
        AND pdProf.IdCita          = mc.IdCita
        AND pdProf.MontoPrestacion = mc.Monto
    LEFT JOIN Clinica.Profesional profPD WITH (NOLOCK)
        ON profPD.IdProfesional = pdProf.IdProfesional

    -- ============================================================
    -- SECCIÓN 5: Resultado final con expansión de filas (TipoFila)
    --            + parte de VWMovimientoCajaInsumosMedicosAdaptado
    -- ============================================================

    -- Tabla para acumular el resultado antes de aplicar los filtros
    -- que sólo se pueden evaluar sobre columnas calculadas
    CREATE TABLE #Resultado (
        IdMovimientoCaja              INT           NOT NULL,
        Identificador                 VARCHAR(20)   NULL,
        NroTransaccionTBK             VARCHAR(200)  NULL,
        NroBoleta                     VARCHAR(200)  NULL,
        NroTransaccionTBKBoleta       VARCHAR(200)  NULL,
        NroBono                       VARCHAR(200)  NULL,
        IdCaja                        INT           NULL,
        Caja                          VARCHAR(200)  NULL,
        ModalidadPago                 VARCHAR(200)  NULL,
        TipoCopago                    VARCHAR(200)  NULL,
        IdTipoCopago                  INT           NULL,
        TotalBono                     DECIMAL(18,2) NULL,
        MontoPagadoPrevision          DECIMAL(18,2) NULL,
        Monto                         DECIMAL(18,2) NULL,
        MontoCopago                   DECIMAL(18,2) NULL,
        FechaMovimiento               DATETIME      NULL,
        HoraMovimiento                DATETIME      NULL,
        IdCajero                      INT           NULL,
        IdUsuarioCajero               INT           NULL,
        Cajero                        VARCHAR(200)  NULL,
        IdCicloCaja                   INT           NULL,
        FechaEmision                  DATETIME      NULL,
        FechaApertura                 DATETIME      NULL,
        IdTipoEstadoMovimientoCaja    INT           NULL,
        TipoEstadoMovimientoCaja      VARCHAR(200)  NULL,
        IdPaciente                    INT           NULL,
        Rut                           VARCHAR(20)   NULL,
        OrigenBono                    VARCHAR(100)  NULL,
        NombrePaciente                VARCHAR(400)  NULL,
        SistemaSalud                  VARCHAR(200)  NULL,
        Isapre                        VARCHAR(200)  NULL,
        FechaCierre                   DATETIME      NULL,
        IdTipoEstadoCaja              INT           NULL,
        IdCita                        INT           NULL,
        Comentario                    VARCHAR(10)   NULL,
        CodigoXml                     VARCHAR(10)   NULL,
        IdProfesional                 INT           NULL,
        IdTipoPrestacion              INT           NULL,
        TipoPrestacion                VARCHAR(200)  NULL,
        MtoBonAdic                    DECIMAL(18,2) NULL,
        Excedentes                    DECIMAL(18,2) NULL,
        Aprobado                      VARCHAR(2)    NULL,
        RutProfesional                VARCHAR(20)   NULL,
        NombreProfesional             VARCHAR(400)  NULL,
        IdProfesionalOrden            INT           NULL,
        RutProfesionalOrden           VARCHAR(20)   NULL,
        NombreProfesionalOrden        VARCHAR(400)  NULL,
        IdPresupuesto                 INT           NULL
    )

    INSERT INTO #Resultado
    SELECT TOP (ISNULL(@Top, 2147483647))
        bd.IdMovimientoCaja,
        CASE WHEN bd.IdPresupuesto IS NOT NULL
             THEN 'P-' + CAST(bd.IdPresupuesto AS VARCHAR)
             ELSE 'C-' + CAST(bd.IdCita AS VARCHAR)
        END AS Identificador,
        CASE WHEN f.TipoFila = 2 THEN ''
             ELSE ISNULL(NULLIF(bd.NroTransaccionTBK, '0'), '')
        END AS NroTransaccionTBK,
        CASE WHEN f.TipoFila IN (1, 3) THEN ISNULL(bd.NroBoleta, '')
             ELSE ''
        END AS NroBoleta,
        CASE WHEN f.TipoFila = 1 THEN
                  CASE WHEN ISNULL(bd.NroTransaccionTBK, '0') = '0' OR bd.NroTransaccionTBK = ''
                       THEN ISNULL(bd.NroBoleta, '')
                       ELSE bd.NroTransaccionTBK
                  END
             WHEN f.TipoFila = 2 THEN ''
             WHEN f.TipoFila = 3 THEN
                  CASE WHEN ISNULL(bd.NroTransaccionTBK, '0') = '0' OR bd.NroTransaccionTBK = ''
                       THEN ISNULL(bd.NroBoleta, '')
                       ELSE bd.NroTransaccionTBK
                  END
        END AS NroTransaccionTBKBoleta,
        CASE WHEN f.TipoFila = 1 THEN
                  CASE WHEN bd.OrigenBono = 'Imed'
                       THEN ISNULL(bd.FoliosConcatenados, '')
                       ELSE ISNULL(bd.NroBono, '')
                  END
             WHEN f.TipoFila = 2 THEN ISNULL(bd.NroBono, '')
             WHEN f.TipoFila = 3 THEN ''
        END AS NroBono,
        bd.IdCaja,
        bd.Caja,
        CASE WHEN f.TipoFila = 1 THEN
                  CASE WHEN bd.IdTipoPrestacion = @TIPO_PRESTACION_PROCEDIMIENTO AND bd.ModalidadPagoDesc = 'Copago' THEN 'Particular'
                       WHEN bd.OrigenBono IS NULL AND bd.IdTipoModalidadPago = 3 THEN 'Particular'
                       ELSE bd.ModalidadPagoDesc
                  END
             WHEN f.TipoFila = 2 THEN 'Bono'
             WHEN f.TipoFila = 3 THEN bd.ModalidadPagoDesc
        END AS ModalidadPago,
        CASE WHEN f.TipoFila IN (1, 3) THEN bd.TipoCopagoDesc
             ELSE NULL
        END AS TipoCopago,
        CASE WHEN f.TipoFila IN (1, 3) THEN bd.IdTipoCopago
             ELSE NULL
        END AS IdTipoCopago,
        CASE WHEN f.TipoFila = 1 THEN
                  CASE WHEN bd.IdPresupuesto IS NOT NULL AND bd.Monto > 0 THEN bd.TotalBono
                       WHEN bd.OrigenBono IS NULL AND bd.IdTipoModalidadPago = 3 AND bd.MontoCopago > 0 THEN bd.TotalBono
                       WHEN bd.IdTipoCopago IS NOT NULL AND bd.Monto > 0 THEN 0
                       ELSE bd.TotalBono
                  END
             WHEN f.TipoFila = 2 THEN bd.TotalBono
             WHEN f.TipoFila = 3 THEN bd.Monto
        END AS TotalBono,
        CASE WHEN f.TipoFila = 3 THEN 0
             ELSE bd.MontoPagadoPrevision
        END AS MontoPagadoPrevision,
        CASE WHEN f.TipoFila = 1 THEN bd.Monto
             WHEN f.TipoFila = 2 THEN 0
             WHEN f.TipoFila = 3 THEN bd.Monto
        END AS Monto,
        CASE WHEN f.TipoFila = 1 THEN bd.MontoCopago
             WHEN f.TipoFila = 2 THEN bd.Monto
             WHEN f.TipoFila = 3 THEN 0
        END AS MontoCopago,
        bd.FechaMovimiento,
        bd.FechaMovimiento AS HoraMovimiento,
        bd.IdUsuarioCajero AS IdCajero,
        bd.IdUsuarioCajero,
        bd.Cajero,
        bd.IdCicloCaja,
        CASE WHEN f.TipoFila = 3 THEN NULL
             ELSE bd.FechaEmision
        END AS FechaEmision,
        bd.FechaApertura,
        bd.IdTipoEstadoMovimientoCaja,
        bd.TipoEstadoMovimientoCajaDesc AS TipoEstadoMovimientoCaja,
        bd.IdPaciente,
        bd.RutPaciente AS Rut,
        CASE WHEN f.TipoFila = 1 THEN
                  CASE WHEN bd.IdPresupuesto IS NOT NULL AND bd.Monto > 0 THEN 'Particular'
                       WHEN bd.OrigenBono IS NULL AND bd.IdTipoModalidadPago = 3 AND bd.MontoCopago > 0 THEN 'Particular'
                       WHEN bd.IdTipoCopago IS NOT NULL AND bd.Monto > 0 THEN 'Copago'
                       ELSE bd.OrigenBono
                  END
             ELSE bd.OrigenBono
        END AS OrigenBono,
        bd.NombrePaciente,
        bd.SistemaSaludDesc AS SistemaSalud,
        bd.IsapreDesc AS Isapre,
        bd.FechaCierre,
        bd.IdTipoEstadoCaja,
        bd.IdCita,
        '' AS Comentario,
        bd.CodigoXml,
        bd.IdProfesional,
        bd.IdTipoPrestacion,
        bd.TipoPrestacionDesc AS TipoPrestacion,
        CASE WHEN f.TipoFila = 1 THEN
                  CASE WHEN bd.OrigenBono != 'Imed' THEN bd.Seguros
                       ELSE ISNULL(bd.MtoBonAdicVw, 0)
                  END
             WHEN f.TipoFila = 2 THEN
                  CASE WHEN bd.Seguros = 0 THEN ISNULL(bd.MtoBonAdicVw, 0)
                       ELSE bd.Seguros
                  END
             WHEN f.TipoFila = 3 THEN 0
        END AS MtoBonAdic,
        CASE WHEN f.TipoFila = 3 THEN 0
             ELSE bd.Excendentes
        END AS Excedentes,
        CASE WHEN bd.Aprobado = 1 THEN 'Si' ELSE 'No' END AS Aprobado,
        CASE WHEN bd.IdTipoOrigenProfesional IN (0,1) THEN bd.RutProf
             ELSE ISNULL(bd.RutProfExt, bd.RutProfOri)
        END AS RutProfesional,
        CASE WHEN bd.IdTipoOrigenProfesional IN (0,1) THEN bd.NomProf + ' ' + bd.ApeProf
             ELSE ISNULL(bd.NomProfExt + ' ' + bd.ApeProfExt, bd.NomProfOri + ' ' + bd.ApeProfOri)
        END AS NombreProfesional,
        CASE WHEN bd.IdPresupuesto IS NOT NULL THEN bd.IdProfesionalPD
             WHEN bd.IdTipoPrestacion != @TIPO_PRESTACION_CONSULTA AND bd.IdProfExt IS NULL THEN bd.IdProfFicha
             WHEN bd.IdProfExt IS NOT NULL THEN bd.IdProfExt
             ELSE NULL
        END AS IdProfesionalOrden,
        CASE WHEN bd.IdPresupuesto IS NOT NULL THEN bd.RutProfesionalPD
             WHEN bd.IdTipoPrestacion != @TIPO_PRESTACION_CONSULTA AND bd.IdProfExt IS NULL THEN bd.RutProfFicha
             WHEN bd.IdProfExt IS NOT NULL THEN bd.RutProfExt
             ELSE '-'
        END AS RutProfesionalOrden,
        CASE WHEN bd.IdPresupuesto IS NOT NULL THEN ISNULL(bd.NomProfesionalPD + ' ' + bd.ApeProfesionalPD, '-')
             WHEN bd.IdTipoPrestacion != @TIPO_PRESTACION_CONSULTA AND bd.IdProfExt IS NULL THEN bd.NomProfFicha + ' ' + bd.ApeProfFicha
             WHEN bd.IdProfExt IS NOT NULL THEN bd.NomProfExt + ' ' + bd.ApeProfExt
             ELSE '-'
        END AS NombreProfesionalOrden,
        bd.IdPresupuesto
    FROM #BaseData bd
    CROSS APPLY (VALUES (1),(2),(3)) AS f(TipoFila)
    WHERE
        (f.TipoFila = 1 OR (f.TipoFila IN (2, 3) AND bd.TieneBonoConMonto = 1))
    ORDER BY bd.IdMovimientoCaja DESC

    -- Agregar insumos médicos adaptados (misma estructura que la vista original)
    INSERT INTO #Resultado
    SELECT * FROM Caja.VWMovimientoCajaInsumosMedicosAdaptado

    -- ============================================================
    -- SECCIÓN 6: Aplicar filtros sobre el resultado calculado
    -- ============================================================
    SELECT
        r.IdMovimientoCaja,
        r.Identificador,
        r.NroTransaccionTBK,
        r.NroBoleta,
        r.NroTransaccionTBKBoleta,
        r.NroBono,
        r.IdCaja,
        r.Caja,
        r.ModalidadPago,
        r.TipoCopago,
        r.IdTipoCopago,
        r.TotalBono,
        r.MontoPagadoPrevision,
        r.Monto,
        r.MontoCopago,
        r.FechaMovimiento,
        r.HoraMovimiento,
        r.IdCajero,
        r.IdUsuarioCajero,
        r.Cajero,
        r.IdCicloCaja,
        r.FechaEmision,
        r.FechaApertura,
        r.IdTipoEstadoMovimientoCaja,
        r.TipoEstadoMovimientoCaja,
        r.IdPaciente,
        r.Rut,
        r.OrigenBono,
        r.NombrePaciente,
        r.SistemaSalud,
        r.Isapre,
        r.FechaCierre,
        r.IdTipoEstadoCaja,
        r.IdCita,
        r.Comentario,
        r.CodigoXml,
        r.IdProfesional,
        r.IdTipoPrestacion,
        r.TipoPrestacion,
        r.MtoBonAdic,
        r.Excedentes,
        r.Aprobado,
        r.RutProfesional,
        r.NombreProfesional,
        r.IdProfesionalOrden,
        r.RutProfesionalOrden,
        r.NombreProfesionalOrden,
        r.IdPresupuesto
    FROM #Resultado r
    WHERE
        (@IdProfesionalOrden          IS NULL OR r.IdProfesionalOrden         = @IdProfesionalOrden)
        AND (@IdProfesional            IS NULL OR r.IdProfesional              = @IdProfesional)
        AND (
            (
                @IdTipoPrestacionMultiple = 1
                AND r.IdTipoPrestacion IN (@TIPO_PRESTACION_CONSULTA, @TIPO_PRESTACION_PROCEDIMIENTO)   -- CONSULTA=1, PROCEDIMIENTOS=4
            )
            OR (
                @IdTipoPrestacionMultiple = 0
                AND @IdTipoPrestacion IS NULL
            )
            OR (
                @IdTipoPrestacionMultiple = 0
                AND r.IdTipoPrestacion = @IdTipoPrestacion
            )
        )
        AND (@IdMovimientoCaja         IS NULL OR r.IdMovimientoCaja          = @IdMovimientoCaja)
        AND (@IdPaciente               IS NULL OR r.IdPaciente                = @IdPaciente)
        AND (@IdCicloCaja              IS NULL OR r.IdCicloCaja               = @IdCicloCaja)
        AND (@IdUsuarioCajero          IS NULL OR r.IdUsuarioCajero           = @IdUsuarioCajero)
        AND (@IdCaja                   IS NULL OR r.IdCaja                    = @IdCaja)
        AND (@IdTipoModalidadPago      IS NULL OR r.IdTipoCopago              = @IdTipoModalidadPago)
        AND (@IdTipoCopago             IS NULL OR r.IdTipoCopago              = @IdTipoCopago)
        AND (@Monto                    IS NULL OR r.Monto                     = @Monto)
        AND (@FechaMovimientoDesde     IS NULL OR r.FechaMovimiento          >= @FechaMovimientoDesde)
        AND (@FechaMovimientoHasta     IS NULL OR r.FechaMovimiento          <= @FechaMovimientoHasta)
        AND (@Excedentes               IS NULL OR r.Excedentes               = @Excedentes)
        AND (@FechaEmisionDesde        IS NULL OR r.FechaEmision             >= @FechaEmisionDesde)
        AND (@FechaEmisionHasta        IS NULL OR r.FechaEmision             <= @FechaEmisionHasta)
        AND (@MontoCopago              IS NULL OR r.MontoCopago              = @MontoCopago)
        AND (@MontoPagadoPrevision     IS NULL OR r.MontoPagadoPrevision     = @MontoPagadoPrevision)
        AND (@NroBono                  IS NULL OR r.NroBono                  LIKE '%' + @NroBono + '%')
        AND (@NroTransaccionTBK        IS NULL OR r.NroTransaccionTBK        LIKE '%' + @NroTransaccionTBK + '%')
        AND (@OrigenBono               IS NULL OR r.OrigenBono               LIKE '%' + @OrigenBono + '%')
        AND (@Seguros                  IS NULL OR CAST(r.MtoBonAdic AS VARCHAR) LIKE '%' + @Seguros + '%')
        AND (@SistemaSalud             IS NULL OR r.SistemaSalud             LIKE '%' + @SistemaSalud + '%')
        AND (@TotalBono                IS NULL OR r.TotalBono                = @TotalBono)
        -- Cheques, garantías y FechaRecepcion: columnas que existen en la tabla base
        -- pero no son proyectadas en la vista; se filtran si se agregan en #BaseData
        AND (@IdCita                   IS NULL OR r.IdCita                   = @IdCita)
        AND (@IdIsapre                 IS NULL OR r.Isapre                   IS NOT NULL)  -- se filtra por descripción; ver nota (*)
        AND (
            (
                @IdTipoEstadoMultiple = 1
                AND r.IdTipoEstadoMovimientoCaja IN (@TIPO_ESTADO_MOVCAJA_PAGADO, @TIPO_ESTADO_MOVCAJA_CONTROL_MEDICO)   -- Pagado=1, ControlMedico=2
            )
            OR (
                @IdTipoEstadoMultiple = 0
                AND @IdTipoEstadoMovimientoCaja IS NULL
            )
            OR (
                @IdTipoEstadoMultiple = 0
                AND r.IdTipoEstadoMovimientoCaja = @IdTipoEstadoMovimientoCaja
            )
        )
    ORDER BY r.IdMovimientoCaja DESC

    -- Limpiar temporales
    DROP TABLE IF EXISTS #ImedFolios
    DROP TABLE IF EXISTS #CitaEvolucion
    DROP TABLE IF EXISTS #ProfPresupuesto
    DROP TABLE IF EXISTS #BaseData
    DROP TABLE IF EXISTS #Resultado
END
