package com.rjconsultores.ventaboletos.relatorios.impl;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.Estado;
import com.rjconsultores.ventaboletos.entidad.TipoPuntoVenta;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.DataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.utilerias.fiscal.vo.FinanceiroAnalitico;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class RelatorioFinanceiroAnalitico extends Relatorio {

	private static Logger log = LogManager.getLogger(RelatorioFinanceiroAnalitico.class);
	List<FinanceiroAnalitico> listdata = null;

	@SuppressWarnings("unchecked")
	public RelatorioFinanceiroAnalitico(final Map<String, Object> parametros, Connection conexao) throws Exception {
		super(parametros, conexao);

		this.setCustomDataSource(new DataSource(this) {
			@Override
			public void initDados() throws Exception {
				try {
					Date inicio = (Date) parametros.get("inicio");
					Date fim = (Date) parametros.get("fim");
					Empresa empresa = (Empresa) parametros.get("empresa");
					TipoPuntoVenta tipoPuntoVenta = (TipoPuntoVenta) parametros.get("tipoPuntoVenta");
					boolean isBpe = (Boolean) parametros.get("isBpe");

					List<Estado> estados = (List<Estado>) parametros.get("estados");
					String ufs = null;
					for (Estado estado : estados) {
						if (ufs == null)
							ufs = estado.getEstadoId().toString();
						else
							ufs = ufs + "," + estado.getEstadoId().toString();
					}

					String pdvs = (String) parametros.get("agencias");

					NamedParameterStatement stmt = new NamedParameterStatement(getConexao(), getSql(ufs, pdvs, tipoPuntoVenta == null ? -1 : tipoPuntoVenta.getTipoptovtaId().intValue(), isBpe));
					stmt.setInt("EMPRESA_ID", empresa.getEmpresaId());
					stmt.setTimestamp("DATE_INICIO", new java.sql.Timestamp(DateUtil.inicioFecha(inicio).getTime()));
					stmt.setTimestamp("DATE_FIM", new java.sql.Timestamp(DateUtil.fimFecha(fim).getTime()));

					listdata = new ArrayList<FinanceiroAnalitico>();
					ResultSet rset = stmt.executeQuery();
					while (rset.next()) {
						FinanceiroAnalitico fs = new FinanceiroAnalitico();
						fs.setFechorVenta(rset.getDate("fechorVenta"));

						fs.setGapVenda(getBigDecimal(rset, "receita_gap"));
						fs.setGapImpressa(getBigDecimal(rset, "entrega_gap"));

						fs.setReceitaBPR(getBigDecimal(rset, "receita_rdi_bpr"));

						BigDecimal totalVendaPassagens = fs.getReceitaBPR().add(fs.getGapVenda());
						totalVendaPassagens = totalVendaPassagens.subtract(fs.getGapImpressa());
						fs.setTotalVendaPassagens(totalVendaPassagens);

						fs.setReceitaEb(getBigDecimal(rset, "receita_eb"));
						fs.setMultaComp(getBigDecimal(rset, "receita_multa"));
						fs.setDifTrocaOCD(getBigDecimal(rset, "receita_dif_troca_ocd"));
						fs.setDifTarifaMaior(getBigDecimal(rset, "receita_dif_dif_tarifa_maior"));

						BigDecimal totalOutrasReceitas = fs.getReceitaEb().add(fs.getMultaComp()).add(fs.getDifTrocaOCD()).add(fs.getDifTarifaMaior());
						fs.setTotalOutrasReceitas(totalOutrasReceitas);

						BigDecimal taxaEmbarque = getBigDecimal(rset, "taxaEmbarque");
						taxaEmbarque = taxaEmbarque.add(getBigDecimal(rset, "taxaEmbarque_ee"));
						fs.setTxEmb(taxaEmbarque);

						fs.setPedagio(getBigDecimal(rset, "pedagio"));
						fs.setSegFacult(getBigDecimal(rset, "segurofac"));

						BigDecimal totalTerceiros = fs.getTxEmb().add(fs.getPedagio()).add(fs.getSegFacult());
						fs.setTotalTerceiros(totalTerceiros);

						BigDecimal receitaBruta = totalVendaPassagens.add(totalOutrasReceitas).add(totalTerceiros);
						fs.setReceitaBruta(receitaBruta);

						fs.setDevolBPR(getBigDecimal(rset, "receita_cancel_rdi_bpr"));
						fs.setDevolGAP(getBigDecimal(rset, "receita_devol_gap"));

						BigDecimal totalDevolucao = fs.getDevolBPR().add(fs.getDevolGAP());
						BigDecimal receitaLiquida = receitaBruta.subtract(totalDevolucao);
						fs.setReceitaLiquida(receitaLiquida);

						fs.setDespesas(getBigDecimal(rset, "despesas"));
						fs.setPgOCD(getBigDecimal(rset, "receita_ocd_deb"));
						fs.setDifTarifaMenor(getBigDecimal(rset, "receita_dif_dif_tarifa_menor"));

						BigDecimal cartaoCredito = getBigDecimal(rset, "cartao_credito");
						cartaoCredito = cartaoCredito.add(getBigDecimal(rset, "cartao_credito_ee"));
						fs.setCartaoCredito(cartaoCredito);

						BigDecimal cartaoDebito = getBigDecimal(rset, "cartao_debito");
						cartaoDebito = cartaoDebito.add(getBigDecimal(rset, "cartao_debito_ee"));
						fs.setCartaoDebito(cartaoDebito);

						BigDecimal boleto = getBigDecimal(rset, "boleto_bnc");
						boleto = boleto.add(getBigDecimal(rset, "boleto_bnc_ee"));
						fs.setBoletoBancario(boleto);

						BigDecimal totalDetalhamento = fs.getDespesas().add(fs.getPgOCD()).add(fs.getDifTarifaMenor())
								.add(fs.getCartaoCredito()).add(fs.getCartaoDebito()).add(fs.getBoletoBancario());
						fs.setTotalDetalhamento(totalDetalhamento);

						BigDecimal saldo = totalDetalhamento.subtract(receitaLiquida);
						fs.setSaldo(saldo);

						listdata.add(fs);
					}

					if (!getConexao().isClosed())
						getConexao().close();

					Collections.sort(listdata);

				} catch (SQLException e) {
					log.error("", e);
				}
			}

		});

		this.setCollectionDataSource(new JRBeanCollectionDataSource(listdata));
	}

	static public BigDecimal getBigDecimal(ResultSet rs, String strColName) throws SQLException {
		BigDecimal nValue = rs.getBigDecimal(strColName);
		return rs.wasNull() ? BigDecimal.ZERO : nValue;
	}

	@Override
	protected void processaParametros() throws Exception {
	}

	private String getSql(String ufs, String pdvs, Integer tipoptovtaId, boolean isBpe) {

		StringBuilder sql = new StringBuilder(18000);
		sql.append(" SELECT *   ");
		sql.append(" FROM ");
		sql.append("   (SELECT  ");
		sql.append("     cdv.empresaId, ");
		sql.append("     cdv.fechorVenta,  ");
		sql.append("     SUM( CASE WHEN (cdv.indreimpresion = 0 ) THEN (CASE WHEN motivocancelacion_id IS NULL THEN 1 ELSE -1 END * cdv.pedagio) ELSE 0 END) AS pedagio, ");
		sql.append("     SUM( CASE WHEN (cdv.indreimpresion = 0 ) THEN (CASE WHEN motivocancelacion_id IS NULL THEN 1 ELSE -1 END * cdv.taxaEmbarque) ELSE 0 END)  AS taxaEmbarque, ");
		sql.append("     SUM( CASE WHEN (cdv.indreimpresion = 0 AND cdv.motivocancelacion_id IS NULL) THEN cdv.valorpago ELSE 0 END) AS receita_bpr, ");
		sql.append("     SUM( CASE WHEN (cdv.indreimpresion = 0 AND cdv.tipoventa_id IN (5,12,18,49) AND motivocancelacion_id IS NULL ) THEN ( cdv.tarifa+cdv.taxaEmbarque+cdv.pedagio+cdv.seguro+cdv.outros) ELSE 0 END) AS receita_gap, ");
		sql.append("     SUM( CASE WHEN (cdv.indreimpresion = 1 AND cdv.indstatusboleto = 'E' ) THEN (CASE WHEN motivocancelacion_id IS NULL THEN 1 ELSE -1 END * (cdv.tarifa+cdv.taxaEmbarque+cdv.pedagio+cdv.seguro+cdv.outros)) ELSE 0 END) AS entrega_gap, ");
		sql.append("     SUM( (SELECT SUM( CASE WHEN cdv.MOTIVOCANCELACION_ID IS NULL THEN 1 ELSE -1 END * cfp.importe) FROM caja_formapago cfp WHERE cfp.caja_id = cdv.cajaid AND cfp.activo = 1 AND cfp.FORMAPAGO_ID IN (2,31,38) AND cdv.indreimpresion = 0 AND cdv.indstatusoperacion = 'F' AND cdv.tipoventa_id <> 6 ) ) AS cartao_credito, ");
		sql.append("     SUM( (SELECT SUM( CASE WHEN cdv.MOTIVOCANCELACION_ID IS NULL THEN 1 ELSE -1 END * cfp.importe) FROM caja_formapago cfp WHERE cfp.caja_id = cdv.cajaid AND cfp.activo = 1 AND cfp.FORMAPAGO_ID IN (3) AND cdv.indreimpresion = 0 AND cdv.indstatusoperacion = 'F' AND cdv.tipoventa_id <> 6 ) ) AS cartao_debito, ");
		sql.append("     SUM( (SELECT SUM( CASE WHEN cdv.MOTIVOCANCELACION_ID IS NULL THEN 1 ELSE -1 END * cfp.importe) FROM caja_formapago cfp WHERE cfp.caja_id = cdv.cajaid AND cfp.activo = 1 AND cfp.FORMAPAGO_ID IN (1) AND cdv.indreimpresion = 0 AND cdv.indstatusoperacion = 'F' AND cdv.tipoventa_id <> 6 ) ) AS boleto_bnc ");
		sql.append("   FROM ");
		sql.append("     ( SELECT DISTINCT c.caja_id AS cajaid, ");
		sql.append("       e.empresa_id              AS empresaId, ");
		sql.append("       trunc(c.feccreacion)      as fechorVenta,  ");
		sql.append("       c.indstatusboleto, ");
		sql.append("       c.indreimpresion, ");
		sql.append("       c.indcancelacion, ");
		sql.append("       c.numfoliosistema, ");
		sql.append("       COALESCE(c.preciopagado, 0)        AS valorpago, ");
		sql.append("       COALESCE(c.preciobase, 0)          AS precobase, ");
		sql.append("       COALESCE(c.preciopagado, 0)        AS tarifa, ");
		sql.append("       COALESCE(c.importetaxaembarque, 0) AS taxaEmbarque, ");
		sql.append("       COALESCE(c.importepedagio, 0)      AS pedagio, ");
		sql.append("       COALESCE(c.importeseguro, 0)       AS seguro, ");
		sql.append("       COALESCE(c.importeoutros, 0)       AS outros, ");
		sql.append("       (SELECT MIN(formapago_id) FROM caja_formapago cfp WHERE cfp.caja_id = c.caja_id AND cfp.activo = 1) AS formapago_id , ");
		sql.append("       c.motivocancelacion_id AS motivocancelacion_id, ");
		sql.append("       c.tipoventa_id         AS tipoventa_id, ");
		sql.append("       c.indstatusoperacion ");
		sql.append("     FROM CONTA_CORRENTE_PTOVTA ccp ");
		sql.append("     INNER JOIN marca ma ");
		sql.append("     ON ma.empresa_id = ccp.EMPRESA_ID ");
		sql.append("     INNER JOIN CAJA c ");
		sql.append("     ON c.FECCORTE       = ccp.FECCORTE ");
		sql.append("     AND c.TURNO_ID      = ccp.TURNO_ID ");
		sql.append("     AND c.PUNTOVENTA_ID = ccp.PUNTOVENTA_ID ");
		sql.append("     AND c.marca_id      = ma.marca_id ");
		sql.append("     AND c.USUARIO_ID    = ccp.USUARIO_ID ");
		sql.append("     INNER JOIN empresa e ");
		sql.append("     ON e.empresa_id = c.empresacorrida_id ");
		sql.append("     JOIN punto_venta pv ");
		sql.append("     ON pv.puntoventa_id = c.puntoventa_id ");
		sql.append("     JOIN parada po ");
		sql.append("     ON po.parada_id = pv.parada_id ");
		sql.append("     JOIN ciudad co ");
		sql.append("     ON co.ciudad_id = po.ciudad_id ");
		sql.append("     JOIN estado eo ");
		sql.append("     ON eo.estado_id    = co.estado_id ");
		sql.append("     WHERE c.activo     = 1 ");
		sql.append("     AND po.activo      = 1 ");
		sql.append("     AND co.activo      = 1 ");
		sql.append("     AND eo.activo      = 1 ");
		sql.append("     AND ccp.feccorte  >= :DATE_INICIO ");
		sql.append("     AND ccp.feccorte  <= :DATE_FIM ");
		sql.append("     AND ccp.empresa_id = :EMPRESA_ID  ");

		sql.append(ufs == null ? "" : " and eo.estado_id in ( " + ufs + " )  ");
		sql.append(pdvs == null ? "" : "and ccp.puntoventa_id in ( " + pdvs + " ) ");
		sql.append(tipoptovtaId == -1 ? "" : "and pv.tipoptovta_id = " + tipoptovtaId);

		sql.append("     ) cdv ");
		sql.append("   GROUP BY cdv.empresaId,  ");
		sql.append("     cdv.fechorVenta ");
		sql.append("   ) agrc ");
		sql.append(" LEFT JOIN ");
		sql.append("   (SELECT cdc.empresaId, ");
		sql.append("     cdc.fechorVenta,  ");
		sql.append("     SUM( CASE WHEN (cdc.indstatusboleto IN ('C', 'T') AND cdc.motivocancelacion_id IN (32,10,37)) THEN cdc.valorpago ELSE 0 END) AS receita_devol_bpr, ");
		sql.append("     SUM( CASE WHEN (cdc.indstatusboleto IN ('C', 'T') AND cdc.motivocancelacion_id IN (31)) THEN cdc.valorpago ELSE 0 END) AS receita_cancel_bpr, ");
		sql.append("     SUM( CASE WHEN ( (cdc.indstatusboleto = 'C' AND cdc.motivocancelacion_id IN (31,32,10,37) OR (cdc.indstatusboleto = 'T' AND cdc.motivocancelacion_id IS NULL )) AND cdc.numfoliosistema IS NULL AND cdc.tipoventa_id IN (5,12,18,49)) THEN cdc.valorpago ELSE 0 END) AS receita_devol_gap, ");
		sql.append("     SUM( CASE WHEN (cdc.indstatusboleto = 'C' AND cdc.motivocancelacion_id IN (35)) THEN cdc.valorpago ELSE 0 END) AS receita_ocd_deb, ");
		sql.append("     SUM( CASE WHEN (cdc.indstatusboleto = 'C' AND cdc.motivocancelacion_id IN (99) ) THEN cdc.valorpago ELSE 0 END) AS receita_ocd_cred ");
		sql.append("  FROM ");
		sql.append("     ( SELECT DISTINCT c.caja_id AS cajaid, ");
		sql.append("       trunc(c.feccreacion)      AS fechorVenta,  ");
		sql.append("       e.empresa_id              AS empresaId, ");
		sql.append("       c.indstatusboleto, ");
		sql.append("       c.indreimpresion, ");
		sql.append("       c.indcancelacion, ");
		sql.append("       c.numfoliosistema, ");
		sql.append("       COALESCE(cfp.importe, 0)           AS valorpago, ");
		sql.append("       COALESCE(c.preciobase, 0)          AS precobase, ");
		sql.append("       COALESCE(c.preciopagado, 0)        AS tarifa, ");
		sql.append("       COALESCE(c.importetaxaembarque, 0) AS taxaEmbarque, ");
		sql.append("       COALESCE(c.importepedagio, 0)      AS pedagio, ");
		sql.append("       COALESCE(c.importeseguro, 0)       AS seguro, ");
		sql.append("       COALESCE(c.importeoutros, 0)       AS outros, ");
		sql.append("       cfp.formapago_id, ");
		sql.append("       c.motivocancelacion_id AS motivocancelacion_id, ");
		sql.append("       c.tipoventa_id         AS tipoventa_id, ");
		sql.append("       c.indstatusoperacion ");
		sql.append("     FROM caja c ");
		sql.append("     INNER JOIN caja_formapago cfp ");
		sql.append("     ON cfp.caja_id = c.caja_id ");
		sql.append("     INNER JOIN forma_pago fp ");
		sql.append("     ON cfp.formapago_id = fp.formapago_id ");
		sql.append("     INNER JOIN marca m ");
		sql.append("     ON m.marca_id = c.marca_id ");
		sql.append("     AND m.activo  = 1 ");
		sql.append("     INNER JOIN empresa e ");
		sql.append("     ON e.empresa_id = m.empresa_id ");
		sql.append("     INNER JOIN punto_venta pv ");
		sql.append("     ON pv.puntoventa_id = c.puntoventa_id ");
		sql.append("     JOIN parada po ");
		sql.append("     ON po.parada_id = pv.parada_id ");
		sql.append("     JOIN ciudad co ");
		sql.append("     ON co.ciudad_id = po.ciudad_id ");
		sql.append("     JOIN estado eo ");
		sql.append("     ON eo.estado_id                = co.estado_id ");
		sql.append("     WHERE (c.motivocancelacion_id IN (31,32,10,37,99,36) ");
		sql.append("     OR c.motivocancelacion_id     IS NULL) ");
		sql.append("     AND c.feccorte                >= :DATE_INICIO ");
		sql.append("     AND c.feccorte                <= :DATE_FIM ");
		sql.append("     AND c.empresacorrida_id        = :EMPRESA_ID  ");

		sql.append(ufs == null ? "" : " and eo.estado_id in ( " + ufs + " )  ");
		sql.append(pdvs == null ? "" : "and pv.puntoventa_id in ( " + pdvs + " ) ");
		sql.append(tipoptovtaId == -1 ? "" : "and pv.tipoptovta_id = " + tipoptovtaId);

		sql.append(" 	AND c.categoria_id NOT IN (SELECT valorconstante FROM constante WHERE nombconstante = 'GRATUIDADE_CRIANCA' ) ");
		sql.append("     ) cdc ");
		sql.append("   GROUP BY cdc.empresaId,  ");
		sql.append("     cdc.fechorVenta ");
		sql.append("   ) canc ON agrc.empresaId = canc.empresaId ");
		sql.append(" and agrc.fechorVenta       = canc.fechorVenta ");
		sql.append(" LEFT JOIN ");
		sql.append("   (SELECT ee.empresa_id AS empresaId, ");
		sql.append("    trunc(ee.fechoringreso) as fechorVenta, ");
		sql.append(" 	SUM( CASE WHEN ee.tipoeventoextra_id = 2 AND tee.indtipo = 1 THEN cdp.importe ELSE 0 END) AS taxaembarque_ee, ");
		sql.append(" 	SUM( CASE WHEN ee.tipoeventoextra_id = 25 AND tee.indtipo = 1 THEN cdp.importe ELSE 0 END) AS segurofac, ");
		sql.append(" 	SUM( CASE WHEN ee.tipoeventoextra_id = 82 AND tee.indtipo = 1 THEN cdp.importe ELSE 0 END) AS receita_eb, ");
		sql.append(" 	SUM( CASE WHEN ee.tipoeventoextra_id IN (41) AND tee.indtipo = 1 THEN cdp.importe ELSE 0 END) AS receita_multa, ");
		sql.append(" 	SUM( CASE WHEN ee.tipoeventoextra_id IN (103,99978,99999) AND tee.indtipo = 1 THEN cdp.importe ELSE 0 END) AS receita_dif_troca_ocd, ");
		sql.append(" 	SUM( CASE WHEN ee.tipoeventoextra_id IN (43) AND tee.indtipo = 1 THEN cdp.importe ELSE 0 END) AS receita_dif_dif_tarifa_maior, ");
		sql.append(" 	SUM( CASE WHEN ee.tipoeventoextra_id IN (44) AND tee.indtipo = 0 THEN cdp.importe ELSE 0 END) AS receita_dif_dif_tarifa_menor, ");
		sql.append(" 	SUM( CASE WHEN ee.tipoeventoextra_id NOT IN (44) AND tee.indtipo = 0 THEN cdp.importe ELSE 0 END) AS despesas, ");
		sql.append(" 	SUM( CASE WHEN (cdp.formapago_id IN (2,31,38) AND e.indtipo = 1) THEN cdp.importe ELSE 0 END) AS cartao_credito_ee, ");
		sql.append(" 	SUM( CASE WHEN (cdp.formapago_id IN (3) AND e.indtipo = 1) THEN cdp.importe ELSE 0 END) AS cartao_debito_ee, ");
		sql.append(" 	SUM( CASE WHEN (cdp.formapago_id IN (1) AND e.indtipo = 1) THEN cdp.importe ELSE 0 END) AS boleto_bnc_ee ");
		sql.append("   FROM CAJA_DIVERSOS cd ");
		sql.append("   JOIN CAJA_DIVERSOS_PAGO cdp ");
		sql.append("   ON cdp.CAJADIVERSOS_ID = cd.CAJADIVERSOS_ID ");
		sql.append("   INNER JOIN forma_pago fp ");
		sql.append("   ON fp.formapago_id = cdp.formapago_id ");
		sql.append("   INNER JOIN EVENTO_EXTRA EE ");
		sql.append("   ON EE.EVENTOEXTRA_ID = cd.EVENTOEXTRA_ID ");
		sql.append("   JOIN tipo_evento_extra tee ");
		sql.append("   ON tee.tipoeventoextra_id = ee.tipoeventoextra_id ");
		sql.append("   LEFT OUTER JOIN empresa e ");
		sql.append("   ON ee.empresa_id = e.empresa_id ");
		sql.append("   INNER JOIN CONTA_CORRENTE_PTOVTA ccp ");
		sql.append("   ON e.EMPRESA_ID       = ccp.EMPRESA_ID ");
		sql.append("   AND ccp.PUNTOVENTA_ID = cd.PUNTOVENTA_ID ");
		sql.append("   AND ccp.FECCORTE      = cd.FECCORTE ");
		sql.append("   AND ccp.TURNO_ID      = cd.turno_id ");
		sql.append("   AND cd.USUARIO_ID     = ccp.USUARIO_ID ");
		sql.append("   JOIN punto_venta pv ");
		sql.append("   ON pv.puntoventa_id = ee.puntoventa_id ");
		sql.append("   LEFT JOIN parada po ");
		sql.append("   ON po.parada_id = pv.parada_id ");
		sql.append("   LEFT JOIN ciudad co ");
		sql.append("   ON co.ciudad_id = po.ciudad_id ");
		sql.append("   LEFT JOIN estado eo ");
		sql.append("   ON eo.estado_id           = co.estado_id ");
		sql.append("   WHERE ( cd.indreimpresion = 0 ");
		sql.append("   OR cd.indreimpresion     IS NULL ) ");
		sql.append("   AND ee.empresa_id         = :EMPRESA_ID  ");
		sql.append("   AND ccp.FECCORTE BETWEEN :DATE_INICIO AND :DATE_FIM ");

		sql.append(ufs == null ? "" : " and eo.estado_id in ( " + ufs + " )  ");
		sql.append(pdvs == null ? "" : "and ccp.puntoventa_id in ( " + pdvs + " ) ");
		sql.append(tipoptovtaId == -1 ? "" : "and pv.tipoptovta_id = " + tipoptovtaId);

		sql.append("   GROUP BY ee.empresa_id, ");
		sql.append("     trunc(ee.fechoringreso)  ");
		sql.append("   ) eed ON agrc.empresaId = eed.empresaId ");
		sql.append(" AND agrc.fechorVenta = eed.fechorVenta ");
		sql.append(" LEFT JOIN ");
		sql.append("     (select empresaId, fechorVenta, sum(tarifa) receita_rdi_bpr from ( ");
		sql.append("     SELECT DISTINCT ");
		sql.append(isBpe ? " c.boleto_id as cajaId, " : " c.caja_id as cajaId, ");
		sql.append("       e.empresa_id AS empresaId,  ");
		sql.append("       TRUNC(c.feccreacion) AS fechorVenta, ");
		sql.append("       COALESCE(c.preciopagado, 0)AS tarifa, ");
		sql.append("       COALESCE(c.importetaxaembarque, 0) AS taxaEmbarque, ");
		sql.append("       COALESCE(c.importepedagio, 0) AS pedagio, ");
		sql.append("       COALESCE(c.importeseguro, 0) AS seguro, ");
		sql.append("       COALESCE(c.importeoutros, 0) AS outros ");
		sql.append(isBpe ? " from boleto c " : " FROM caja c ");
		sql.append(isBpe ? " inner join bpe bpe on bpe.boleto_id = c.boleto_id " : "");
		sql.append(isBpe ? " and bpe.activo = (case when c.motivocancelacion_id = 17 and c.boletooriginal_id is null then 0 else 1 end) " : "");
		sql.append("     INNER JOIN marca m ON m.marca_id = c.marca_id AND m.activo  = 1 ");
		sql.append("     INNER JOIN empresa e ON e.empresa_id = m.empresa_id ");
		sql.append("     INNER JOIN punto_venta pv ON pv.puntoventa_id = c.puntoventa_id ");
		sql.append("     INNER JOIN parada p ON pv.parada_id = p.parada_id  ");
		sql.append("     INNER JOIN ciudad co ON co.ciudad_id = p.ciudad_id  ");
		sql.append("     INNER JOIN estado eo ON eo.estado_id = co.estado_id ");
		sql.append("     WHERE c.activo = 1 AND p.activo = 1 AND co.activo = 1 AND eo.activo = 1 ");
		sql.append(isBpe ? " and bpe.bpe_id is not null " : " AND c.serieimpfiscal IS NOT NULL ");
		sql.append("     AND ((c.indreimpresion = 0 AND c.motivocancelacion_id IS NULL ");
		sql.append("     AND c.numfoliosistema IS NOT NULL) OR (c.indstatusboleto = 'E' AND c.indreimpresion = 1)) ");
		sql.append("     AND (COALESCE(c.preciopagado,0) + COALESCE(c.importetaxaembarque,0) + COALESCE(c.importeseguro,0) + COALESCE(c.importepedagio,0) + COALESCE(c.importeoutros,0)) > 0 ");
		sql.append("     AND c.feccreacion >= :DATE_INICIO AND c.feccreacion <= :DATE_FIM ");
		sql.append("     AND e.empresa_id   = :EMPRESA_ID ");
		
		sql.append(ufs == null ? "" : " and eo.estado_id in ( " + ufs + " )  ");
		sql.append(pdvs == null ? "" : "and pv.puntoventa_id in ( " + pdvs + " ) ");
		sql.append(tipoptovtaId == -1 ? "" : "and pv.tipoptovta_id = " + tipoptovtaId);

		sql.append("     UNION ALL ");
		sql.append("     SELECT DISTINCT c.caja_id AS cajaId, ");
		sql.append("       e.empresa_id AS empresaId,  ");
		sql.append("       TRUNC(c.feccreacion) AS fechorVenta, ");
		sql.append("       COALESCE(c.preciopagado, 0) AS tarifa, ");
		sql.append("       COALESCE(c.importetaxaembarque, 0) AS taxaEmbarque, ");
		sql.append("       COALESCE(c.importepedagio, 0) AS pedagio, ");
		sql.append("       COALESCE(c.importeseguro, 0) AS seguro, ");
		sql.append("       COALESCE(c.importeoutros, 0) AS outros ");
		sql.append("     FROM caja c ");
		sql.append("     JOIN marca m ");
		sql.append("     ON c.marca_id = m.marca_id ");
		sql.append("     JOIN empresa e ");
		sql.append("     ON e.empresa_id = m.empresa_id ");
		sql.append("     JOIN aidf a ");
		sql.append("     ON a.aidf_id = c.aidf_id ");
		sql.append("     JOIN punto_venta pv ");
		sql.append("     ON pv.puntoventa_id = c.puntoventa_id ");
		sql.append("     JOIN parada po ");
		sql.append("     ON po.parada_id = pv.parada_id ");
		sql.append("     JOIN ciudad co ");
		sql.append("     ON co.ciudad_id = po.ciudad_id ");
		sql.append("     JOIN estado eo ");
		sql.append("     ON eo.estado_id = co.estado_id ");
		sql.append("     WHERE ((c.tipoventa_id       = 3 ");
		sql.append("     AND c.indstatusboleto        = 'V' ");
		sql.append("     AND c.indreimpresion         = 0) ");
		sql.append("     OR (c.tipoventa_id          IN (12,18) ");
		sql.append("     AND c.indstatusboleto        = 'E' ");
		sql.append("     AND c.numfoliosistema        = c.numfoliopreimpreso)) ");
		sql.append("     AND (c.motivocancelacion_id IS NULL ");
		sql.append("     OR c.motivocancelacion_id   <> 35) ");
		sql.append("     AND c.indcancelacion         = 0 ");
		sql.append("     AND e.empresa_id      = :EMPRESA_ID ");
		sql.append("     AND c.feccreacion BETWEEN :DATE_INICIO AND :DATE_FIM ");

		sql.append(ufs == null ? "" : " and eo.estado_id in ( " + ufs + " )  ");
		sql.append(pdvs == null ? "" : "and pv.puntoventa_id in ( " + pdvs + " ) ");
		sql.append(tipoptovtaId == -1 ? "" : "and pv.tipoptovta_id = " + tipoptovtaId);

		sql.append("     ) rbl ");
		sql.append("     GROUP BY rbl.fechorVenta, ");
		sql.append("     rbl.empresaId  ");
		sql.append("     )rbpr ON agrc.empresaId = rbpr.empresaId ");
		sql.append(" 	AND agrc.fechorVenta     = rbpr.fechorVenta ");
		sql.append(" LEFT JOIN ");
		sql.append(" ( select empresaId, fechorVenta, sum(tarifa) receita_cancel_rdi_bpr from ( ");
		sql.append("     SELECT DISTINCT b.boleto_id AS cajaId, ");
		sql.append("       e.empresa_id AS empresaId,  ");
		sql.append("       TRUNC(b.feccreacion) AS fechorVenta, ");
		sql.append("       COALESCE(b.preciopagado, 0) AS tarifa, ");
		sql.append("       COALESCE(b.importetaxaembarque, 0) AS taxaEmbarque, ");
		sql.append("       COALESCE(b.importepedagio, 0) AS pedagio, ");
		sql.append("       COALESCE(b.importeseguro, 0) AS seguro, ");
		sql.append("       COALESCE(b.importeoutros, 0) AS outros ");
		sql.append("     FROM boleto b ");
		sql.append("     INNER JOIN marca m ");
		sql.append("     ON m.marca_id = b.marca_id ");
		sql.append("     AND m.activo  = 1 ");
		sql.append("     INNER JOIN empresa e ");
		sql.append("     ON e.empresa_id = m.empresa_id ");
		sql.append("     INNER JOIN punto_venta pv ");
		sql.append("     ON pv.puntoventa_id = b.puntoventa_id ");
		sql.append("     INNER JOIN parada p ");
		sql.append("     ON pv.parada_id = p.parada_id  ");
		sql.append("     INNER JOIN ciudad co ");
		sql.append("     ON co.ciudad_id = p.ciudad_id  ");
		sql.append("     INNER JOIN estado eo ");
		sql.append("     ON eo.estado_id = co.estado_id ");
		sql.append("     WHERE b.motivocancelacion_id IN (31,32,10,37,99,36) ");
		sql.append("     AND b.indstatusboleto = 'C' ");
		sql.append("     AND b.indcancelacion = 1 ");
		sql.append("     AND b.numfoliopreimpreso IS NOT NULL ");
		sql.append("     AND e.empresa_id = :EMPRESA_ID ");
		sql.append("     AND b.fechorventa >= :DATE_INICIO ");
		sql.append("     AND b.fechorventa <= :DATE_FIM ");

		sql.append(ufs == null ? "" : " and eo.estado_id in ( " + ufs + " )  ");
		sql.append(pdvs == null ? "" : "and pv.puntoventa_id in ( " + pdvs + " ) ");
		sql.append(tipoptovtaId == -1 ? "" : "and pv.tipoptovta_id = " + tipoptovtaId);

		sql.append("     AND b.categoria_id NOT IN ");
		sql.append("       (SELECT valorconstante ");
		sql.append("       FROM constante ");
		sql.append("       WHERE nombconstante = 'GRATUIDADE_CRIANCA' ");
		sql.append("       ) ");
		sql.append("     ) cbl ");
		sql.append("     GROUP BY cbl.fechorVenta, ");
		sql.append("     cbl.empresaId  ");
		sql.append(" ) cbpr ");
		sql.append(" ON agrc.empresaId      = cbpr.empresaId ");
		sql.append(" AND agrc.fechorVenta   = cbpr.fechorVenta ");
		sql.append(" order by agrc.fechorVenta ");

		return sql.toString();
	}

}
