WITH titulo_financeiro AS (

    WITH titulo_mes AS (

        WITH tmp_titulo_financeiro AS (

            SELECT
                p.codigo AS codigo_credor_devedor,
                p.nome AS credor_devedor,
                tf.data_emissao,
                tf.data_vencimento,
                tf.numero_titulo,
                tf.data_liquidacao,
                tf.valor_titulo AS valor_principal,
                (tf.acrescimo_financeiro + tf.juros_cobranca + tf.multa_cobranca) AS total_acrescimo,
                (tf.desconto_financeiro + tf.desconto_cobranca + tf.retencao_tributaria + tf.valor_taxa_administracao + tf.tarifa_transacao) AS total_desconto,
                se.nome AS nome_empresa, 
                tf.id_titulo_financeiro,
                tf.pagar_receber, -- 1 - Pagar, 2 - Receber
                tf.natureza_titulo as codigo_natureza_titulo,
                tf.tipo_titulo,
                tf.situacao,
                ovl1.titulo AS natureza_titulo,
                CASE WHEN tf.valor_liquidado > 0 THEN tf.valor_liquidado ELSE
                (tf.valor_titulo
                - (tf.desconto_financeiro + tf.desconto_cobranca + tf.retencao_tributaria + tf.valor_taxa_administracao + tf.tarifa_transacao)
                + (tf.acrescimo_financeiro + tf.juros_cobranca + tf.multa_cobranca)) END AS valor_titulo
            FROM titulo_financeiro AS tf 
            INNER JOIN sis_empresa AS se ON se.id_empresa = tf.id_empresa
            LEFT JOIN pessoa AS p ON (tf.id_credor_devedor = p.id_pessoa)
            LEFT JOIN sis_opcao_lista_valor AS ovl1 ON (ovl1.id = tf.natureza_titulo AND ovl1.id_lista_valor = 'C043EFC0EDD5414995003170978F8878')

            WHERE tf.id_empresa IN (:IdEmpresaMultSlc) 
            AND CASE 
                WHEN tf.pagar_receber = 1 AND tf.natureza_titulo IN (101, 106, 116, 109, 114, 222)  THEN tf.data_emissao <= :DataFinal AND (tf.situacao IN (1, 9) OR tf.data_liquidacao > :DataFinal)
                WHEN tf.pagar_receber = 2 AND tf.natureza_titulo IN (201, 202, 203, 204, 205, 206, 209, 220, 221) AND tf.tipo_titulo = 1 THEN tf.data_emissao <= :DataFinal AND (tf.situacao IN (1, 9) OR tf.data_liquidacao > :DataFinal)      
            END 
            ORDER BY tf.pagar_receber,  tf.id_titulo_financeiro
            /*
                101 - Compra a Prazo
                106 - Adiantamento de Clientes
                109 - Despesas
                114 - Ticket
                116 - Conhecimento Frete
                201 - Venda a Prazo
                202 - Cartão de Crédito
                203 - Cartão de Débito
                204 - Cheque a Vista
                205 - Cheque Pré-Datado
                206 - Adiantamento a Fornecedores
                209 - Receitas
                220 - Vale Motorista
                221 - Fatura Global
                222 - Pagamento Antecipado
            */
        )
        
        SELECT 
            1 AS orderby,
            nome_empresa,
            array_agg(numero_titulo) AS numero_titulo,
            codigo_credor_devedor,
            credor_devedor,
            data_emissao,
            data_liquidacao,
            natureza_titulo,
            CASE WHEN pagar_receber = 2 THEN 'Título a Receber' ELSE 'Título a Pagar' END AS natureza,
            SUM(valor_principal) AS valor_principal,
            SUM(valor_titulo) AS valor_titulo
        FROM tmp_titulo_financeiro 
        GROUP BY nome_empresa, codigo_credor_devedor, credor_devedor, pagar_receber, data_emissao, natureza_titulo, data_liquidacao

    ),

    titulo_mes_anterior AS (

        WITH tmp_titulo_financeiro AS (

            SELECT
                p.codigo AS codigo_credor_devedor,
                p.nome AS credor_devedor,
                tf.data_emissao,
                tf.data_vencimento,
                tf.numero_titulo,
                tf.data_liquidacao,
                tf.valor_titulo AS valor_principal,
                (tf.acrescimo_financeiro + tf.juros_cobranca + tf.multa_cobranca) AS total_acrescimo,
                (tf.desconto_financeiro + tf.desconto_cobranca + tf.retencao_tributaria + tf.valor_taxa_administracao + tf.tarifa_transacao) AS total_desconto,
                se.nome AS nome_empresa, 
                tf.id_titulo_financeiro,
                tf.pagar_receber, -- 1 - Pagar, 2 - Receber
                tf.natureza_titulo as codigo_natureza_titulo,
                tf.tipo_titulo,
                tf.situacao,
                ovl1.titulo AS natureza_titulo,
                CASE WHEN tf.valor_liquidado > 0 THEN tf.valor_liquidado ELSE
                (tf.valor_titulo
                - (tf.desconto_financeiro + tf.desconto_cobranca + tf.retencao_tributaria + tf.valor_taxa_administracao + tf.tarifa_transacao)
                + (tf.acrescimo_financeiro + tf.juros_cobranca + tf.multa_cobranca)) END AS valor_titulo
            FROM titulo_financeiro AS tf 
            INNER JOIN sis_empresa AS se ON se.id_empresa = tf.id_empresa
            LEFT JOIN sis_opcao_lista_valor AS ovl1 ON (ovl1.id = tf.natureza_titulo AND ovl1.id_lista_valor = 'C043EFC0EDD5414995003170978F8878')
            LEFT JOIN pessoa AS p ON (tf.id_credor_devedor = p.id_pessoa)
            WHERE tf.id_empresa IN (:IdEmpresaMultSlc) 

            AND CASE 
                WHEN tf.pagar_receber = 1 AND tf.natureza_titulo IN (101, 106, 116, 109, 114, 222)  THEN tf.data_emissao <= date_trunc('month',CAST(:DataFinal AS DATE)) - INTERVAL'1 day' AND (tf.situacao IN (1, 9) OR tf.data_liquidacao > date_trunc('month',CAST(:DataFinal AS DATE)) - INTERVAL'1 day')
                WHEN tf.pagar_receber = 2 AND tf.natureza_titulo IN (201, 202, 203, 204, 205, 206, 209, 220, 221) AND tf.tipo_titulo = 1 THEN tf.data_emissao <= date_trunc('month',CAST(:DataFinal AS DATE)) - INTERVAL'1 day' AND (tf.situacao IN (1, 9) OR tf.data_liquidacao > date_trunc('month',CAST(:DataFinal AS DATE)) - INTERVAL'1 day')      
            END 
            ORDER BY tf.pagar_receber,  tf.id_titulo_financeiro
        )
        
        SELECT 
            1 AS orderby,
            nome_empresa,
            array_agg(numero_titulo) AS numero_titulo,
            codigo_credor_devedor,
            credor_devedor,
            data_emissao,
            data_liquidacao,
            natureza_titulo,
            CASE WHEN pagar_receber = 2 THEN 'Título a Receber' ELSE 'Título a Pagar' END AS natureza,
            SUM(valor_principal) AS valor_principal,
            SUM(valor_titulo) AS valor_titulo
        FROM tmp_titulo_financeiro 
        GROUP BY nome_empresa, codigo_credor_devedor, credor_devedor, pagar_receber, data_emissao, natureza_titulo, data_liquidacao
        
    ),
    mes AS (
    SELECT :DataFinal::DATE AS data
    ),

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

    SELECT
        mes.data AS cabecalho,
        'MES' AS tipo,  
        nome_empresa,
        codigo_credor_devedor,
        credor_devedor,
        numero_titulo,
        data_emissao,
        data_liquidacao,
        natureza_titulo,
        natureza,
        valor_principal,
        valor_titulo
    FROM titulo_mes, mes

    UNION ALL

    SELECT
         mes_anterior.data AS cabecalho,
        'MES_ANTERIOR' AS tipo,  
        nome_empresa,
        codigo_credor_devedor,
        credor_devedor,
        numero_titulo,
        data_emissao,
        data_liquidacao,
        natureza_titulo,
        natureza,
        valor_principal,
        valor_titulo
    FROM titulo_mes_anterior, mes_anterior

    ORDER BY nome_empresa ASC, cabecalho DESC, natureza ASC, data_emissao ASC

)

SELECT * FROM titulo_financeiro