

-- ============================================================

-- SP_PrestacionesParticular (v2)

-- Consultas (IdPrestacion=1): una fila por MovimientoCaja,

--   TipoCopago del propio registro.

-- Exámenes/Imágenes (IdTipoPrestacion!=1): una fila por

--   prestación de cfee, TipoCopago = STRING_AGG de todos los

--   pagos de esa cita, Valor = ValorAmbulatorioParticularHabil.

-- ============================================================

CREATE PROCEDURE [Clinica].[SP_PrestacionesParticular]

    @FechaDesde          DATETIME,

    @FechaHasta          DATETIME,

    @IdProfesional       INT = NULL,

    @IdProfesionalOrden  INT = NULL,

    @IdTipoPrestacion    VARCHAR(100) = NULL,

    @IdCaja              INT = NULL

AS

BEGIN

    SET NOCOUNT ON;



    -- ════════════════════════════════════════════════════════

    -- Bloque 1: Consultas (IdTipoPrestacion = 1)

    -- Una fila por cita — suma montos de multipago, concatena TipoCopago.

    -- ════════════════════════════════════════════════════════

    SELECT

        MIN(mc.IdMovimientoCaja) AS IdMovimientoCaja,

        CONVERT(VARCHAR,'C-'+CONVERT(VARCHAR,mc.IdCita)) AS Identificador,

        cc.IdCaja,

        caja.Descripcion AS Caja,

        ec.IdTipoEstadoCaja,

        ec.Descripcion AS TipoEstadoCaja,

        '' AS RutCajero,

        usuario.LoginName AS NombreCajero,

        MIN(mc.FechaMovimiento) AS FechaMovimiento,

        FORMAT(MIN(mc.FechaMovimiento),'HH:mm') AS HoraMovimiento,

        CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.IdProfesional

             ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN cita.IdProfesionalExterno ELSE profesionalOrigen.IdProfesional END

        END AS IdProfesional,

        CASE

            WHEN MIN(CASE WHEN mc.OrigenBono = 'Interno' THEN 1 ELSE 0 END) = 1 THEN 'Costo $0'

            WHEN MIN(CASE WHEN mc.OrigenBono = 'Costo $0' THEN 1 ELSE 0 END) = 1 THEN 'Costo $0'

            ELSE tmp.Descripcion

        END AS OrigenBono,

        CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.Rut

             ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN profesionalExterno.Rut ELSE profesionalOrigen.Rut END

        END AS RutProfesional,

        CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.Nombres+' '+profesional.Apellidos

             ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN profesionalExterno.Nombres+' '+profesionalExterno.Apellidos ELSE profesionalOrigen.Nombres+' '+profesionalOrigen.Apellidos END

        END AS NombreProfesional,

        CASE WHEN prestacion.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

             WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

        END AS IdProfesionalOrden_Potencial,

        CASE WHEN (

            CASE WHEN prestacion.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

                 WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

            END

            =

            CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.IdProfesional

                 ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN cita.IdProfesionalExterno ELSE profesionalOrigen.IdProfesional END

            END

        ) THEN NULL

        ELSE

            CASE WHEN prestacion.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

                 WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

            END

        END AS IdProfesionalOrden,

        CASE WHEN (

            CASE WHEN prestacion.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

                 WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

            END

            =

            CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.IdProfesional

                 ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN cita.IdProfesionalExterno ELSE profesionalOrigen.IdProfesional END

            END

        ) THEN '-'

        ELSE COALESCE(profesionalExterno.Rut, profesionalFicha.Rut, '-')

        END AS RutProfesionalOrden,

        CASE WHEN (

            CASE WHEN prestacion.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

                 WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

            END

            =

            CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.IdProfesional

                 ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN cita.IdProfesionalExterno ELSE profesionalOrigen.IdProfesional END

            END

        ) THEN '-'

        ELSE COALESCE(profesionalExterno.Nombres+' '+profesionalExterno.Apellidos, profesionalFicha.Nombres+' '+profesionalFicha.Apellidos, '-')

        END AS NombreProfesionalOrden,

        paciente.Rut AS RutPaciente,

        paciente.Nombres+' '+paciente.Apellidos AS NombrePaciente,

        prestacion.CodigoInterno AS CodigoPrestacion,

        prestacion.Descripcion AS NombrePrestacion,

        tp.IdTipoPrestacion,

        tp.Descripcion AS TipoPrestacion,

        tmp.Descripcion AS Modalidad,

        sistemaSalud.Descripcion AS SistemaSalud,

        isapre.Descripcion AS Isapre,

        NULL AS NroBono,

        FORMAT(MIN(mc.FechaEmision),'dd-MM-yyyy') AS FechaEmision,

        FORMAT(MIN(mc.FechaRecepcion),'dd-MM-yyyy') AS FechaRecepcion,

        SUM(mc.Monto) AS Valor,

        0 AS MontoPagadoPrevision,

        SUM(mc.Monto) AS MontoCopago,

        0 AS SeguroComplementario,

        0 AS Excedentes,

        SUM(mc.Monto) AS TotalPagado,

        CASE WHEN COUNT(DISTINCT mc.IdTipoCopago) = 1 THEN MIN(mc.IdTipoCopago) ELSE NULL END AS IdTipoCopago,

        (

            SELECT STRING_AGG(tc_sub.Descripcion, ' / ') WITHIN GROUP (ORDER BY tc_sub.Descripcion)

            FROM (

                SELECT DISTINCT tc4.Descripcion

                FROM Caja.MovimientoCaja mc4

                JOIN Caja.TipoCopago tc4 ON tc4.IdTipoCopago = mc4.IdTipoCopago

                WHERE mc4.IdCita = mc.IdCita

                  AND mc4.IdTipoEstadoMovimientoCaja IN (1, 3)

                  AND (mc4.OrigenBono IS NULL OR mc4.OrigenBono = '' OR mc4.OrigenBono = 'Interno' OR mc4.OrigenBono = 'Costo $0')

            ) tc_sub

        ) AS TipoCopago

    FROM Caja.MovimientoCaja mc

    JOIN Caja.CicloCaja cc ON cc.IdCicloCaja = mc.IdCicloCaja

    JOIN Core.Usuario usuario ON usuario.IdUsuario = cc.IdUsuarioCajero

    JOIN Caja.Caja caja ON caja.IdCaja = mc.IdCaja

    JOIN Caja.TipoEstadoCaja ec ON caja.IdTipoEstadoCaja = ec.IdTipoEstadoCaja

    JOIN Clinica.Cita cita ON cita.IdCita = mc.IdCita

    JOIN Clinica.Profesional profesional ON profesional.IdProfesional = cita.IdProfesional

    JOIN Clinica.Paciente paciente ON paciente.IdPaciente = cita.IdPaciente

    JOIN Clinica.Prestacion prestacion ON prestacion.IdPrestacion = cita.IdPrestacion

    JOIN Clinica.TipoPrestacion tp ON tp.IdTipoPrestacion = prestacion.IdTipoPrestacion

    JOIN Caja.TipoModalidadPago tmp ON tmp.IdTipoModalidadPago = mc.IdTipoModalidadPago

    LEFT JOIN Clinica.SistemaSalud sistemaSalud ON sistemaSalud.IdSistemaSalud = mc.SistemaSalud

    LEFT JOIN Clinica.Isapre isapre ON isapre.IdIsapre = mc.IdIsapre

    OUTER APPLY (

        SELECT TOP 1 fe3.IdProfesional AS IdProfFicha

        FROM Clinica.CitaFichaEvolucionExamen cfee3

        JOIN Ficha.FichaEvolucion fe3 ON fe3.IdFichaEvolucion = cfee3.IdFichaEvolucion

        WHERE cfee3.IdCita = cita.IdCita

        ORDER BY cfee3.IdCitaFichaEvolucionExamen

    ) fichaOrden

    LEFT JOIN Clinica.Profesional profesionalFicha ON profesionalFicha.IdProfesional = fichaOrden.IdProfFicha

    LEFT JOIN Clinica.Profesional profesionalOrigen ON profesionalOrigen.IdProfesional = (

        SELECT TOP 1 fe2.IdProfesional FROM Ficha.FichaEvolucion fe2

        JOIN Clinica.CitaFichaEvolucionExamen cfee2 ON cfee2.IdFichaEvolucion = fe2.IdFichaEvolucion

        WHERE cfee2.IdCita = cita.IdCita

    )

    LEFT JOIN Clinica.Profesional profesionalExterno ON profesionalExterno.IdProfesional = cita.IdProfesionalExterno

    WHERE prestacion.IdTipoPrestacion = 1

      AND (mc.OrigenBono IS NULL OR mc.OrigenBono = '' OR mc.OrigenBono = 'Interno' OR mc.OrigenBono = 'Costo $0')

      AND mc.IdTipoEstadoMovimientoCaja IN (1, 3)

      AND CAST(mc.FechaMovimiento AS DATE) BETWEEN CAST(@FechaDesde AS DATE) AND CAST(@FechaHasta AS DATE)

      AND mc.IdPresupuesto IS NULL

      AND NOT EXISTS (

          SELECT 1 FROM Caja.MovimientoCaja mc2

          WHERE mc2.IdCita = mc.IdCita

            AND mc2.IdTipoEstadoMovimientoCaja IN (1, 3)

            AND mc2.IdMovimientoCaja != mc.IdMovimientoCaja

            AND (

                (mc2.OrigenBono IS NOT NULL AND mc2.OrigenBono NOT IN ('', 'Interno', 'Copago'))

                OR mc2.OrigenBono = 'Imed'

            )

      )

    GROUP BY

        mc.IdCita,

        cc.IdCaja,

        caja.Descripcion,

        ec.IdTipoEstadoCaja,

        ec.Descripcion,

        usuario.LoginName,

        tmp.Descripcion,

        sistemaSalud.Descripcion,

        isapre.Descripcion,

        profesional.IdTipoOrigenProfesional,

        profesional.IdProfesional,

        profesional.Rut,

        profesional.Nombres,

        profesional.Apellidos,

        cita.IdProfesionalExterno,

        profesionalOrigen.IdProfesional,

        profesionalOrigen.Rut,

        profesionalOrigen.Nombres,

        profesionalOrigen.Apellidos,

        profesionalExterno.IdProfesional,

        profesionalExterno.Rut,

        profesionalExterno.Nombres,

        profesionalExterno.Apellidos,

        profesionalFicha.IdProfesional,

        profesionalFicha.Rut,

        profesionalFicha.Nombres,

        profesionalFicha.Apellidos,

        paciente.Rut,

        paciente.Nombres,

        paciente.Apellidos,

        prestacion.CodigoInterno,

        prestacion.Descripcion,

        prestacion.IdTipoPrestacion,

        tp.IdTipoPrestacion,

        tp.Descripcion

    HAVING

        (@IdProfesional IS NULL OR

            CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.IdProfesional

                 ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN cita.IdProfesionalExterno ELSE profesionalOrigen.IdProfesional END

            END = @IdProfesional)

        AND (@IdTipoPrestacion IS NULL OR tp.IdTipoPrestacion IN (SELECT CAST(value AS INT) FROM STRING_SPLIT(@IdTipoPrestacion, ',')))

        AND (@IdCaja IS NULL OR cc.IdCaja = @IdCaja)

        AND (@IdProfesionalOrden IS NULL OR

            CASE WHEN (

                CASE WHEN prestacion.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

                     WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

                END

                =

                CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.IdProfesional

                     ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN cita.IdProfesionalExterno ELSE profesionalOrigen.IdProfesional END

                END

            ) THEN NULL

            ELSE

                CASE WHEN prestacion.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

                     WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

                END

            END = @IdProfesionalOrden)



    UNION ALL



    -- ════════════════════════════════════════════════════════

    -- Bloque 2: Exámenes / Imágenes (IdTipoPrestacion != 1)

    -- Una fila por (IdCita, cfee.IdCitaFichaEvolucionExamen).

    -- TipoCopago = STRING_AGG de todos los pagos de la cita.

    -- Valor = ValorAmbulatorioParticularHabil de la prestación.

    -- ════════════════════════════════════════════════════════

    SELECT

        -- Usar el IdMovimientoCaja más bajo de la cita como representante

        MIN(mc.IdMovimientoCaja) AS IdMovimientoCaja,

        CONVERT(VARCHAR,'C-'+CONVERT(VARCHAR,mc.IdCita)) AS Identificador,

        cc.IdCaja,

        caja.Descripcion AS Caja,

        ec.IdTipoEstadoCaja,

        ec.Descripcion AS TipoEstadoCaja,

        '' AS RutCajero,

        usuario.LoginName AS NombreCajero,

        MIN(mc.FechaMovimiento) AS FechaMovimiento,

        FORMAT(MIN(mc.FechaMovimiento),'HH:mm') AS HoraMovimiento,

        CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.IdProfesional

             ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN cita.IdProfesionalExterno ELSE profesionalOrigen.IdProfesional END

        END AS IdProfesional,

        CASE

            WHEN MIN(CASE WHEN mc.OrigenBono = 'Interno' THEN 1 ELSE 0 END) = 1 THEN 'Costo $0'

            WHEN MIN(CASE WHEN mc.OrigenBono = 'Costo $0' THEN 1 ELSE 0 END) = 1 THEN 'Costo $0'

            ELSE tmp.Descripcion

        END AS OrigenBono,

        CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.Rut

             ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN profesionalExterno.Rut ELSE profesionalOrigen.Rut END

        END AS RutProfesional,

        CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.Nombres+' '+profesional.Apellidos

             ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN profesionalExterno.Nombres+' '+profesionalExterno.Apellidos ELSE profesionalOrigen.Nombres+' '+profesionalOrigen.Apellidos END

        END AS NombreProfesional,

        CASE WHEN prestacionExamen.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

             WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

        END AS IdProfesionalOrden_Potencial,

        CASE WHEN (

            CASE WHEN prestacionExamen.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

                 WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

            END

            =

            CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.IdProfesional

                 ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN cita.IdProfesionalExterno ELSE profesionalOrigen.IdProfesional END

            END

        ) THEN NULL

        ELSE

            CASE WHEN prestacionExamen.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

                 WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

            END

        END AS IdProfesionalOrden,

        CASE WHEN (

            CASE WHEN prestacionExamen.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

                 WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

            END

            =

            CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.IdProfesional

                 ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN cita.IdProfesionalExterno ELSE profesionalOrigen.IdProfesional END

            END

        ) THEN '-'

        ELSE COALESCE(profesionalExterno.Rut, profesionalFicha.Rut, '-')

        END AS RutProfesionalOrden,

        CASE WHEN (

            CASE WHEN prestacionExamen.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

                 WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

            END

            =

            CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.IdProfesional

                 ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN cita.IdProfesionalExterno ELSE profesionalOrigen.IdProfesional END

            END

        ) THEN '-'

        ELSE COALESCE(profesionalExterno.Nombres+' '+profesionalExterno.Apellidos, profesionalFicha.Nombres+' '+profesionalFicha.Apellidos, '-')

        END AS NombreProfesionalOrden,

        paciente.Rut AS RutPaciente,

        paciente.Nombres+' '+paciente.Apellidos AS NombrePaciente,

        prestacionExamen.CodigoInterno AS CodigoPrestacion,

        prestacionExamen.Descripcion AS NombrePrestacion,

        tpExamen.IdTipoPrestacion,

        tpExamen.Descripcion AS TipoPrestacion,

        tmp.Descripcion AS Modalidad,

        sistemaSalud.Descripcion AS SistemaSalud,

        isapre.Descripcion AS Isapre,

        NULL AS NroBono,

        FORMAT(MIN(mc.FechaEmision),'dd-MM-yyyy') AS FechaEmision,

        FORMAT(MIN(mc.FechaRecepcion),'dd-MM-yyyy') AS FechaRecepcion,

        prestacionExamen.ValorAmbulatorioParticularHabil AS Valor,

        0 AS MontoPagadoPrevision,

        prestacionExamen.ValorAmbulatorioParticularHabil AS MontoCopago,

        0 AS SeguroComplementario,

        0 AS Excedentes,

        prestacionExamen.ValorAmbulatorioParticularHabil AS TotalPagado,

        -- IdTipoCopago: valor único si solo hay un tipo; NULL si hay múltiples

        CASE WHEN COUNT(DISTINCT mc.IdTipoCopago) = 1 THEN MIN(mc.IdTipoCopago) ELSE NULL END AS IdTipoCopago,

        -- TipoCopago: subquery correlacionado evita multiplicación por cfee × mc

        (

            SELECT STRING_AGG(tc_sub.Descripcion, ' / ') WITHIN GROUP (ORDER BY tc_sub.Descripcion)

            FROM (

                SELECT DISTINCT tc4.Descripcion

                FROM Caja.MovimientoCaja mc4

                JOIN Caja.TipoCopago tc4 ON tc4.IdTipoCopago = mc4.IdTipoCopago

                WHERE mc4.IdCita = mc.IdCita

                  AND mc4.IdTipoEstadoMovimientoCaja IN (1, 3)

                  AND (mc4.OrigenBono IS NULL OR mc4.OrigenBono = '' OR mc4.OrigenBono = 'Interno' OR mc4.OrigenBono = 'Costo $0')

            ) tc_sub

        ) AS TipoCopago

    FROM Caja.MovimientoCaja mc

    JOIN Caja.CicloCaja cc ON cc.IdCicloCaja = mc.IdCicloCaja

    JOIN Core.Usuario usuario ON usuario.IdUsuario = cc.IdUsuarioCajero

    JOIN Caja.Caja caja ON caja.IdCaja = mc.IdCaja

    JOIN Caja.TipoEstadoCaja ec ON caja.IdTipoEstadoCaja = ec.IdTipoEstadoCaja

    JOIN Clinica.Cita cita ON cita.IdCita = mc.IdCita

    JOIN Clinica.Profesional profesional ON profesional.IdProfesional = cita.IdProfesional

    JOIN Clinica.Paciente paciente ON paciente.IdPaciente = cita.IdPaciente

    JOIN Clinica.Prestacion prestacionCita ON prestacionCita.IdPrestacion = cita.IdPrestacion

    JOIN Caja.TipoModalidadPago tmp ON tmp.IdTipoModalidadPago = mc.IdTipoModalidadPago

    -- cfee: una fila por examen/imagen de la cita

    JOIN Clinica.CitaFichaEvolucionExamen cfee ON cfee.IdCita = cita.IdCita

    JOIN Clinica.Prestacion prestacionExamen ON prestacionExamen.IdPrestacion = cfee.IdPrestacion

    JOIN Clinica.TipoPrestacion tpExamen ON tpExamen.IdTipoPrestacion = prestacionExamen.IdTipoPrestacion

    LEFT JOIN Ficha.FichaEvolucion fe ON fe.IdFichaEvolucion = cfee.IdFichaEvolucion

    LEFT JOIN Clinica.Profesional profesionalFicha ON profesionalFicha.IdProfesional = fe.IdProfesional

    LEFT JOIN Clinica.SistemaSalud sistemaSalud ON sistemaSalud.IdSistemaSalud = mc.SistemaSalud

    LEFT JOIN Clinica.Isapre isapre ON isapre.IdIsapre = mc.IdIsapre

    LEFT JOIN Clinica.Profesional profesionalOrigen ON profesionalOrigen.IdProfesional = (

        SELECT TOP 1 fe2.IdProfesional FROM Ficha.FichaEvolucion fe2

        JOIN Clinica.CitaFichaEvolucionExamen cfee2 ON cfee2.IdFichaEvolucion = fe2.IdFichaEvolucion

        WHERE cfee2.IdCita = cita.IdCita

    )

    LEFT JOIN Clinica.Profesional profesionalExterno ON profesionalExterno.IdProfesional = cita.IdProfesionalExterno

    WHERE prestacionCita.IdTipoPrestacion != 1

      AND tpExamen.IdTipoPrestacion != 1

      AND (mc.OrigenBono IS NULL OR mc.OrigenBono = '' OR mc.OrigenBono = 'Interno' OR mc.OrigenBono = 'Costo $0')

      AND mc.IdTipoEstadoMovimientoCaja IN (1, 3)

      AND CAST(mc.FechaMovimiento AS DATE) BETWEEN CAST(@FechaDesde AS DATE) AND CAST(@FechaHasta AS DATE)

      AND mc.IdPresupuesto IS NULL

      AND NOT EXISTS (

          SELECT 1 FROM Caja.MovimientoCaja mc2

          WHERE mc2.IdCita = mc.IdCita

            AND mc2.IdTipoEstadoMovimientoCaja IN (1, 3)

            AND mc2.IdMovimientoCaja != mc.IdMovimientoCaja

            AND (

                (mc2.OrigenBono IS NOT NULL AND mc2.OrigenBono NOT IN ('', 'Interno', 'Copago'))

                OR mc2.OrigenBono = 'Imed'

            )

      )

    GROUP BY

        mc.IdCita,

        cfee.IdCitaFichaEvolucionExamen,

        prestacionExamen.IdPrestacion,

        prestacionExamen.CodigoInterno,

        prestacionExamen.Descripcion,

        prestacionExamen.ValorAmbulatorioParticularHabil,

        tpExamen.IdTipoPrestacion,

        tpExamen.Descripcion,

        cc.IdCaja,

        caja.Descripcion,

        ec.IdTipoEstadoCaja,

        ec.Descripcion,

        usuario.LoginName,

        tmp.Descripcion,

        sistemaSalud.Descripcion,

        isapre.Descripcion,

        profesional.IdTipoOrigenProfesional,

        profesional.IdProfesional,

        profesional.Rut,

        profesional.Nombres,

        profesional.Apellidos,

        cita.IdProfesionalExterno,

        profesionalOrigen.IdProfesional,

        profesionalOrigen.Rut,

        profesionalOrigen.Nombres,

        profesionalOrigen.Apellidos,

        profesionalExterno.IdProfesional,

        profesionalExterno.Rut,

        profesionalExterno.Nombres,

        profesionalExterno.Apellidos,

        profesionalFicha.IdProfesional,

        profesionalFicha.Rut,

        profesionalFicha.Nombres,

        profesionalFicha.Apellidos,

        paciente.Rut,

        paciente.Nombres,

        paciente.Apellidos,

        prestacionExamen.IdTipoPrestacion

    HAVING

        (@IdProfesional IS NULL OR

            CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.IdProfesional

                 ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN cita.IdProfesionalExterno ELSE profesionalOrigen.IdProfesional END

            END = @IdProfesional)

        AND (@IdTipoPrestacion IS NULL OR tpExamen.IdTipoPrestacion IN (SELECT CAST(value AS INT) FROM STRING_SPLIT(@IdTipoPrestacion, ',')))

        AND (@IdCaja IS NULL OR cc.IdCaja = @IdCaja)

        AND (@IdProfesionalOrden IS NULL OR

            CASE WHEN (

                CASE WHEN prestacionExamen.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

                     WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

                END

                =

                CASE WHEN profesional.IdTipoOrigenProfesional != 2 THEN profesional.IdProfesional

                     ELSE CASE WHEN cita.IdProfesionalExterno IS NOT NULL THEN cita.IdProfesionalExterno ELSE profesionalOrigen.IdProfesional END

                END

            ) THEN NULL

            ELSE

                CASE WHEN prestacionExamen.IdTipoPrestacion != 1 AND profesionalExterno.IdProfesional IS NULL THEN profesionalFicha.IdProfesional

                     WHEN profesionalExterno.IdProfesional IS NOT NULL THEN profesionalExterno.IdProfesional ELSE NULL

                END

            END = @IdProfesionalOrden);



END

