WITH saldo_conta AS (

    WITH saldo AS (

        SELECT
            mf.data_movimento,
            cf.codigo,
            cf.denominacao,
            (SELECT id_empresa FROM sis_parametro_empresa WHERE id_parametro = 'sistema.id_pessoa_empresa' AND valor_numerico = cf.id_pessoa_conta) AS id_empresa,
            SUM(mf.valor_movimento * (POSITION(CAST('1' AS CHAR) IN CAST(tmf.entrada_saida AS CHAR(1))) * 2 - 1)) AS saldo_disponivel
        FROM	movimento_financeiro AS mf
            INNER JOIN tipo_movimento_financeiro AS tmf ON (tmf.id_tipo_movimento_financeiro = mf.id_tipo_movimento_financeiro)
            INNER JOIN conta_financeira AS cf ON (cf.id_conta_financeira = mf.id_conta_financeira)

        WHERE	mf.data_movimento <= :DataFinal
        AND cf.id_conta_financeira IN (:IdContaFinanceiraPessoa)
        AND cf.id_pessoa_conta IN (SELECT COALESCE(valor_numerico, 0)
                                    FROM sis_parametro_empresa 
                                    WHERE id_parametro = 'sistema.id_pessoa_empresa' 
                                    AND id_empresa IN (:IdEmpresaMultSlc))
        GROUP BY  mf.data_movimento, cf.codigo, cf.denominacao, cf.id_pessoa_conta

    )
    
    SELECT
        'MES' AS tipo,
        se.nome AS nome_empresa,
        r.id_empresa,
        r.denominacao,
        SUM(r.saldo_disponivel) AS saldo_disponivel
    FROM	saldo AS r
    INNER JOIN sis_empresa AS se ON se.id_empresa = r.id_empresa
    GROUP BY se.nome, r.id_empresa, r.denominacao

    UNION ALL

    SELECT
        'MES_ANTERIOR' AS tipo,
        se.nome AS nome_empresa,
        r.id_empresa,
        r.denominacao,
        SUM(r.saldo_disponivel) AS saldo_disponivel
    FROM	saldo AS r
    INNER JOIN sis_empresa AS se ON se.id_empresa = r.id_empresa
    WHERE	r.data_movimento <= date_trunc('month',CAST(:DataFinal AS DATE)) - INTERVAL'1 day'
    GROUP BY se.nome, r.id_empresa, r.denominacao

    
    ORDER BY nome_empresa
),

mes AS (
    SELECT :DataFinal::DATE AS data
),

mes_anterior AS (
    SELECT date_trunc('month',CAST(:DataFinal AS DATE)) - INTERVAL'1 day' AS data
)

/*MES*/
SELECT 
    mes.data AS cabecalho,
    nome_empresa,
    denominacao,
    'Saldo Disponível em Conta' AS dado,
    saldo_disponivel AS valor
FROM saldo_conta, mes WHERE tipo = 'MES'

UNION ALL

/*MES ANTERIOR*/
SELECT 
    mes_anterior.data AS cabecalho,
    nome_empresa,
    denominacao,
    'Saldo Disponível em Conta' AS dado,
    saldo_disponivel AS valor
FROM saldo_conta, mes_anterior WHERE tipo = 'MES_ANTERIOR'

ORDER BY nome_empresa ASC, cabecalho DESC, denominacao ASC