package com.rjconsultores.ventaboletos.dao.hibernate;

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

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.hibernate.type.IntegerType;
import org.hibernate.type.StringType;
import org.hibernate.type.TimestampType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import com.rjconsultores.ventaboletos.dao.BpeDAO;
import com.rjconsultores.ventaboletos.entidad.Constante;
import com.rjconsultores.ventaboletos.entidad.Estado;
import com.rjconsultores.ventaboletos.exception.BusinessException;
import com.rjconsultores.ventaboletos.service.ConstanteService;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.utilerias.MoneyHelper;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.utilerias.exportacao.bpe.ExportacaoBPEBase;
import com.rjconsultores.ventaboletos.utilerias.exportacao.bpe.ExportacaoBPEVo;
import com.rjconsultores.ventaboletos.utilerias.exportacao.bpe.ExportacaoBPEVo.TipoComp;
import com.rjconsultores.ventaboletos.utilerias.exportacao.bpe.xml.BPeUtil;
import com.rjconsultores.ventaboletos.utilerias.fiscal.vo.DetalhadoFiscal;
import com.rjconsultores.ventaboletos.utilerias.fiscal.vo.FiscalRdi;
import com.rjconsultores.ventaboletos.utilerias.fiscal.vo.RdiValidacion;
import com.rjconsultores.ventaboletos.vo.bpe.BPeVO;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;
import com.rjconsultores.ventaboletos.web.utilerias.spring.AppContext;

import br.inf.portalfiscal.bpe.TBPe;

@Repository("bpeDAO")
public class BpeHibernateDAO extends HibernateDaoSupport implements BpeDAO {
	private static final Logger log = LogManager.getLogger(BpeHibernateDAO.class);

	private static final String DATE_FORMAT_DMY = "dd/MM/yyyy";

	@Autowired
	public BpeHibernateDAO(@Qualifier("sessionFactory") SessionFactory factory) {
		setSessionFactory(factory);
	}

	@SuppressWarnings("deprecation")
	@Override
	public ExportacaoBPEVo buscarRegistroExportacaoBpe(Connection connection, Date inicio, Date fim, Integer empresaId, String cveestado, boolean consultaOtimizada, String codContPrevidencia) {

		log.info("Inicio da consulta buscarRegistroExportacaoBpe: " + new Date());

		boolean isNoXml = isNoXml() && consultaOtimizada;
		List<ExportacaoBPEBase> registros = consultaRegistroExportacaoBpe(connection, inicio, fim, empresaId, cveestado, isNoXml);

		/*
		 * Bilhetes emitidos dentro do mes for cancelados apenas informar o cancelamento; Bilhetes emitidos em um mês e cancelados em outro mês, este deve ir apenas no relatório de devolução;
		 */
		LinkedHashMap<String, ExportacaoBPEBase> mapAux = new LinkedHashMap<String, ExportacaoBPEBase>();
		for (ExportacaoBPEBase expBPe : registros) {
			expBPe.setIndContribuicaoPrevidenciaria(codContPrevidencia);
			if (mapAux.containsKey(expBPe.getChbpe())) {
				if (ExportacaoBPEVo.isBpeCancelado(expBPe.getCodstatus()) && !ExportacaoBPEVo.validaBPeCorridaAgrupada(expBPe))
					mapAux.put(expBPe.getChbpe(), expBPe);
			} else {
				if (!ExportacaoBPEVo.isBpeCancelado(expBPe.getCodstatus()) && !ExportacaoBPEVo.validaBPeCorridaAgrupada(expBPe))
					mapAux.put(expBPe.getChbpe(), expBPe);
			}
		}

		List<ExportacaoBPEBase> listaRegistroBaseBPE = new ArrayList<ExportacaoBPEBase>();

		for (Map.Entry<String, ExportacaoBPEBase> pair : mapAux.entrySet()) {

			if (isNoXml) {
				listaRegistroBaseBPE.add(ExportacaoBPEVo.gerarListas(pair.getValue()));
			} else {
				listaRegistroBaseBPE.add(ExportacaoBPEVo.gerarListasXML(pair.getValue()));
			}
		}

		ExportacaoBPEVo resp = new ExportacaoBPEVo();
		resp.setListaRegistroBaseBPE(listaRegistroBaseBPE);

		log.info(" !!!! --- Fim preocesso da ExportacaoBpe: " + new Date());

		return resp;
	}

	private List<ExportacaoBPEBase> consultaRegistroExportacaoBpe(Connection connection, Date inicio, Date fim, Integer empresaId, String cveestado, boolean isNoXml) {
		List<ExportacaoBPEBase> registros = new ArrayList<ExportacaoBPEBase>();

		String sql = null;
		if (isNoXml) {
			sql = queryNoXml();
		} else {
			sql = queryXml();
		}

		try {
			log.info("Consulta Exportacao Bpe: " + sql);

			PreparedStatement ps = connection.prepareStatement(sql);
			ps.setString(1, DateUtil.getStringDate(inicio, DATE_FORMAT_DMY) + " 00:00:00");
			ps.setString(2, DateUtil.getStringDate(fim, DATE_FORMAT_DMY) + " 23:59:59");
			ps.setLong(3, Long.valueOf(empresaId));
			ps.setString(4, cveestado);

			ps.setFetchSize(999);
			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				BigDecimal valortributado = BigDecimal.ZERO;
				BigDecimal valortotal = BigDecimal.ZERO;

				if (rs.getBigDecimal("valortributado") != null) {
					valortributado = rs.getBigDecimal("valortributado");
				}

				if (rs.getBigDecimal("valortotal") != null) {
					valortotal = rs.getBigDecimal("valortotal");
				}

				ExportacaoBPEBase registro = new ExportacaoBPEBase();
				registro.setBoletoId(rs.getLong("boleto_id"));
				registro.setNumfoliosistema(rs.getString("numfoliosistema"));
				registro.setvDesconto(rs.getBigDecimal("v_desconto"));
				registro.setChbpe(rs.getString("chbpe"));
				registro.setChbpeSub(rs.getString("chbpe_sub"));
				registro.setDhrecbto(rs.getString("dhrecbto"));
				registro.setDhEmisao(rs.getString("dh_emisao"));
				registro.setTpBpe(rs.getString("tp_bpe"));
				registro.setRetorno(rs.getString("retorno"));
				registro.setNprot(rs.getString("nprot"));
				registro.setNumBpe(rs.getString("num_bpe"));
				registro.setNumSerieBpe(rs.getString("numserie_bpe"));
				registro.setCodEstabelecimento(rs.getString("cod_estabelecimento"));
				registro.setRedBaseCalcEstadual(rs.getBigDecimal("red_base_calc_estadual"));
				registro.setRedBaseCalcMunicipal(rs.getBigDecimal("red_base_calc_municipal"));
				registro.setPorcRedMunicipal(rs.getBigDecimal("porc_red_municipal"));
				registro.setPorcRedEstadual(rs.getBigDecimal("porc_red_estadual"));
				registro.setTributacaoImportacao(rs.getBigDecimal("tributacao_importacao"));
				registro.setCodstatus(rs.getString("codstatus"));
				registro.setTipoevento(rs.getString("tipoevento"));
				registro.setCodigoContabilEstadual(rs.getString("codigocontabil_estadual"));
				registro.setCodigocontabilMunicipal(rs.getString("codigocontabil_municipal"));
				registro.setCrt(rs.getInt("crt"));
				registro.setIndPedagioMunicipal(rs.getInt("indpedagiomunicipal") == 1);
				registro.setIndSeguroMunicipal(rs.getInt("indseguromunicipal") == 1);
				registro.setIndTarifaMunicipal(rs.getInt("indtarifamunicipal") == 1);
				registro.setIndTxEmbarqueMunicipal(rs.getInt("indtxembarquemunicipal") == 1);
				registro.setIndPedadioEstdual(rs.getInt("indpedagioestdual") == 1);
				registro.setIndSeguroEstadual(rs.getInt("indseguroestadual") == 1);
				registro.setIndTarifaEstadual(rs.getInt("indtarifaestadual") == 1);
				registro.setIndTxEmbarqueEstadual(rs.getInt("indtxembarqueestadual") == 1);
				registro.setDhrecbtoBPe(rs.getString("dhrecbto_bpe"));
				registro.setActivoBPe(rs.getInt("activo_bpe") == 1);
				registro.setMotivoCancelacionId(rs.getInt("motivocancelacion_id"));
				registro.setValortributado(valortributado);
				registro.setValortotal(valortotal);

				if (isNoXml) {
					registro.setCmunini(rs.getString("cmunini"));
					registro.setCmunfim(rs.getString("cmunfim"));
					registro.setUfini(rs.getString("ufini"));
					registro.setUffim(rs.getString("uffim"));
					registro.setNbp(rs.getString("nbp"));
					registro.setDhemb(rs.getString("dhemb"));
					registro.setCst00(rs.getString("cst00"));
					registro.setCst20(rs.getString("cst20"));
					registro.setCst45(rs.getString("cst45"));
					registro.setCst90(rs.getString("cst90"));
					registro.setCstoutrauf(rs.getString("cstoutrauf"));
					registro.setCstsn(rs.getString("cstsn"));
					registro.setVbc00(rs.getString("vbc00"));
					registro.setPicms00(rs.getString("picms00"));
					registro.setVicms00(rs.getString("vicms00"));
					registro.setVbc20(rs.getString("vbc20"));
					registro.setPicms20(rs.getString("picms20"));
					registro.setVicms20(rs.getString("vicms20"));
					registro.setVbp(rs.getString("vbp"));
					registro.setVdesconto(rs.getString("vdesconto"));
					registro.setVpgto(rs.getString("vpgto"));
					registro.setTpcomp01(rs.getString("tpcomp01"));
					registro.setTpcomp02(rs.getString("tpcomp02"));
					registro.setTpcomp03(rs.getString("tpcomp03"));
					registro.setTpcomp04(rs.getString("tpcomp04"));
					registro.setTpcomp05(rs.getString("tpcomp05"));
					registro.setTpcomp06(rs.getString("tpcomp06"));
					registro.setTpcomp99(rs.getString("tpcomp99"));
					registro.setVcomp01(rs.getString("vcomp01"));
					registro.setVcomp02(rs.getString("vcomp02"));
					registro.setVcomp03(rs.getString("vcomp03"));
					registro.setVcomp04(rs.getString("vcomp04"));
					registro.setVcomp05(rs.getString("vcomp05"));
					registro.setVcomp06(rs.getString("vcomp06"));
					registro.setVcomp99(rs.getString("vcomp99"));
					registro.setpRedBC(rs.getString("pRedBC"));
				} else {
					String xml_bpe = rs.getNString("xml_bpe");
					String xml_bpe_2 = rs.getNString("xml_bpe_2");
					String xml_bpe_3 = rs.getNString("xml_bpe_3");
					registro.setXml(StringUtils.join(new String[] { xml_bpe, xml_bpe_2, xml_bpe_3 }));

				}

				registros.add(registro);
			}

			rs.close();
			ps.close();

		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}

		return registros;
	}

	private boolean isNoXml() {
		ConstanteService constanteService = (ConstanteService) AppContext.getApplicationContext().getBean("constanteService");
		Constante contante = constanteService.buscarPorNomeConstante("IMPORT_BPE_NOXML");
		String valorConstante = contante == null ? null : contante.getValorconstante();

		if (StringUtils.isBlank(valorConstante))
			return false;
		else
			return true;
	}

	/**
	 * Pega aquery da exportação do BPe
	 * 
	 * Para utilizar este modelo o cliente deve estar com a versão que contemple o mantis 15032
	 * 
	 * Deve ser inserido a constante IMPORT_BPE_NOXML, o file .sql esta no mantis 15005
	 * 
	 * @return nova query da exportação do BPe.
	 */
	private String queryNoXml() {
		StringBuilder sql = new StringBuilder();
		sql.append("select /*+INDEX(BPE IDX__BPE_BOLETO)*/ ");
		sql.append("  c.boleto_id, ");
		sql.append("  coalesce(c.num_bpe, c.numfoliosistema) as num_bpe, ");
		sql.append("  c.numfoliosistema as numfoliosistema, ");
		sql.append("  coalesce(c.preciopagado,0) + coalesce(c.importetaxaembarque,0) + coalesce(c.importeseguro,0) + coalesce(c.importepedagio,0) + coalesce(c.importeoutros,0) as valortotal, ");
		sql.append("  bpe.codstat as codstatus, ");
		sql.append("  bpe.tipoevento as tipoevento, ");
		sql.append("  bpe.desconto as v_desconto, ");
		sql.append("  bpe.chbpe, ");
		sql.append("  coalesce(bpe.chbpe_substituicao, ' ') as chbpe_sub, ");
		sql.append("  to_char(to_date(substr(bpe.dhrecbto,0,10), 'YYYY-MM-DD'), 'yyyymmdd') as dhrecbto_bpe, ");
		sql.append("  to_char(c.feccreacion, 'yyyymmdd') as dh_emisao, ");
		sql.append("  to_char(c.fechorviaje, 'yyyymmdd') as dhrecbto, ");
		sql.append("  coalesce(bpe.tiposubstituicao, '0') as tp_bpe, ");
		sql.append("  bpe.retorno_id as retorno, ");
		sql.append("  bpe.nprot, ");
		sql.append("  coalesce(c.numserie_bpe, '1') as numserie_bpe, ");
		sql.append("  c.categoria_id, ");
		/**
		 * Mantis 18267
		 */
		sql.append("  ei.codestabelecimento as cod_estabelecimento, ");
		sql.append("  ep.crtbpe as crt, ");
		sql.append("  ((case when coalesce(r.indtribtarifa,0) = 1 then c.preciopagado else 0 end) + (case when coalesce(r.indtribtaxaembarque,0) = 1 then c.importetaxaembarque else 0 end) + (case when coalesce(r.indtribpedagio,0) = 1 then c.importepedagio else 0 end)) as valortributado, ");
		sql.append("  ei.porcredbaseicms as red_base_calc_estadual, ");
		sql.append("  ei.porcredbaseicmsim as red_base_calc_municipal, ");
		sql.append("  ei.porcredmunicipal as porc_red_municipal, ");
		sql.append("  ei.porcredestadual as porc_red_estadual, ");
		sql.append("  ei.tributacaoimportacao as tributacao_importacao, ");
		sql.append("  ei.codigocontabilestadual as codigocontabil_estadual, ");
		sql.append("  ei.codigocontabilmunicipal as codigocontabil_municipal, ");
		sql.append("  coalesce(ei.indtarifamunicipal,0) as indtarifamunicipal, ");
		sql.append("  coalesce(ei.indseguromunicipal,0) as indseguromunicipal, ");
		sql.append("  coalesce(ei.indtxembarquemunicipal,0) as indtxembarquemunicipal, ");
		sql.append("  coalesce(ei.indpedagiomunicipal,0) as indpedagiomunicipal, ");
		sql.append("  coalesce(ei.indtarifaestadual,0) as indtarifaestadual,");
		sql.append("  coalesce(ei.indseguroestadual,0) as indseguroestadual, ");
		sql.append("  coalesce(ei.indtxembarqueestadual,0) as indtxembarqueestadual, ");
		sql.append("  coalesce(ei.indpedagioestdual,0) as indpedagioestdual, ");
		sql.append("  bpe.cmunini, ");
		sql.append("  bpe.cmunfim, ");
		sql.append("  bpe.ufini, ");
		sql.append("  bpe.uffim, ");
		sql.append("  bpe.nbp, ");
		sql.append("  bpe.dhemb, ");
		sql.append("  bpe.cst00, ");
		sql.append("  bpe.cst20, ");
		sql.append("  bpe.cst45, ");
		sql.append("  bpe.cst90, ");
		sql.append("  bpe.cstoutrauf, ");
		sql.append("  bpe.cstsn, ");
		sql.append("  bpe.vbc00, ");
		sql.append("  bpe.picms00, ");
		sql.append("  bpe.vicms00, ");
		sql.append("  bpe.vbc20, ");
		sql.append("  bpe.picms20, ");
		sql.append("  bpe.vicms20, ");
		sql.append("  bpe.vbp, ");
		sql.append("  bpe.vdesconto, ");
		sql.append("  bpe.vpgto, ");
		sql.append("  bpe.tpcomp01, ");
		sql.append("  bpe.tpcomp02, ");
		sql.append("  bpe.tpcomp03, ");
		sql.append("  bpe.tpcomp04, ");
		sql.append("  bpe.tpcomp05, ");
		sql.append("  bpe.tpcomp06, ");
		sql.append("  bpe.tpcomp99, ");
		sql.append("  bpe.vcomp01, ");
		sql.append("  bpe.vcomp02, ");
		sql.append("  bpe.vcomp03, ");
		sql.append("  bpe.vcomp04, ");
		sql.append("  bpe.vcomp05, ");
		sql.append("  bpe.vcomp06, ");
		sql.append("  bpe.vcomp99, ");
		sql.append("  bpe.pRedBC, ");
		sql.append("  bpe.activo as activo_bpe, ");
		sql.append("  c.motivocancelacion_id ");
		sql.append("from boleto c ");
		sql.append("  join bpe bpe on c.boleto_id = bpe.boleto_id ");
		sql.append("  join estado e on e.codibge = bpe.uf ");
		sql.append("  join marca ma on c.marca_id = ma.marca_id ");
		sql.append("  join empresa ep on ma.empresa_id = ep.empresa_id ");
		sql.append("  join ruta r on r.ruta_id = c.ruta_id ");
		sql.append("  inner join empresa_imposto ei on ei.empresa_id = ep.empresa_id and ei.estado_id = e.estado_id ");
		sql.append("where c.activo = 1 and e.activo = 1 and ei.activo = 1 ");
		sql.append("  and bpe.tipoamb = 1 and ep.activo = 1 ");
		sql.append("  and bpe.codstat in ('-1','100','101','102','135','150') ");
		sql.append("  and (bpe.tipoevento not in ('110115','110116') or bpe.tipoevento is null) ");
		sql.append("  and c.feccreacion >= to_date(?,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append("  and c.feccreacion <= to_date(?,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append("  and ep.empresa_id = ? ");
		sql.append("  and e.cveestado = ? ");
		// sql.append(" and (bpe.xmlregular is not null or bpe.xmlcontingencia is not null) ");
		sql.append("order by to_number(c.numfoliosistema), to_number(num_bpe), dh_emisao, tipoevento desc ");
		return sql.toString();
	}

	/**
	 * Este modelo de consulta que faz a busca do xml da tabela BPe deve ser evitado, por motivos de queda na performance da consulta e do processamento da conversão do xml.
	 * 
	 * Porem so devera ser utlizado novo modelo de exportação apos o cliente esta com a versão que contemple o mantis 15032
	 * 
	 * @deprecated use {@link queryNoXml()} instead.
	 */
	@Deprecated
	private String queryXml() {
		StringBuilder sql = new StringBuilder();
		sql.append("select ");
		sql.append("  c.boleto_id, ");
		sql.append("  coalesce(c.num_bpe, c.numfoliosistema) as num_bpe, ");
		sql.append("  c.numfoliosistema as numfoliosistema, ");
		sql.append("  coalesce(c.preciopagado,0) + coalesce(c.importetaxaembarque,0) + coalesce(c.importeseguro,0) + coalesce(c.importepedagio,0) + coalesce(c.importeoutros,0) as valortotal, ");
		sql.append("  bpe.codstat as codstatus, ");
		sql.append("  DBMS_LOB.substr(coalesce(bpe.xmlregular, bpe.xmlcontingencia), 3000) as xml_bpe, ");
		sql.append("  DBMS_LOB.substr(coalesce(bpe.xmlregular, bpe.xmlcontingencia), 3000, 3001) as xml_bpe_2, ");
		sql.append("  DBMS_LOB.substr(coalesce(bpe.xmlregular, bpe.xmlcontingencia), 3000, 6001) as xml_bpe_3, ");
		sql.append("  bpe.tipoevento as tipoevento, ");
		sql.append("  bpe.desconto as v_desconto, ");
		sql.append("  bpe.chbpe, ");
		sql.append("  coalesce(bpe.chbpe_substituicao, ' ') as chbpe_sub, ");
		sql.append("  to_char(to_date(substr(bpe.dhrecbto,0,10), 'YYYY-MM-DD'), 'yyyymmdd') as dhrecbto_bpe, ");
		sql.append("  to_char(c.feccreacion, 'yyyymmdd') as dh_emisao, ");
		sql.append("  to_char(c.fechorviaje, 'yyyymmdd') as dhrecbto, ");
		sql.append("  coalesce(bpe.tiposubstituicao, '0') as tp_bpe, ");
		sql.append("  bpe.retorno_id as retorno, ");
		sql.append("  bpe.nprot, ");
		sql.append("  coalesce(c.numserie_bpe, '1') as numserie_bpe, ");
		sql.append("  c.categoria_id, ");
		/**
		 * Mantis 18267
		 */
		sql.append("  ei.codestabelecimento as cod_estabelecimento, ");
		sql.append("  ep.crtbpe as crt, ");
		sql.append("  ((case when coalesce(r.indtribtarifa,0) = 1 then c.preciopagado else 0 end) + (case when coalesce(r.indtribtaxaembarque,0) = 1 then c.importetaxaembarque else 0 end) + (case when coalesce(r.indtribpedagio,0) = 1 then c.importepedagio else 0 end)) as valortributado, ");
		sql.append("  ei.porcredbaseicms as red_base_calc_estadual, ");
		sql.append("  ei.porcredbaseicmsim as red_base_calc_municipal, ");
		sql.append("  ei.porcredmunicipal as porc_red_municipal, ");
		sql.append("  ei.porcredestadual as porc_red_estadual, ");
		sql.append("  ei.tributacaoimportacao as tributacao_importacao, ");
		sql.append("  ei.codigocontabilestadual as codigocontabil_estadual, ");
		sql.append("  ei.codigocontabilmunicipal as codigocontabil_municipal, ");
		sql.append("  coalesce(ei.indtarifamunicipal,0) as indtarifamunicipal, ");
		sql.append("  coalesce(ei.indseguromunicipal,0) as indseguromunicipal, ");
		sql.append("  coalesce(ei.indtxembarquemunicipal,0) as indtxembarquemunicipal, ");
		sql.append("  coalesce(ei.indpedagiomunicipal,0) as indpedagiomunicipal, ");
		sql.append("  coalesce(ei.indtarifaestadual,0) as indtarifaestadual,");
		sql.append("  coalesce(ei.indseguroestadual,0) as indseguroestadual, ");
		sql.append("  coalesce(ei.indtxembarqueestadual,0) as indtxembarqueestadual, ");
		sql.append("  coalesce(ei.indpedagioestdual,0) as indpedagioestdual, ");
		sql.append("  bpe.activo as activo_bpe, ");
		sql.append("  c.motivocancelacion_id ");
		sql.append("from boleto c ");
		sql.append("  join bpe bpe on c.boleto_id = bpe.boleto_id ");
		sql.append("  join estado e on e.codibge = bpe.uf ");
		sql.append("  join marca ma on c.marca_id = ma.marca_id ");
		sql.append("  join empresa ep on ma.empresa_id = ep.empresa_id ");
		sql.append("  join ruta r on r.ruta_id = c.ruta_id ");
		sql.append("  left join empresa_imposto ei on ei.empresa_id = ep.empresa_id and ei.estado_id = e.estado_id ");
		sql.append("where c.activo = 1 and e.activo = 1 and ei.activo = 1 ");
		sql.append("  and bpe.tipoamb = 1 and ep.activo = 1 ");
		sql.append("  and bpe.codstat in ('-1','100','101','102','135','150') ");
		sql.append("  and (bpe.tipoevento not in ('110115','110116') or bpe.tipoevento is null) ");
		sql.append("  and c.feccreacion >= to_date(?,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append("  and c.feccreacion <= to_date(?,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append("  and ep.empresa_id = ? ");
		sql.append("  and e.cveestado = ? ");
		sql.append("  and (bpe.xmlregular is not null or bpe.xmlcontingencia is not null) ");
		sql.append("order by to_number(c.numfoliosistema), to_number(num_bpe), dh_emisao, tipoevento desc  ");
		return sql.toString();
	}

	@Override
	public String buscarXmlBPE(Connection connection, String chBpe) {

		String xmlBpe = null;
		StringBuilder sql = new StringBuilder();
		sql.append(" select distinct ");
		sql.append("    DBMS_LOB.substr(bpe.xmlregular, 3000) as xml_bpe, ");
		sql.append("    DBMS_LOB.substr(bpe.xmlregular, 3000, 3001) as xml_bpe_2, ");
		sql.append("    DBMS_LOB.substr(bpe.xmlregular, 3000, 6001) as xml_bpe_3 ");
		sql.append(" from bpe bpe ");
		sql.append(" where bpe.activo = 1 ");
		sql.append("  	and bpe.tipoamb = 1 ");
		sql.append("  	and bpe.codstat in ('100','150') ");
		sql.append("  	and bpe.chbpe = ? ");

		try {
			PreparedStatement ps = connection.prepareStatement(sql.toString());
			ps.setString(1, chBpe);

			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				String xml_bpe = rs.getNString("xml_bpe");
				String xml_bpe_2 = rs.getNString("xml_bpe_2");
				String xml_bpe_3 = rs.getNString("xml_bpe_3");
				xmlBpe = StringUtils.join(new String[] { xml_bpe, xml_bpe_2, xml_bpe_3 });
			}

			rs.close();
			ps.close();

		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return xmlBpe;
	}

	@Override
	public List<FiscalRdi> buscarBpeRDI(Connection connection, Date inicio, Date fim, Integer empresaId, List<Estado> estados, boolean isReceitaTerceiros, boolean consultaOtimizada) {

		String ufs = null;
		for (Estado estado : estados) {
			if (ufs == null)
				ufs = "'" + estado.getCveestado() + "'";
			else
				ufs = ufs + ",'" + estado.getCveestado() + "'";
		}

		List<FiscalRdi> rdis = new ArrayList<FiscalRdi>();

//		boolean isNoXML = isNoXml() && consultaOtimizada;

		
			StringBuilder sqlVendidos = new StringBuilder();
			sqlVendidos.append(sqlRelatorioRDIVendidosNoXML(ufs));

			List<DetalhadoFiscal> listVendidos = montaRelatorioRDINoXML(connection, inicio, fim, empresaId, ufs, sqlVendidos.toString());
			List<FiscalRdi> rdiVendidos = calcularRelatorioRDINoXML(listVendidos, isReceitaTerceiros);
			rdis.addAll(rdiVendidos);

			StringBuilder sql = new StringBuilder();
			sql.append(sqlRelatorioRDICanceladosSubstituidosNoXML(ufs));
			sql.append(" UNION ALL ");
			sql.append(sqlRelatorioRDICanceladosNoXML(ufs));

			List<DetalhadoFiscal> listCancelados = montaRelatorioRDINoXML(connection, inicio, fim, empresaId, ufs, sql.toString());
			List<FiscalRdi> rdiCancelados = calcularRelatorioRDINoXML(listCancelados, isReceitaTerceiros);
			rdis.addAll(rdiCancelados);

			Collections.sort(rdis, new Comparator<FiscalRdi>() {
				@Override
				public int compare(FiscalRdi m1, FiscalRdi m2) {
					return m1.getEstado().compareTo(m2.getEstado());
				}
			});

//			StringBuilder sql = new StringBuilder();
//			sql.append(sqlRelatorioRDIVendidosXML(ufs));
//			sql.append("    union all    ");
//			sql.append(sqlRelatorioRDICanceladosXML(ufs));
//
//			List<DetalhadoFiscal> list = montaRelatorioRDIXML(connection, inicio, fim, empresaId, ufs, sql.toString());
//			rdis.addAll(calcularRelatorioRDIXML(list, isReceitaTerceiros));
		

		return agrupaRdi(rdis);
	}

	private List<FiscalRdi> agrupaRdi(List<FiscalRdi> list) {
		List<FiscalRdi> aux = new ArrayList<FiscalRdi>();

		FiscalRdi rdi = null;
		for (FiscalRdi detail : list) {

			FiscalRdi atual = new FiscalRdi(detail.getEstado(), detail.getTipoViagem(), detail.getTipoReceita());
			if (!aux.contains(atual)) {
				rdi = new FiscalRdi(detail.getEstado(), detail.getTipoViagem(), detail.getTipoReceita());
				aux.add(rdi);
			}

			int index = aux.indexOf(atual);
			FiscalRdi agr = aux.get(index);
			montarParametros(agr, detail);
			aux.set(index, agr);
		}

		List<RdiValidacion> validacion = new ArrayList<RdiValidacion>();
		for (FiscalRdi detail : aux) {

			RdiValidacion rv = new RdiValidacion(detail.getEstado());
			if (!validacion.contains(rv)) {
				rv = new RdiValidacion(detail.getEstado());
				validacion.add(rv);
			}

			int indice = validacion.indexOf(rv);
			RdiValidacion rvAux = validacion.get(indice);

			if (detail.getTipoReceita().equals("REC") && detail.getTipoViagem().equals("IM"))
				rvAux.setTemIMRec(true);

			if (detail.getTipoReceita().equals("DEV") && detail.getTipoViagem().equals("IM"))
				rvAux.setTemIMDev(true);

			if (detail.getTipoReceita().equals("REC") && detail.getTipoViagem().equals("IE"))
				rvAux.setTemIERec(true);

			if (detail.getTipoReceita().equals("DEV") && detail.getTipoViagem().equals("IE"))
				rvAux.setTemIEDev(true);

			validacion.set(indice, rvAux);
		}

		for (RdiValidacion val : validacion) {

			if (!val.isTemIMRec()) {
				FiscalRdi rdiAux = new FiscalRdi(val.getEstado(), "IM", "REC");
				aux.add(montarParametros(rdiAux, new FiscalRdi()));
			}

			if (!val.isTemIMDev()) {
				FiscalRdi rdiAux = new FiscalRdi(val.getEstado(), "IM", "DEV");
				aux.add(montarParametros(rdiAux, new FiscalRdi()));
			}

			if (!val.isTemIERec()) {
				FiscalRdi rdiAux = new FiscalRdi(val.getEstado(), "IE", "REC");
				aux.add(montarParametros(rdiAux, new FiscalRdi()));
			}

			if (!val.isTemIEDev()) {
				FiscalRdi rdiAux = new FiscalRdi(val.getEstado(), "IE", "DEV");
				aux.add(montarParametros(rdiAux, new FiscalRdi()));
			}
		}

		Collections.sort(aux);
		return aux;
	}

	private FiscalRdi montarParametros(FiscalRdi agr, FiscalRdi detail) {
		agr.setQuantBilhetes(MoneyHelper.somar(agr.getQuantBilhetes(), detail.getTarifa() == null ? BigDecimal.ZERO : BigDecimal.ONE));
		agr.setTarifa(agr.getTarifa().add(detail.getTarifa() == null ? BigDecimal.ZERO : detail.getTarifa()));
		agr.setSeguro(MoneyHelper.somar(agr.getSeguro(), detail.getSeguro()));
		agr.setTxEmbarque(MoneyHelper.somar(agr.getTxEmbarque(), detail.getTxEmbarque()));
		agr.setPedagio(MoneyHelper.somar(agr.getPedagio(), detail.getPedagio()));
		agr.setPassagem(MoneyHelper.somar(agr.getPassagem(), detail.getPassagem()));
		agr.setIsentos(MoneyHelper.somar(agr.getIsentos(), detail.getIsentos()));
		agr.setOutros(MoneyHelper.somar(agr.getOutros(), detail.getOutros()));
		agr.setRbc(detail.getRbc() == null ? BigDecimal.ZERO : detail.getRbc());
		agr.setBaseCalculo(MoneyHelper.somar(agr.getBaseCalculo(), detail.getBaseCalculo()));
		agr.setAliquota(detail.getAliquota() == null ? BigDecimal.ZERO : detail.getAliquota());
		agr.setIcms(MoneyHelper.somar(agr.getIcms(), detail.getIcms()));
		agr.setCp(detail.getCp() == null ? BigDecimal.ZERO : detail.getCp());

		BigDecimal credPres = agr.getIcms().multiply(agr.getCp()).divide(new BigDecimal("100"));
		BigDecimal icmsRec = agr.getIcms().subtract(credPres);

		agr.setCredPres(credPres);
		agr.setIcmsRec(icmsRec);

		return agr;
	}

	private List<FiscalRdi> calcularRelatorioRDINoXML(List<DetalhadoFiscal> list, boolean isReceitaTerceiros) {

		List<FiscalRdi> rdis = new ArrayList<FiscalRdi>();

		/*
		 * Bilhetes emitidos dentro do mes for cancelados apenas informar o cancelamento; Bilhetes emitidos em um mês e cancelados em outro mês, este deve ir apenas no relatório de devolução;
		 */
		LinkedHashMap<String, DetalhadoFiscal> mapAux = new LinkedHashMap<String, DetalhadoFiscal>();
		for (DetalhadoFiscal det : list) {
			if ("REC".equals(det.getTipoReceita())) {
				if (mapAux.containsKey(det.getChbpe())) {
					if (ExportacaoBPEVo.isBpeCancelado(det.getCodstatus())) {
						// det.setTipoReceita("DEV");
						// mapAux.put(det.getChbpe(), det);
						mapAux.remove(det.getChbpe());
					}
				} else {
					if (!ExportacaoBPEVo.isBpeCancelado(det.getCodstatus())) {
						det.setTipoReceita("REC");
						mapAux.put(det.getChbpe(), det);
					}
				}
			} else {
				mapAux.put(det.getChbpe(), det);
			}
		}

		BigDecimal aliquotaAnt = null;
		for (Map.Entry<String, DetalhadoFiscal> pair : mapAux.entrySet()) {
			DetalhadoFiscal det = pair.getValue();

			boolean isEstadual = det.isInterEstadual();
			String tipoViagem = isEstadual ? "IE" : "IM";

			String vBC = null;
			String pICMS = null;
			String vICMS = null;
			String pRedBC = null;

			if (StringUtils.isNotBlank(det.getPicms00())) {
				vBC = det.getVbc00();
				pICMS = det.getPicms00();
				vICMS = det.getVicms00();
			} else if (StringUtils.isNotBlank(det.getPicms20())) {
				vBC = det.getVbc20();
				pICMS = det.getPicms20();
				vICMS = det.getVicms20();
				pRedBC = det.getpRedBC();
			}

			String vDesconto = det.getVdesconto();
			String vPgto = det.getVpgto();
			BigDecimal passagem = new BigDecimal(vPgto == null ? "0.0" : vPgto);

			BigDecimal tarifa = new BigDecimal(det.getVcomp01() == null ? "0.0" : det.getVcomp01());
			tarifa = MoneyHelper.subtrair(tarifa, new BigDecimal(vDesconto == null ? "0.0" : vDesconto));

			BigDecimal isentos = BigDecimal.ZERO;

			BigDecimal pedagio = isReceitaTerceiros ? new BigDecimal(det.getVcomp02() == null ? "0.0" : det.getVcomp02()) : BigDecimal.ZERO;
			BigDecimal pedagioIsento = isEstadual && !det.getIndPedagioEstdual() ? pedagio : BigDecimal.ZERO;
			if (pedagioIsento.compareTo(BigDecimal.ZERO) == 0)
				pedagioIsento = !isEstadual && !det.getIndPedagioMunicipal() ? pedagio : BigDecimal.ZERO;

			BigDecimal taxaEmbarque = isReceitaTerceiros ? new BigDecimal(det.getVcomp03() == null ? "0.0" : det.getVcomp03()) : BigDecimal.ZERO;
			BigDecimal taxaEmbarqueIsento = isEstadual && !det.getIndTxembarqueEstadual() ? taxaEmbarque : BigDecimal.ZERO;
			if (taxaEmbarqueIsento.compareTo(BigDecimal.ZERO) == 0)
				taxaEmbarqueIsento = !isEstadual && !det.getIndTxembarqueMunicipal() ? taxaEmbarque : BigDecimal.ZERO;

			BigDecimal seguro = isReceitaTerceiros ? new BigDecimal(det.getVcomp04() == null ? "0.0" : det.getVcomp04()) : BigDecimal.ZERO;
			BigDecimal seguroIsento = isEstadual && !det.getIndSeguroEstadual() ? seguro : BigDecimal.ZERO;
			if (seguroIsento.compareTo(BigDecimal.ZERO) == 0)
				seguroIsento = isEstadual && !det.getIndSeguroEstadual() ? seguro : BigDecimal.ZERO;

			isentos = MoneyHelper.somar(isentos, pedagioIsento, taxaEmbarqueIsento, seguroIsento);

			BigDecimal aliquota = new BigDecimal(pICMS == null ? "0.0" : pICMS);

			aliquota = (aliquota.intValue() == 0 ? (aliquotaAnt == null ? aliquota : aliquotaAnt) : aliquota);
			if (aliquota != null && aliquota.intValue() > 0)
				aliquotaAnt = aliquota;

			BigDecimal icms = new BigDecimal(vICMS == null ? "0.0" : vICMS);

			BigDecimal cp = null;
			if (isEstadual) {
				cp = det.getPorcRedEstadual() == null ? BigDecimal.ZERO : det.getPorcRedEstadual();
			} else {
				cp = det.getPorcRedMunicipal() == null ? BigDecimal.ZERO : det.getPorcRedMunicipal();
			}

			BigDecimal credPres = MoneyHelper.dividir(MoneyHelper.multiplicar(icms, cp), new BigDecimal("100"));
			BigDecimal icmsRec = MoneyHelper.subtrair(icms, credPres);
			BigDecimal vRedBC = new BigDecimal(pRedBC == null ? "0.0" : pRedBC);

			BigDecimal baseCalculo = new BigDecimal(vBC == null ? "0.0" : vBC);
			BigDecimal outros = isentos.equals(BigDecimal.ZERO) ? BigDecimal.ZERO : MoneyHelper.subtrair(passagem, MoneyHelper.subtrair(isentos, baseCalculo));
			if (pRedBC != null) {
				outros = MoneyHelper.subtrair(passagem, baseCalculo);
				outros = MoneyHelper.subtrair(outros, isentos);
			}

			rdis.add(new FiscalRdi(det.getEstadoOrigem(), tipoViagem, det.getTipoReceita(), tarifa,
					seguro, taxaEmbarque, pedagio, passagem, isentos, outros, vRedBC,
					baseCalculo, aliquota, icms, cp, credPres, icmsRec));
		}

		return rdis;
	}

	private List<DetalhadoFiscal> montaRelatorioRDINoXML(Connection connection, Date inicio, Date fim, Integer empresaId, String ufs, String sql) {

		log.info("Inicio da consulta busca RelatorioRDI BPe: " + new Date());

		List<DetalhadoFiscal> list = new ArrayList<DetalhadoFiscal>();
		try {

			log.info("Consulta RDI Bpe: " + sql);

			NamedParameterStatement ps = new NamedParameterStatement(connection, sql);
			ps.setLong("EMPRESA_ID", Long.valueOf(empresaId));

			ps.setString("DATE_INICIO", DateUtil.getStringDate(inicio, DATE_FORMAT_DMY) + " 00:00:00");
			ps.setString("DATE_FIM", DateUtil.getStringDate(fim, DATE_FORMAT_DMY) + " 23:59:59");
			ps.getStatement().setFetchSize(99999);

			ResultSet rs = ps.executeQuery();
			while (rs.next()) {

				DetalhadoFiscal df = new DetalhadoFiscal();

				df.setCajaId(rs.getLong("cajaId"));
				df.setTipoReceita(rs.getString("tipoReceita"));
				df.setNumoperacion(rs.getString("numoperacion"));
				df.setEstadoId(rs.getInt("estadoId"));
				df.setFechorVenta(rs.getDate("fechorVenta"));
				df.setIcmsInterestadual(rs.getBigDecimal("icmsInterestadual"));
				df.setIcmsIntermunicipal(rs.getBigDecimal("icmsIntermunicipal"));
				df.setIcmsInterestadual(rs.getBigDecimal("icmsInterestadual"));
				df.setRedBaseCalcIcms(rs.getBigDecimal("redBaseCalcIcms"));
				df.setPorcRedMunicipal(rs.getBigDecimal("porcRedMunicipal"));
				df.setPorcRedEstadual(rs.getBigDecimal("porcRedEstadual"));
				df.setTributacaoImportacao(rs.getBigDecimal("tributacaoImportacao"));
				df.setIndTarifaMunicipal(rs.getBoolean("indtarifamunicipal"));
				df.setIndSeguroMunicipal(rs.getBoolean("indseguromunicipal"));
				df.setIndTxembarqueMunicipal(rs.getBoolean("indtxembarquemunicipal"));
				df.setIndPedagioMunicipal(rs.getBoolean("indpedagiomunicipal"));
				df.setIndTarifaEstadual(rs.getBoolean("indtarifaestadual"));
				df.setIndSeguroEstadual(rs.getBoolean("indseguroestadual"));
				df.setIndTxembarqueEstadual(rs.getBoolean("indtxembarqueestadual"));
				df.setIndPedagioEstdual(rs.getBoolean("indpedagioestdual"));
				df.setIsenta(rs.getBoolean("isenta"));
				df.setTarifa(rs.getBigDecimal("tarifa"));
				df.setTaxaEmbarque(rs.getBigDecimal("taxaEmbarque"));
				df.setPedagio(rs.getBigDecimal("pedagio"));
				df.setSeguro(rs.getBigDecimal("seguro"));
				df.setOutros(rs.getBigDecimal("outros"));
				df.setDatamov(rs.getString("datamov"));
				df.setChbpe(rs.getString("chbpe"));
				df.setCodstatus(rs.getString("codstatus"));
				df.setCmunini(rs.getString("cmunini"));
				df.setCmunfim(rs.getString("cmunfim"));
				df.setUfini(rs.getString("ufini"));
				df.setUffim(rs.getString("uffim"));
				df.setNbp(rs.getString("nbp"));
				df.setDhemb(rs.getString("dhemb"));
				df.setCst00(rs.getString("cst00"));
				df.setCst20(rs.getString("cst20"));
				df.setCst45(rs.getString("cst45"));
				df.setCst90(rs.getString("cst90"));
				df.setCstoutrauf(rs.getString("cstoutrauf"));
				df.setCstsn(rs.getString("cstsn"));
				df.setVbc00(rs.getString("vbc00"));
				df.setPicms00(rs.getString("picms00"));
				df.setVicms00(rs.getString("vicms00"));
				df.setVbc20(rs.getString("vbc20"));
				df.setPicms20(rs.getString("picms20"));
				df.setVicms20(rs.getString("vicms20"));
				df.setVbp(rs.getString("vbp"));
				df.setVdesconto(rs.getString("vdesconto"));
				df.setVpgto(rs.getString("vpgto"));
				df.setTpcomp01(rs.getString("tpcomp01"));
				df.setTpcomp02(rs.getString("tpcomp02"));
				df.setTpcomp03(rs.getString("tpcomp03"));
				df.setTpcomp04(rs.getString("tpcomp04"));
				df.setTpcomp05(rs.getString("tpcomp05"));
				df.setTpcomp06(rs.getString("tpcomp06"));
				df.setTpcomp99(rs.getString("tpcomp99"));
				df.setVcomp01(rs.getString("vcomp01"));
				df.setVcomp02(rs.getString("vcomp02"));
				df.setVcomp03(rs.getString("vcomp03"));
				df.setVcomp04(rs.getString("vcomp04"));
				df.setVcomp05(rs.getString("vcomp05"));
				df.setVcomp06(rs.getString("vcomp06"));
				df.setVcomp99(rs.getString("vcomp99"));
				df.setpRedBC(rs.getString("pRedBC"));

				String municipioOrigem = df.getCmunini();
				String estadoOrigem = (StringUtils.isNotBlank(df.getUfini()) ? df.getUfini() : rs.getString("estadoOrigem"));
				String estadoDestino = df.getUffim();

				boolean isInterEstadual = !estadoOrigem.equals(estadoDestino);
				df.setEstadoOrigem(estadoOrigem);
				df.setEstadoDestino(estadoDestino);
				df.setMunicipioOrigem(municipioOrigem);
				df.setInterEstadual(isInterEstadual);

				list.add(df);
			}

			rs.close();
			ps.close();

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

		log.info("Fim da consulta busca RelatorioRDI BPe: " + new Date());

		return list;
	}

	private String sqlRelatorioRDIVendidosNoXML(String ufs) {

		StringBuilder sql = new StringBuilder();
		sql.append("select /*+INDEX(BPE IDX__BPE_BOLETO)*/ ");
		sql.append(" c.boleto_id as cajaId, ");
		sql.append(" 'REC' as tipoReceita, ");
		sql.append(" to_number(c.num_bpe) as num_bpe, ");
		sql.append(" to_number(c.numfoliosistema) as numfoliosistema, ");
		sql.append(" c.numoperacion as numoperacion, ");
		sql.append(" trunc(c.feccreacion) as fechorVenta, ");
		sql.append(" e.estado_id as estadoId, ");
		sql.append(" e.cveestado as estadoOrigem, ");
		sql.append(" ei.icms as icmsInterestadual, ");
		sql.append(" ei.icmsim as icmsIntermunicipal, ");
		sql.append(" 0 as isenta, ");
		sql.append(" ei.porcredbaseicms as redBaseCalcIcms, ");
		sql.append(" ei.porcredmunicipal as porcRedMunicipal, ");
		sql.append(" ei.porcredestadual as porcRedEstadual, ");
		sql.append(" ei.indtarifamunicipal as indtarifamunicipal, ");
		sql.append(" ei.indseguromunicipal as indseguromunicipal, ");
		sql.append(" ei.indtxembarquemunicipal as indtxembarquemunicipal, ");
		sql.append(" ei.indpedagiomunicipal as indpedagiomunicipal, ");
		sql.append(" ei.indtarifaestadual as indtarifaestadual, ");
		sql.append(" ei.indseguroestadual as indseguroestadual, ");
		sql.append(" ei.indtxembarqueestadual as indtxembarqueestadual, ");
		sql.append(" ei.indpedagioestdual as indpedagioestdual, ");
		sql.append(" ei.tributacaoImportacao as tributacaoImportacao, ");
		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(" to_char(trunc(c.feccreacion), 'yyyymmdd') as datamov, ");
		sql.append(" bpe.chbpe, ");
		sql.append(" bpe.codstat as codstatus, ");
		sql.append(" bpe.tipoevento, ");
		sql.append(" bpe.cmunini, ");
		sql.append(" bpe.cmunfim, ");
		sql.append(" bpe.ufini, ");
		sql.append(" bpe.uffim, ");
		sql.append(" bpe.nbp, ");
		sql.append(" bpe.dhemb, ");
		sql.append(" bpe.cst00, ");
		sql.append(" bpe.cst20, ");
		sql.append(" bpe.cst45, ");
		sql.append(" bpe.cst90, ");
		sql.append(" bpe.cstoutrauf, ");
		sql.append(" bpe.cstsn, ");
		sql.append(" bpe.vbc00, ");
		sql.append(" bpe.picms00, ");
		sql.append(" bpe.vicms00, ");
		sql.append(" bpe.vbc20, ");
		sql.append(" bpe.picms20, ");
		sql.append(" bpe.vicms20, ");
		sql.append(" bpe.vbp, ");
		sql.append(" bpe.vdesconto, ");
		sql.append(" bpe.vpgto, ");
		sql.append(" bpe.tpcomp01, ");
		sql.append(" bpe.tpcomp02, ");
		sql.append(" bpe.tpcomp03, ");
		sql.append(" bpe.tpcomp04, ");
		sql.append(" bpe.tpcomp05, ");
		sql.append(" bpe.tpcomp06, ");
		sql.append(" bpe.tpcomp99, ");
		sql.append(" bpe.vcomp01, ");
		sql.append(" bpe.vcomp02, ");
		sql.append(" bpe.vcomp03, ");
		sql.append(" bpe.vcomp04, ");
		sql.append(" bpe.vcomp05, ");
		sql.append(" bpe.vcomp06, ");
		sql.append(" bpe.vcomp99, ");
		sql.append(" bpe.pRedBC ");
		sql.append("from boleto c ");
		sql.append(" join bpe bpe on c.boleto_id = bpe.boleto_id ");
		sql.append("  	and bpe.activo = (case when c.motivocancelacion_id = 17 and c.boletooriginal_id is null then 0 else 1 end)");
		sql.append(" join estado e on e.codibge = bpe.uf ");
		sql.append(" join marca ma on c.marca_id = ma.marca_id ");
		sql.append(" join empresa ep on ma.empresa_id = ep.empresa_id ");
		sql.append(" join ruta r on r.ruta_id = c.ruta_id ");
		sql.append(" left join empresa_imposto ei on ei.empresa_id = ep.empresa_id and ei.estado_id = e.estado_id and ei.activo = 1 ");
		sql.append("where c.activo = 1 and e.activo = 1 and ei.activo = 1 ");
		sql.append(" and bpe.tipoamb = 1 and ep.activo = 1 ");
		sql.append(" and bpe.codstat in ('-1','100','101','102','135','150') ");
		sql.append(" and (bpe.tipoevento not in ('110115','110116') or bpe.tipoevento is null) ");
		sql.append(" and c.feccreacion >= to_date(:DATE_INICIO,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append(" and c.feccreacion <= to_date(:DATE_FIM,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append(" and ep.empresa_id = :EMPRESA_ID ");
		sql.append(" and e.cveestado in ( ").append(ufs).append(" ) ");
		sql.append(" and (bpe.xmlregular is not null or bpe.xmlcontingencia is not null) ");
		sql.append("order by numfoliosistema, num_bpe, datamov, tipoevento desc ");
		return sql.toString();

	}

	private String sqlRelatorioRDICanceladosSubstituidosNoXML(String ufs) {

		StringBuilder sql = new StringBuilder();
		sql.append("select /*+INDEX(BPE IDX__BPE_BOLETO)*/ ");
		sql.append("  bori.boleto_id as cajaId, ");
		sql.append("  'DEV' as tipoReceita, ");
		sql.append("  to_number(bori.num_bpe) as num_bpe, ");
		sql.append("  to_number(bori.numfoliosistema) as numfoliosistema, ");
		sql.append("  bori.numoperacion as numoperacion, ");
		sql.append("  trunc(bori.feccreacion) as fechorVenta, ");
		sql.append("  est_bpe.estado_id as estadoId, ");
		sql.append("  est_bpe.cveestado as estadoOrigem, ");
		sql.append("  ei.icms as icmsInterestadual, ");
		sql.append("  ei.icmsim as icmsIntermunicipal, ");
		sql.append("  0 as isenta, ");
		sql.append("  ei.porcredbaseicms as redBaseCalcIcms, ");
		sql.append("  ei.porcredmunicipal as porcRedMunicipal, ");
		sql.append("  ei.porcredestadual as porcRedEstadual, ");
		sql.append("  ei.indtarifamunicipal as indtarifamunicipal, ");
		sql.append("  ei.indseguromunicipal as indseguromunicipal, ");
		sql.append("  ei.indtxembarquemunicipal as indtxembarquemunicipal, ");
		sql.append("  ei.indpedagiomunicipal as indpedagiomunicipal, ");
		sql.append("  ei.indtarifaestadual as indtarifaestadual, ");
		sql.append("  ei.indseguroestadual as indseguroestadual, ");
		sql.append("  ei.indtxembarqueestadual as indtxembarqueestadual, ");
		sql.append("  ei.indpedagioestdual as indpedagioestdual, ");
		sql.append("  ei.tributacaoImportacao as tributacaoImportacao, ");
		sql.append("  coalesce(bori.preciopagado, 0)  as tarifa, ");
		sql.append("  coalesce(bori.importetaxaembarque, 0) as taxaEmbarque, ");
		sql.append("  coalesce(bori.importepedagio, 0) as pedagio, ");
		sql.append("  coalesce(bori.importeseguro, 0) as seguro, ");
		sql.append("  coalesce(bori.importeoutros, 0) as outros, ");
		sql.append("  to_char(trunc(bori.feccreacion), 'yyyymmdd') as datamov, ");
		sql.append("  bpeori.chbpe, ");
		sql.append("  bpe.codstat as codstatus, ");
		sql.append("  case when bpe.ufini is not null then bpe.cmunini else bpeori.cmunini end as cmunini, ");
		sql.append("  case when bpe.ufini is not null then bpe.cmunfim else bpeori.cmunfim end as cmunfim, ");
		sql.append("  case when bpe.ufini is not null then bpe.ufini else bpeori.ufini end as ufini, ");
		sql.append("  case when bpe.ufini is not null then bpe.uffim else bpeori.uffim end as uffim, ");
		sql.append("  case when bpe.ufini is not null then bpe.nbp  else bpeori.nbp  end as nbp, ");
		sql.append("  case when bpe.ufini is not null then bpe.dhemb else bpeori.dhemb end as dhemb, ");
		sql.append("  case when bpe.ufini is not null then bpe.cst00 else bpeori.cst00 end as cst00, ");
		sql.append("  case when bpe.ufini is not null then bpe.cst20 else bpeori.cst20 end as cst20, ");
		sql.append("  case when bpe.ufini is not null then bpe.cst45 else bpeori.cst45 end as cst45, ");
		sql.append("  case when bpe.ufini is not null then bpe.cst90 else bpeori.cst90 end as cst90, ");
		sql.append("  case when bpe.ufini is not null then bpe.cstoutrauf else bpeori.cstoutrauf end as cstoutrauf, ");
		sql.append("  case when bpe.ufini is not null then bpe.cstsn else bpeori.cstsn end as cstsn, ");
		sql.append("  case when bpe.ufini is not null then bpe.vbc00 else bpeori.vbc00 end as vbc00, ");
		sql.append("  case when bpe.ufini is not null then bpe.picms00 else bpeori.picms00 end as picms00, ");
		sql.append("  case when bpe.ufini is not null then bpe.vicms00 else bpeori.vicms00 end as vicms00, ");
		sql.append("  case when bpe.ufini is not null then bpe.vbc20 else bpeori.vbc20 end as vbc20, ");
		sql.append("  case when bpe.ufini is not null then bpe.picms20 else bpeori.picms20 end as picms20, ");
		sql.append("  case when bpe.ufini is not null then bpe.vicms20 else bpeori.vicms20 end as vicms20, ");
		sql.append("  case when bpe.ufini is not null then bpe.vbp else bpeori.vbp end as vbp, ");
		sql.append("  case when bpe.ufini is not null then bpe.vdesconto else bpeori.vdesconto end as vdesconto, ");
		sql.append("  case when bpe.ufini is not null then bpe.vpgto else bpeori.vpgto end as vpgto, ");
		sql.append("  case when bpe.ufini is not null then bpe.tpcomp01 else bpeori.tpcomp01 end as tpcomp01, ");
		sql.append("  case when bpe.ufini is not null then bpe.tpcomp02 else bpeori.tpcomp02 end as tpcomp02, ");
		sql.append("  case when bpe.ufini is not null then bpe.tpcomp03 else bpeori.tpcomp03 end as tpcomp03, ");
		sql.append("  case when bpe.ufini is not null then bpe.tpcomp04 else bpeori.tpcomp04 end as tpcomp04, ");
		sql.append("  case when bpe.ufini is not null then bpe.tpcomp05 else bpeori.tpcomp05 end as tpcomp05, ");
		sql.append("  case when bpe.ufini is not null then bpe.tpcomp06 else bpeori.tpcomp06 end as tpcomp06, ");
		sql.append("  case when bpe.ufini is not null then bpe.tpcomp99 else bpeori.tpcomp99 end as tpcomp99, ");
		sql.append("  case when bpe.ufini is not null then bpe.vcomp01 else bpeori.vcomp01 end as vcomp01, ");
		sql.append("  case when bpe.ufini is not null then bpe.vcomp02 else bpeori.vcomp02 end as vcomp02, ");
		sql.append("  case when bpe.ufini is not null then bpe.vcomp03 else bpeori.vcomp03 end as vcomp03, ");
		sql.append("  case when bpe.ufini is not null then bpe.vcomp04 else bpeori.vcomp04 end as vcomp04, ");
		sql.append("  case when bpe.ufini is not null then bpe.vcomp05 else bpeori.vcomp05 end as vcomp05, ");
		sql.append("  case when bpe.ufini is not null then bpe.vcomp06 else bpeori.vcomp06 end as vcomp06, ");
		sql.append("  case when bpe.ufini is not null then bpe.vcomp99 else bpeori.vcomp99 end as vcomp99, ");
		sql.append("  case when bpe.ufini is not null then bpe.predbc else bpeori.predbc end as predbc ");
		sql.append("from boleto bori ");
		sql.append("  inner join marca m on m.marca_id = bori.marca_id and m.activo = 1 ");
		sql.append("  inner join empresa e on e.empresa_id = m.empresa_id ");
		sql.append("  inner join bpe bpe on bpe.boleto_id = bori.boleto_id ");
		sql.append("  	and bpe.activo = (case when bori.motivocancelacion_id = 17 and bori.boletooriginal_id is null then 0 else 1 end) ");
		sql.append("  inner join estado est_bpe on bpe.uf = est_bpe.codibge ");
		sql.append("  left join bpe bpeori on bpeori.chbpe = bpe.chbpe_substituicao and bpeori.activo = 1 ");
		sql.append("  left join boleto b on b.boleto_id = bpeori.boleto_id ");
		sql.append("  inner join punto_venta ptv on ptv.puntoventa_id = b.puntoventa_id ");
		sql.append("  join inscricao_estadual ie on e.empresa_id = ie.empresa_id and ie.estado_id = est_bpe.estado_id and ie.activo = 1 ");
		sql.append("  join empresa_imposto ei on ei.empresa_id = e.empresa_id and ei.estado_id = est_bpe.estado_id and ei.activo = 1 ");
		sql.append("  left join aidf aidf on aidf.aidf_id = b.aidf_id and b.tipoventa_id = 3 ");
		sql.append("  left join estado esaidf on esaidf.estado_id = aidf.estado_id ");
		sql.append("  left join boleto bant on bant.boleto_id = (case when bpeori.tipoevento is not null then coalesce(b.boletoanterior_id, b.boletooriginal_id) else null end) ");
		sql.append("  left join bpe bpeant on bpeant.boleto_id = bant.boleto_id and bpeant.activo = 1 ");
		sql.append("  left join punto_venta ptvo on ptvo.puntoventa_id = coalesce(bant.puntoventa_id, bori.puntoventa_id,b.ptovtaventa_id) ");
		sql.append("where ( (bpe.codstat in ('-1','100','101','102','135','150') and bpe.chbpe_substituicao is not null) ");
		sql.append("    or (bpe.codstat in ('101','135') and to_char(b.feccreacion, 'mm/yyyy') < to_char(bori.feccreacion, 'mm/yyyy')) ) ");
		sql.append("    and (bpe.codstat in ('-1','100','101','102','135','150') and bpe.tipoevento not in ('110115','110116') or bpe.tipoevento is null) ");
		sql.append("    and (bpeori.codstat in ('-1','100','101','102','135','150') and bpeori.tipoevento not in ('110115','110116') or bpeori.tipoevento is null) ");
		sql.append("    and bori.feccreacion >= to_date(:DATE_INICIO,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append("    and bori.feccreacion <= to_date(:DATE_FIM,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append("    and est_bpe.cveestado in ( ").append(ufs).append(" ) ");
		sql.append("    and e.empresa_id = :EMPRESA_ID   ");
		sql.append("   and (bpe.xmlregular is not null or bpe.xmlcontingencia is not null) ");
		return sql.toString();

	}

	private String sqlRelatorioRDICanceladosNoXML(String ufs) {

		StringBuilder sql = new StringBuilder();
		sql.append("select /*+INDEX(BPE IDX__BPE_BOLETO)*/ ");
		sql.append("  b.boleto_id as cajaId, ");
		sql.append("  'DEV' as tipoReceita, ");
		sql.append("  to_number(b.num_bpe) as num_bpe, ");
		sql.append("  to_number(b.numfoliosistema) as numfoliosistema, ");
		sql.append("  b.numoperacion as numoperacion, ");
		sql.append("  trunc(bori.feccreacion) as fechorVenta, ");
		sql.append("  est_bpe.estado_id as estadoId, ");
		sql.append("  est_bpe.cveestado as estadoOrigem, ");
		sql.append("  ei.icms as icmsInterestadual, ");
		sql.append("  ei.icmsim as icmsIntermunicipal, ");
		sql.append("  0 as isenta, ");
		sql.append("  ei.porcredbaseicms as redBaseCalcIcms, ");
		sql.append("  ei.porcredmunicipal as porcRedMunicipal, ");
		sql.append("  ei.porcredestadual as porcRedEstadual, ");
		sql.append("  ei.indtarifamunicipal as indtarifamunicipal, ");
		sql.append("  ei.indseguromunicipal as indseguromunicipal, ");
		sql.append("  ei.indtxembarquemunicipal as indtxembarquemunicipal, ");
		sql.append("  ei.indpedagiomunicipal as indpedagiomunicipal, ");
		sql.append("  ei.indtarifaestadual as indtarifaestadual, ");
		sql.append("  ei.indseguroestadual as indseguroestadual, ");
		sql.append("  ei.indtxembarqueestadual as indtxembarqueestadual, ");
		sql.append("  ei.indpedagioestdual as indpedagioestdual, ");
		sql.append("  ei.tributacaoImportacao as tributacaoImportacao, ");
		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("  to_char(trunc(bori.feccreacion), 'yyyymmdd') as datamov, ");
		sql.append("  bpe.chbpe, ");
		sql.append("  bpe.codstat as codstatus, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.cmunini else bpe.cmunini end as cmunini, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.cmunfim else bpe.cmunfim end as cmunfim, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.ufini else bpe.ufini end as ufini, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.uffim else bpe.uffim end as uffim, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.nbp  else bpe.nbp  end as nbp, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.dhemb else bpe.dhemb end as dhemb, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.cst00 else bpe.cst00 end as cst00, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.cst20 else bpe.cst20 end as cst20, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.cst45 else bpe.cst45 end as cst45, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.cst90 else bpe.cst90 end as cst90, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.cstoutrauf else bpe.cstoutrauf end as cstoutrauf, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.cstsn else bpe.cstsn end as cstsn, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vbc00 else bpe.vbc00 end as vbc00, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.picms00 else bpe.picms00 end as picms00, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vicms00 else bpe.vicms00 end as vicms00, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vbc20 else bpe.vbc20 end as vbc20, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.picms20 else bpe.picms20 end as picms20, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vicms20 else bpe.vicms20 end as vicms20, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vbp else bpe.vbp end as vbp, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vdesconto else bpe.vdesconto end as vdesconto, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vpgto else bpe.vpgto end as vpgto, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.tpcomp01 else bpe.tpcomp01 end as tpcomp01, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.tpcomp02 else bpe.tpcomp02 end as tpcomp02, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.tpcomp03 else bpe.tpcomp03 end as tpcomp03, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.tpcomp04 else bpe.tpcomp04 end as tpcomp04, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.tpcomp05 else bpe.tpcomp05 end as tpcomp05, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.tpcomp06 else bpe.tpcomp06 end as tpcomp06, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.tpcomp99 else bpe.tpcomp99 end as tpcomp99, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vcomp01 else bpe.vcomp01 end as vcomp01, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vcomp02 else bpe.vcomp02 end as vcomp02, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vcomp03 else bpe.vcomp03 end as vcomp03, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vcomp04 else bpe.vcomp04 end as vcomp04, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vcomp05 else bpe.vcomp05 end as vcomp05, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vcomp06 else bpe.vcomp06 end as vcomp06, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.vcomp99 else bpe.vcomp99 end as vcomp99, ");
		sql.append("  case when bpeori.ufini is not null then bpeori.predbc else bpe.predbc end as predbc ");
		sql.append("from boleto bori ");
		sql.append("  inner join marca m on m.marca_id = bori.marca_id and m.activo = 1 ");
		sql.append("  inner join empresa e on e.empresa_id = m.empresa_id ");
		sql.append("  inner join bpe bpe on bpe.boleto_id = bori.boleto_id ");
		sql.append("  	and bpe.activo = (case when bori.motivocancelacion_id = 17 and bori.boletooriginal_id is null then 0 else 1 end) ");
		sql.append("  inner join estado est_bpe on bpe.uf = est_bpe.codibge ");
		sql.append("  left join boleto b on b.boleto_id = coalesce(bori.boletoanterior_id, bori.boletooriginal_id)  ");
		sql.append("  left join bpe bpeori on b.boleto_id = bpeori.boleto_id and bpeori.activo = 1 ");
		sql.append("  inner join punto_venta ptv on ptv.puntoventa_id = bori.puntoventa_id ");
		sql.append("join inscricao_estadual ie on e.empresa_id = ie.empresa_id and ie.estado_id = est_bpe.estado_id and ie.activo = 1 ");
		sql.append("join empresa_imposto ei on ei.empresa_id = e.empresa_id and ei.estado_id = est_bpe.estado_id and ei.activo = 1 ");
		sql.append("left join aidf aidf on aidf.aidf_id = b.aidf_id and b.tipoventa_id = 3 ");
		sql.append("left join estado esaidf on esaidf.estado_id = aidf.estado_id ");
		sql.append("left join punto_venta ptvo on ptvo.puntoventa_id = coalesce(b.ptovtaventa_id, bori.puntoventa_id) ");
		sql.append("where ");
		sql.append("    (bpe.codstat in ('101','135') and to_char(b.feccreacion, 'mm/yyyy') < to_char(bori.feccreacion, 'mm/yyyy')) ");
		sql.append("    and (bpe.codstat in ('-1','100','101','102','135','150') and bpe.tipoevento not in ('110115','110116') or bpe.tipoevento is null) ");
		sql.append("    and (bpeori.codstat in ('-1','100','101','102','135','150') and bpeori.tipoevento not in ('110115','110116') or bpeori.tipoevento is null) ");
		sql.append("    and bori.feccreacion >= to_date(:DATE_INICIO,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append("    and bori.feccreacion <= to_date(:DATE_FIM,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append("    and est_bpe.cveestado in ( ").append(ufs).append(" ) ");
		sql.append("    and e.empresa_id = :EMPRESA_ID   ");
		sql.append("   and (bpe.xmlregular is not null or bpe.xmlcontingencia is not null) ");

		sql.append("order by numfoliosistema, num_bpe, datamov ");

		System.out.println(sql.toString());
		return sql.toString();
	}

	@Deprecated
	private List<FiscalRdi> calcularRelatorioRDIXML(List<DetalhadoFiscal> list, boolean isReceitaTerceiros) {

		List<FiscalRdi> rdis = new ArrayList<FiscalRdi>();

		BigDecimal aliquotaAnt = null;
		for (DetalhadoFiscal det : list) {

			String xml = det.getXml();

			BigDecimal tarifa = BigDecimal.ZERO;
			BigDecimal taxaEmbarque = BigDecimal.ZERO;
			BigDecimal pedagio = BigDecimal.ZERO;
			BigDecimal seguro = BigDecimal.ZERO;
			BigDecimal passagem = BigDecimal.ZERO;
			BigDecimal isentos = BigDecimal.ZERO;

			boolean isEstadual = det.isInterEstadual();
			String tipoViagem = isEstadual ? "IE" : "IM";

			TBPe tbpe = null;
			if (StringUtils.isNotBlank(xml))
				tbpe = BPeUtil.convertXmlToBpe(xml);

			String vBC = null;
			String pICMS = null;
			String vICMS = null;
			String pRedBC = null;

			if (StringUtils.isNotBlank(xml)) {
				if (tbpe.getInfBPe().getImp().getICMS().getICMS00() != null) {
					vBC = tbpe.getInfBPe().getImp().getICMS().getICMS00().getVBC();
					pICMS = tbpe.getInfBPe().getImp().getICMS().getICMS00().getPICMS();
					vICMS = tbpe.getInfBPe().getImp().getICMS().getICMS00().getVICMS();
				} else if (tbpe.getInfBPe().getImp().getICMS().getICMS20() != null) {
					vBC = tbpe.getInfBPe().getImp().getICMS().getICMS20().getVBC();
					pICMS = tbpe.getInfBPe().getImp().getICMS().getICMS20().getPICMS();
					vICMS = tbpe.getInfBPe().getImp().getICMS().getICMS20().getVICMS();
					pRedBC = tbpe.getInfBPe().getImp().getICMS().getICMS20().getPRedBC();
				}

				if (tbpe.getInfBPe().getInfValorBPe() != null) {

					String vPgto = tbpe.getInfBPe().getInfValorBPe().getVPgto();
					passagem = new BigDecimal(vPgto == null ? "0.0" : vPgto);

					for (TBPe.InfBPe.InfValorBPe.Comp comp : tbpe.getInfBPe().getInfValorBPe().getComp()) {
						if (comp.getTpComp().equals(TipoComp.TARIFA)) {
							String vDesconto = tbpe.getInfBPe().getInfValorBPe().getVDesconto();
							tarifa = new BigDecimal(comp.getVComp() == null ? "0.0" : comp.getVComp());
							tarifa = tarifa.subtract(new BigDecimal(vDesconto == null ? "0.0" : vDesconto));
						}

						if (comp.getTpComp().equals(TipoComp.PEDAGIO)) {
							pedagio = isReceitaTerceiros ? new BigDecimal(det.getVcomp02() == null ? "0.0" : det.getVcomp02()) : BigDecimal.ZERO;
							BigDecimal pedagioIsento = isEstadual && !det.getIndPedagioEstdual() ? pedagio : BigDecimal.ZERO;
							if (pedagioIsento.compareTo(BigDecimal.ZERO) == 0)
								pedagioIsento = !isEstadual && !det.getIndPedagioMunicipal() ? pedagio : BigDecimal.ZERO;

							isentos = isentos.add(pedagioIsento);
						}

						if (comp.getTpComp().equals(TipoComp.TAXA_EMBARQUE)) {
							taxaEmbarque = isReceitaTerceiros ? new BigDecimal(det.getVcomp03() == null ? "0.0" : det.getVcomp03()) : BigDecimal.ZERO;
							BigDecimal taxaEmbarqueIsento = isEstadual && !det.getIndTxembarqueEstadual() ? taxaEmbarque : BigDecimal.ZERO;
							if (taxaEmbarqueIsento.compareTo(BigDecimal.ZERO) == 0)
								taxaEmbarqueIsento = !isEstadual && !det.getIndTxembarqueMunicipal() ? taxaEmbarque : BigDecimal.ZERO;

							isentos = isentos.add(taxaEmbarqueIsento);
						}

						if (comp.getTpComp().equals(TipoComp.SEGURO)) {
							seguro = isReceitaTerceiros ? new BigDecimal(det.getVcomp04() == null ? "0.0" : det.getVcomp04()) : BigDecimal.ZERO;
							BigDecimal seguroIsento = isEstadual && !det.getIndSeguroEstadual() ? seguro : BigDecimal.ZERO;
							if (seguroIsento.compareTo(BigDecimal.ZERO) == 0)
								seguroIsento = isEstadual && !det.getIndSeguroEstadual() ? seguro : BigDecimal.ZERO;

							isentos = isentos.add(seguroIsento);
						}
					}
				}
			}

			BigDecimal baseCalculo = new BigDecimal(vBC == null ? "0.0" : vBC);

			BigDecimal aliquota = new BigDecimal(pICMS == null ? "0.0" : pICMS);
			aliquota = (aliquota.intValue() == 0 ? (aliquotaAnt == null ? aliquota : aliquotaAnt) : aliquota);
			if (aliquota != null && aliquota.intValue() > 0)
				aliquotaAnt = aliquota;

			BigDecimal icms = new BigDecimal(vICMS == null ? "0.0" : vICMS);

			BigDecimal cp = null;
			if (isEstadual) {
				cp = det.getPorcRedEstadual() == null ? BigDecimal.ZERO : det.getPorcRedEstadual();
			} else {
				cp = det.getPorcRedMunicipal() == null ? BigDecimal.ZERO : det.getPorcRedMunicipal();
			}

			BigDecimal credPres = icms.multiply(cp.divide(BigDecimal.TEN.multiply(BigDecimal.TEN)));
			BigDecimal icmsRec = icms.subtract(credPres);
			BigDecimal vRedBC = det.getRedBaseCalcIcms();

			BigDecimal outros = isentos.equals(BigDecimal.ZERO) ? BigDecimal.ZERO : passagem.subtract(isentos).subtract(baseCalculo);
			if (pRedBC != null) {
				outros = passagem.subtract(baseCalculo);
				outros = outros.subtract(isentos);
			}

			rdis.add(new FiscalRdi(det.getEstadoOrigem(), tipoViagem, det.getTipoReceita(), tarifa,
					seguro, taxaEmbarque, pedagio, passagem, isentos, outros, vRedBC,
					baseCalculo, aliquota, icms, cp, credPres, icmsRec));
		}

		return rdis;
	}

	@Deprecated
	private List<DetalhadoFiscal> montaRelatorioRDIXML(Connection connection, Date inicio, Date fim, Integer empresaId, String ufs, String sql) {

		List<DetalhadoFiscal> list = new ArrayList<DetalhadoFiscal>();
		try {

			NamedParameterStatement ps = new NamedParameterStatement(connection, sql);
			ps.setLong("EMPRESA_ID", Long.valueOf(empresaId));

			ps.setTimestamp("DATE_INICIO", new java.sql.Timestamp(DateUtil.inicioFecha(inicio).getTime()));
			ps.setTimestamp("DATE_FIM", new java.sql.Timestamp(DateUtil.fimFecha(fim).getTime()));

			ResultSet rs = ps.executeQuery();
			while (rs.next()) {

				String xml_bpe = rs.getNString("xml_bpe");
				String xml_bpe_2 = rs.getNString("xml_bpe_2");
				String xml_bpe_3 = rs.getNString("xml_bpe_3");
				String xml = StringUtils.join(new String[] { xml_bpe, xml_bpe_2, xml_bpe_3 });

				TBPe tbpe = null;
				if (StringUtils.isNotBlank(xml))
					tbpe = BPeUtil.convertXmlToBpe(xml);

				DetalhadoFiscal df = new DetalhadoFiscal();
				df.setXml(xml);

				String municipioOrigem = StringUtils.isNotBlank(xml) ? tbpe.getInfBPe().getIde().getCMunIni() : rs.getString("municipioOrigem");
				String estadoOrigem = (StringUtils.isNotBlank(xml) ? tbpe.getInfBPe().getIde().getUFIni().value() : rs.getString("estadoOrigem"));
				String estadoDestino = (StringUtils.isNotBlank(xml) ? tbpe.getInfBPe().getIde().getUFFim().value() : rs.getString("estadoDestino"));

				boolean isInterEstadual = !estadoOrigem.equals(estadoDestino);
				df.setEstadoOrigem(estadoOrigem);
				df.setEstadoDestino(estadoDestino);
				df.setMunicipioOrigem(municipioOrigem);
				df.setInterEstadual(isInterEstadual);
				df.setCajaId(rs.getLong("cajaId"));
				df.setTipoReceita(rs.getString("tipoReceita"));
				df.setNumoperacion(rs.getString("numoperacion"));
				df.setEstadoId(rs.getInt("estadoId"));
				df.setFechorVenta(rs.getDate("fechorVenta"));
				df.setIcmsInterestadual(rs.getBigDecimal("icmsInterestadual"));
				df.setIcmsIntermunicipal(rs.getBigDecimal("icmsIntermunicipal"));
				df.setIcmsInterestadual(rs.getBigDecimal("icmsInterestadual"));
				df.setRedBaseCalcIcms(rs.getBigDecimal("redBaseCalcIcms"));
				df.setPorcRedMunicipal(rs.getBigDecimal("porcRedMunicipal"));
				df.setPorcRedEstadual(rs.getBigDecimal("porcRedEstadual"));
				df.setTributacaoImportacao(rs.getBigDecimal("tributacaoImportacao"));
				df.setIndTarifaMunicipal(rs.getBoolean("indtarifamunicipal"));
				df.setIndSeguroMunicipal(rs.getBoolean("indseguromunicipal"));
				df.setIndTxembarqueMunicipal(rs.getBoolean("indtxembarquemunicipal"));
				df.setIndPedagioMunicipal(rs.getBoolean("indpedagiomunicipal"));
				df.setIndTarifaEstadual(rs.getBoolean("indtarifaestadual"));
				df.setIndSeguroEstadual(rs.getBoolean("indseguroestadual"));
				df.setIndTxembarqueEstadual(rs.getBoolean("indtxembarqueestadual"));
				df.setIndPedagioEstdual(rs.getBoolean("indpedagioestdual"));
				df.setIsenta(rs.getBoolean("isenta"));
				df.setTarifa(rs.getBigDecimal("tarifa"));
				df.setTaxaEmbarque(rs.getBigDecimal("taxaEmbarque"));
				df.setPedagio(rs.getBigDecimal("pedagio"));
				df.setSeguro(rs.getBigDecimal("seguro"));
				df.setOutros(rs.getBigDecimal("outros"));
				df.setDatamov(rs.getString("datamov"));
				list.add(df);
			}

			rs.close();
			ps.close();

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

		return list;
	}

	@Deprecated
	private String sqlRelatorioRDIVendidosXML(String ufs) {

		StringBuilder sql = new StringBuilder();
		sql.append("select ");
		sql.append("  c.boleto_id as cajaId, ");
		sql.append("  'REC' as tipoReceita, ");
		sql.append("  c.numoperacion as numoperacion, ");
		sql.append("  trunc(c.feccreacion) as fechorVenta, ");
		sql.append("  e.estado_id as estadoId, ");
		sql.append("  ei.icms as icmsInterestadual, ");
		sql.append("  ei.icmsim as icmsIntermunicipal, ");
		sql.append("  e.cveestado as estadoOrigem, ");
		sql.append("  ed.cveestado as estadoDestino, ");
		sql.append("  co.codibge as municipioOrigem, ");
		sql.append("  case when (e.cveestado = ed.cveestado)  then 0 else 1 end as isInterEstadual, ");
		sql.append("  0 as isenta, ");
		sql.append("  ei.porcredbaseicms as redBaseCalcIcms, ");
		sql.append("  ei.porcredmunicipal as porcRedMunicipal, ");
		sql.append("  ei.porcredestadual as porcRedEstadual, ");
		sql.append("  ei.indtarifamunicipal as indtarifamunicipal, ");
		sql.append("  ei.indseguromunicipal as indseguromunicipal, ");
		sql.append("  ei.indtxembarquemunicipal as indtxembarquemunicipal, ");
		sql.append("  ei.indpedagiomunicipal as indpedagiomunicipal, ");
		sql.append("  ei.indtarifaestadual as indtarifaestadual, ");
		sql.append("  ei.indseguroestadual as indseguroestadual, ");
		sql.append("  ei.indtxembarqueestadual as indtxembarqueestadual, ");
		sql.append("  ei.indpedagioestdual as indpedagioestdual, ");
		sql.append("  ei.tributacaoImportacao as tributacaoImportacao, ");
		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("  to_char(trunc(c.feccreacion), 'yyyymmdd') as datamov, ");
		sql.append("  DBMS_LOB.substr(coalesce(bpe.xmlregular, bpe.xmlcontingencia), 3000) as xml_bpe, ");
		sql.append("  DBMS_LOB.substr(coalesce(bpe.xmlregular, bpe.xmlcontingencia), 3000, 3001) as xml_bpe_2, ");
		sql.append("  DBMS_LOB.substr(coalesce(bpe.xmlregular, bpe.xmlcontingencia), 3000, 6001) as xml_bpe_3 ");
		sql.append("from boleto c ");
		sql.append("  join bpe bpe on c.boleto_id = bpe.boleto_id ");
		sql.append("        and bpe.activo = (case when c.motivocancelacion_id = 17 and c.boletooriginal_id is null then 0 else 1 end) ");
		sql.append("  left join bpe bpecan on bpecan.chbpe = bpe.chbpe and bpecan.codstat in ('101','135') and bpe.codstat = '100' ");
		sql.append("                        and (bpecan.tipoevento = '110111' or bpecan.tipoevento is null) and bpecan.activo = 1 ");
		sql.append("  join estado e on e.codibge = bpe.uf ");
		sql.append("  join marca ma on c.marca_id = ma.marca_id ");
		sql.append("  join empresa ep on ma.empresa_id = ep.empresa_id ");
		sql.append("  join ruta r on r.ruta_id = c.ruta_id ");
		sql.append("  left join alias_servico ase on ase.origen_id = c.origen_id ");
		sql.append("  		and ase.destino_id = c.destino_id and ase.ruta_id = c.ruta_id and ase.activo = 1 and ase.corrida_id is null and ase.activo = 1 ");
		sql.append("  inner join parada o on coalesce(ase.aliasorigen_id, c.origen_id) = o.parada_id ");
		sql.append("  inner join ciudad co on o.ciudad_id = co.ciudad_id ");
		sql.append("  inner join estado eo on eo.estado_id = co.estado_id ");
		sql.append("  inner join parada d on coalesce(ase.aliasdestino_id, c.destino_id) = d.parada_id ");
		sql.append("  inner join ciudad cd on d.ciudad_id = cd.ciudad_id ");
		sql.append("  inner join estado ed on ed.estado_id = cd.estado_id ");
		sql.append("  left join empresa_imposto ei on ei.empresa_id = ep.empresa_id and ei.estado_id = e.estado_id and ei.activo = 1 ");
		sql.append("where c.activo = 1 and bpe.tipoamb = 1 and bpe.codstat in ('-1','100','102','150') ");
		sql.append("  and (bpe.fecmodif < (case when (to_char(bpe.fecmodif, 'mm/yyyy') <> to_char(bpecan.fecmodif, 'mm/yyyy') ) ");
		sql.append("          then bpecan.fecmodif else bpe.fecmodif end) or bpecan.fecmodif is null) ");
		sql.append("  and c.feccreacion >= :DATE_INICIO ");
		sql.append("  and c.feccreacion <= :DATE_FIM ");
		sql.append("  and ep.empresa_id = :EMPRESA_ID  ");
		sql.append("  and (bpe.xmlregular is not null or bpe.xmlcontingencia is not null) ");
		sql.append("  and e.cveestado in ( ").append(ufs).append(" )  ");

		return sql.toString();
	}

	@Deprecated
	private String sqlRelatorioRDICanceladosXML(String ufs) {

		StringBuilder sql = new StringBuilder();
		sql.append("select ");
		sql.append("  b.boleto_id as cajaId, ");
		sql.append("  'DEV' as tipoReceita, ");
		sql.append("  b.numoperacion as numoperacion, ");
		sql.append("  trunc(bori.feccreacion) as fechorVenta, ");
		sql.append("  est_bpe.estado_id as estadoId, ");
		sql.append("  ei.icms as icmsInterestadual, ");
		sql.append("  ei.icmsim as icmsIntermunicipal, ");
		sql.append("  est_bpe.cveestado as estadoOrigem, ");
		sql.append("  eds.cveestado as estadoDestino, ");
		sql.append("  co.codibge as municipioOrigem, ");
		sql.append("  case when (est_bpe.cveestado = eds.cveestado)  then 0 else 1 end as isInterEstadual, ");
		sql.append("  0 as isenta, ");
		sql.append("  ei.porcredbaseicms as redBaseCalcIcms, ");
		sql.append("  ei.porcredmunicipal as porcRedMunicipal, ");
		sql.append("  ei.porcredestadual as porcRedEstadual, ");
		sql.append("  ei.indtarifamunicipal as indtarifamunicipal, ");
		sql.append("  ei.indseguromunicipal as indseguromunicipal, ");
		sql.append("  ei.indtxembarquemunicipal as indtxembarquemunicipal, ");
		sql.append("  ei.indpedagiomunicipal as indpedagiomunicipal, ");
		sql.append("  ei.indtarifaestadual as indtarifaestadual, ");
		sql.append("  ei.indseguroestadual as indseguroestadual, ");
		sql.append("  ei.indtxembarqueestadual as indtxembarqueestadual, ");
		sql.append("  ei.indpedagioestdual as indpedagioestdual, ");
		sql.append("  ei.tributacaoImportacao as tributacaoImportacao, ");
		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("  to_char(trunc(bori.feccreacion), 'yyyymmdd') as datamov, ");
		sql.append("  dbms_lob.substr((case when bpeori.tipoevento is not null then bpeant.xmlregular else bpeori.xmlregular end), 3000) as xml_bpe, ");
		sql.append("  dbms_lob.substr((case when bpeori.tipoevento is not null then bpeant.xmlregular else bpeori.xmlregular end), 3000, 3001) as xml_bpe_2, ");
		sql.append("  dbms_lob.substr((case when bpeori.tipoevento is not null then bpeant.xmlregular else bpeori.xmlregular end), 3000, 6001) as xml_bpe_3 ");
		sql.append("from boleto bori ");
		sql.append("  inner join marca m on m.marca_id = bori.marca_id and m.activo = 1 ");
		sql.append("  inner join empresa e on e.empresa_id = m.empresa_id ");
		sql.append("  inner join bpe bpe on bpe.boleto_id = bori.boleto_id ");
		sql.append("        and bpe.activo = (case when bori.motivocancelacion_id = 17 and bori.boletooriginal_id is null then 0 else 1 end) ");
		sql.append("  inner join estado est_bpe on bpe.uf = est_bpe.codibge ");
		sql.append("  left join bpe bpeori on bpeori.chbpe = bpe.chbpe_substituicao ");
		sql.append("        and bpeori.activo = (case when bori.motivocancelacion_id = 17 and bori.boletooriginal_id is null then 0 else 1 end) ");
		sql.append("  left join boleto b on b.boleto_id = bpeori.boleto_id ");
		sql.append("  inner join punto_venta ptv on ptv.puntoventa_id = b.puntoventa_id ");
		sql.append("  inner join parada ori on (b.origen_id = ori.parada_id ) ");
		sql.append("  inner join parada des on (b.destino_id = des.parada_id ) ");
		sql.append("  inner join ciudad co on (co.ciudad_id = ori.ciudad_id ) ");
		sql.append("  inner join ciudad cd on (cd.ciudad_id = des.ciudad_id ) ");
		sql.append("  inner join estado est on est.estado_id = co.estado_id ");
		sql.append("  left join alias_servico s on s.origen_id = b.origen_id ");
		sql.append("                 		  and s.destino_id = b.destino_id and (s.corrida_id = b.corrida_id or s.corrida_id is null) ");
		sql.append("                 		  and s.ruta_id = b.ruta_id ");
		sql.append("  left join parada pos on pos.parada_id = s.aliasorigen_id ");
		sql.append("  left join ciudad cos on cos.ciudad_id = pos.ciudad_id ");
		sql.append("  left join estado eos on eos.estado_id = cos.estado_id ");
		sql.append("  left join parada pds on pds.parada_id = s.aliasdestino_id ");
		sql.append("  left join ciudad cds on cds.ciudad_id = pds.ciudad_id ");
		sql.append("  left join estado eds on eds.estado_id = cds.estado_id ");
		sql.append("  join inscricao_estadual ie on e.empresa_id = ie.empresa_id ");
		sql.append("               			   and ie.estado_id = coalesce(eos.estado_id, est.estado_id) and ie.activo = 1 ");
		sql.append("  join empresa_imposto ei on ei.empresa_id = e.empresa_id ");
		sql.append("               			   and ei.estado_id = coalesce(eos.estado_id, est.estado_id) and ei.activo = 1 ");
		sql.append("  left join aidf aidf on aidf.aidf_id = b.aidf_id and b.tipoventa_id = 3 ");
		sql.append("  left join estado esaidf on esaidf.estado_id = aidf.estado_id ");
		sql.append("  left join boleto bant on bant.boleto_id = (case when bpeori.tipoevento is not null then coalesce(b.boletoanterior_id, b.boletooriginal_id) else null end) ");
		sql.append("  left join bpe bpeant on bpeant.boleto_id = bant.boleto_id ");
		sql.append("  left join punto_venta ptvo on ptvo.puntoventa_id = coalesce(bant.puntoventa_id, bori.puntoventa_id,b.ptovtaventa_id) ");
		sql.append("where ( (bpe.codstat in ('-1','100','101','102','135','150') and bpe.chbpe_substituicao is not null) ");
		sql.append("    or (bpe.codstat in ('101','135') and to_char(b.feccreacion, 'mm/yyyy') < to_char(bori.feccreacion, 'mm/yyyy')) ) ");
		sql.append("    and (bpe.codstat in ('-1','100','101','102','135','150') and bpe.tipoevento <> '110115' or bpe.tipoevento is null) ");
		sql.append("    and (bpeori.codstat in ('-1','100','101','102','135','150') and bpeori.tipoevento <> '110115' or bpeori.tipoevento is null) ");
		sql.append("    and bori.feccreacion >= :DATE_INICIO  ");
		sql.append("    and bori.feccreacion <= :DATE_FIM ");
		sql.append("    and est_bpe.cveestado in ( ").append(ufs).append(" ) ");
		sql.append("    and e.empresa_id = :EMPRESA_ID   ");
		sql.append(" ");
		sql.append("  union all ");
		sql.append("   ");
		sql.append("select ");
		sql.append("  b.boleto_id as cajaId, ");
		sql.append("  'DEV' as tipoReceita, ");
		sql.append("  b.numoperacion as numoperacion, ");
		sql.append("  trunc(bori.feccreacion) as fechorVenta, ");
		sql.append("  est_bpe.estado_id as estadoId, ");
		sql.append("  ei.icms as icmsInterestadual, ");
		sql.append("  ei.icmsim as icmsIntermunicipal, ");
		sql.append("  est_bpe.cveestado as estadoOrigem, ");
		sql.append("  eds.cveestado as estadoDestino, ");
		sql.append("  co.codibge as municipioOrigem, ");
		sql.append("  case when (est_bpe.cveestado = eds.cveestado)  then 0 else 1 end as isInterEstadual, ");
		sql.append("  0 as isenta, ");
		sql.append("  ei.porcredbaseicms as redBaseCalcIcms, ");
		sql.append("  ei.porcredmunicipal as porcRedMunicipal, ");
		sql.append("  ei.porcredestadual as porcRedEstadual, ");
		sql.append("  ei.indtarifamunicipal as indtarifamunicipal, ");
		sql.append("  ei.indseguromunicipal as indseguromunicipal, ");
		sql.append("  ei.indtxembarquemunicipal as indtxembarquemunicipal, ");
		sql.append("  ei.indpedagiomunicipal as indpedagiomunicipal, ");
		sql.append("  ei.indtarifaestadual as indtarifaestadual, ");
		sql.append("  ei.indseguroestadual as indseguroestadual, ");
		sql.append("  ei.indtxembarqueestadual as indtxembarqueestadual, ");
		sql.append("  ei.indpedagioestdual as indpedagioestdual, ");
		sql.append("  ei.tributacaoImportacao as tributacaoImportacao, ");
		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("  to_char(trunc(bori.feccreacion), 'yyyymmdd') as datamov, ");
		sql.append("  dbms_lob.substr((case when bpeori.tipoevento is not null then bpeant.xmlregular else bpeori.xmlregular end), 3000) as xml_bpe, ");
		sql.append("  dbms_lob.substr((case when bpeori.tipoevento is not null then bpeant.xmlregular else bpeori.xmlregular end), 3000, 3001) as xml_bpe_2, ");
		sql.append("  dbms_lob.substr((case when bpeori.tipoevento is not null then bpeant.xmlregular else bpeori.xmlregular end), 3000, 6001) as xml_bpe_3 ");
		sql.append("from boleto bori ");
		sql.append("  inner join marca m on m.marca_id = bori.marca_id and m.activo = 1 ");
		sql.append("  inner join empresa e on e.empresa_id = m.empresa_id ");
		sql.append("  inner join bpe bpe on bpe.boleto_id = bori.boleto_id ");
		sql.append("        and bpe.activo = (case when bori.motivocancelacion_id = 17 and bori.boletooriginal_id is null then 0 else 1 end) ");
		sql.append("  inner join estado est_bpe on bpe.uf = est_bpe.codibge ");
		sql.append("  left join boleto b on b.boleto_id = (case when bori.motivocancelacion_id = 99 then  bori.boletoanterior_id else bori.boletooriginal_id end) ");
		sql.append("  left join bpe bpeori on b.boleto_id = bpeori.boleto_id ");
		sql.append("        and bpeori.activo = (case when bori.motivocancelacion_id = 17 and bori.boletooriginal_id is null then 0 else 1 end) ");
		sql.append("  inner join punto_venta ptv on ptv.puntoventa_id = bori.puntoventa_id ");
		sql.append("  inner join parada ori on (b.origen_id = ori.parada_id ) ");
		sql.append("  inner join parada des on (b.destino_id = des.parada_id ) ");
		sql.append("  inner join ciudad co on (co.ciudad_id = ori.ciudad_id ) ");
		sql.append("  inner join ciudad cd on (cd.ciudad_id = des.ciudad_id ) ");
		sql.append("  inner join estado est on est.estado_id = co.estado_id ");
		sql.append("left join alias_servico s on s.origen_id = b.origen_id ");
		sql.append("                 		  and s.destino_id = b.destino_id and (s.corrida_id = b.corrida_id or s.corrida_id is null) ");
		sql.append("                 		  and s.ruta_id = b.ruta_id and s.activo = 1 ");
		sql.append("left join parada pos on pos.parada_id = s.aliasorigen_id ");
		sql.append("left join ciudad cos on cos.ciudad_id = pos.ciudad_id ");
		sql.append("left join estado eos on eos.estado_id = cos.estado_id ");
		sql.append("left join parada pds on pds.parada_id = s.aliasdestino_id ");
		sql.append("left join ciudad cds on cds.ciudad_id = pds.ciudad_id ");
		sql.append("left join estado eds on eds.estado_id = cds.estado_id ");
		sql.append("join inscricao_estadual ie on e.empresa_id = ie.empresa_id ");
		sql.append("               			   and ie.estado_id = coalesce(eos.estado_id, est.estado_id) and ie.activo = 1 ");
		sql.append("join empresa_imposto ei on ei.empresa_id = e.empresa_id ");
		sql.append("               			   and ei.estado_id = coalesce(eos.estado_id, est.estado_id) and ei.activo = 1 ");
		sql.append("left join aidf aidf on aidf.aidf_id = b.aidf_id and b.tipoventa_id = 3 ");
		sql.append("left join estado esaidf on esaidf.estado_id = aidf.estado_id ");
		sql.append("left join boleto bant on bant.boleto_id = (case when bpeori.tipoevento is not null then coalesce(b.boletoanterior_id, b.boletooriginal_id) else null end) ");
		sql.append("left join bpe bpeant on bpeant.boleto_id = bant.boleto_id ");
		sql.append("        and bpeant.activo = (case when bori.motivocancelacion_id = 17 and bori.boletooriginal_id is null then 0 else 1 end) ");
		sql.append("left join punto_venta ptvo on ptvo.puntoventa_id = coalesce(bant.puntoventa_id, bori.puntoventa_id,b.ptovtaventa_id) ");
		sql.append("where ");
		sql.append("    (bpe.codstat in ('101','135') and to_char(b.feccreacion, 'mm/yyyy') < to_char(bori.feccreacion, 'mm/yyyy')) ");
		sql.append("    and (bpe.codstat in ('-1','100','101','102','135','150') and bpe.tipoevento <> '110115' or bpe.tipoevento is null) ");
		sql.append("    and (bpeori.codstat in ('-1','100','101','102','135','150') and bpeori.tipoevento <> '110115' or bpeori.tipoevento is null) ");
		sql.append("    and bori.feccreacion >= :DATE_INICIO  ");
		sql.append("    and bori.feccreacion <= :DATE_FIM ");
		sql.append("    and est_bpe.cveestado in ( ").append(ufs).append(" ) ");
		sql.append("    and e.empresa_id = :EMPRESA_ID   ");

		sql.append("order by estadoId, isInterEstadual ");

		return sql.toString();
	}

	@Override
	public List<BPeVO> buscarBPeRejeitadosContingencia(Integer empresaId, String numBpe, String chbpe, Date dtVendaInicio, Date dtVendaFim, List<Integer> estados, List<String> codigosRejeicoes) {
		StringBuilder sQuery = new StringBuilder();
		sQuery.append("select bpe.bpe_id bpeId, bpe.codstat, bpe.chbpe, b.num_bpe numBpe, b.numserie_bpe numserieBpe, e.cveestado uf, bpe.motivo, ")
			  .append("bpe.errocontingencia, b.fechorventa, em.nombempresa ")
			  .append("from bpe bpe ")
			  .append("join boleto b on b.boleto_id = bpe.boleto_id ")
			  .append("join marca m on m.marca_id = b.marca_id ")
			  .append("left join estado e on e.codibge = bpe.uf ")
			  .append("join empresa em on em.empresa_id = m.empresa_id ")
			  .append("where bpe.activo = 1 ")
			  .append("and b.activo = 1 ")
			  .append("and bpe.codstat in ('-10','-20') ");
		
		if(empresaId != null) {
			sQuery.append("and m.empresa_id = :empresaId ");
		}
		if(StringUtils.isNotBlank(numBpe)) {
			sQuery.append("and b.num_bpe = :numBpe ");
		}
		if(StringUtils.isNotBlank(chbpe)) {
			sQuery.append("and bpe.chbpe = :chbpe ");
		}
		if(dtVendaInicio != null && dtVendaFim != null) {
			sQuery.append("and b.fechorventa between to_date(:dtVendaInicio,'dd/mm/yyyy hh24:mi') and to_date(:dtVendaFim,'dd/mm/yyyy hh24:mi') ");
		}
		if(estados != null && !estados.isEmpty()) {
			sQuery.append("and e.estado_id in (:estados) ");
		}
		if(codigosRejeicoes != null && !codigosRejeicoes.isEmpty()) {
			sQuery.append("and substr(bpe.errocontingencia,1,3) in (:codigosRejeicoes) ");
		}
		
		Query qr = getSession().createSQLQuery(sQuery.toString())
							   .addScalar("bpeId", IntegerType.INSTANCE)
							   .addScalar("codstat", StringType.INSTANCE)
							   .addScalar("chbpe", StringType.INSTANCE)
							   .addScalar("numBpe", StringType.INSTANCE)
							   .addScalar("numserieBpe", StringType.INSTANCE)
							   .addScalar("uf", StringType.INSTANCE)
							   .addScalar("motivo", StringType.INSTANCE)
							   .addScalar("errocontingencia", StringType.INSTANCE)
							   .addScalar("fechorventa", TimestampType.INSTANCE)
							   .addScalar("nombempresa", StringType.INSTANCE)
							   .setResultTransformer(new AliasToBeanResultTransformer(BPeVO.class));
		if(empresaId != null) {
			qr.setParameter("empresaId", empresaId);
		}
		if(StringUtils.isNotBlank(numBpe)) {
			qr.setParameter("numBpe", numBpe);
		}
		if(StringUtils.isNotBlank(chbpe)) {
			qr.setParameter("chbpe", chbpe);
		}
		if(dtVendaInicio != null && dtVendaFim != null) {
			qr.setParameter("dtVendaInicio", DateUtil.getStringDate(DateUtil.inicioFecha(dtVendaInicio), "dd/MM/yyyy HH:mm"));
			qr.setParameter("dtVendaFim", DateUtil.getStringDate(DateUtil.fimFecha(dtVendaFim), "dd/MM/yyyy HH:mm"));
		}
		if(estados != null && !estados.isEmpty()) {
			qr.setParameterList("estados", estados);
		}
		if(codigosRejeicoes != null && !codigosRejeicoes.isEmpty()) {
			qr.setParameterList("codigosRejeicoes", codigosRejeicoes);
		}
		
		return qr.list();
	}

	@Override
	public void definirBPeRejeitadoSefazReenvio(Integer bpeId, String codstat) throws BusinessException {
		String codstatUpdate = null;
		if("-10".equals(codstat)) {
			codstatUpdate = "-1";
		} else if("-20".equals(codstat)) {
			codstatUpdate = "-2";
		}
		
		if(codstatUpdate == null || bpeId == null) {
			throw new BusinessException("NÃO foi possível atualizar o BPe selecionado");
		}
		
		try {
			Query qr = getSession().createSQLQuery("update bpe set codstat = :codstatUpdate, xmlregular = null, fecmodif = :dataAtual, usuario_id = :usuarioId where bpe_id = :bpeId");
			qr.setParameter("codstatUpdate", codstatUpdate);
			qr.setParameter("bpeId", bpeId);
			qr.setParameter("dataAtual", new Date());
			qr.setParameter("usuarioId", UsuarioLogado.getUsuarioLogado().getUsuarioId());
			qr.executeUpdate();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new BusinessException(e.getMessage(), e);
		}
	}

	@Override
	public List<BPeVO> buscarBPeVendaEEventosAutorizados(Integer empresaId, Date dtVendaInicio, Date dtVendaFim, Integer estadoId) {
		StringBuilder sQuery = new StringBuilder();
		sQuery.append("select bpe.chbpe, bpe.tipoevento, b.num_bpe numBpe, b.numserie_bpe numserieBpe, b.fechorventa,  ")
			  .append("case when bpe.xmlcontingencia is not null and bpe.indcontingencia = 1 then bpe.xmlcontingencia else bpe.xmlregular end xmlEnvio, ")
			  .append("bpe.xmlresposta xmlResposta ")
			  .append("from bpe bpe ")
			  .append("join boleto b on b.boleto_id = bpe.boleto_id ")
			  .append("join marca m on m.marca_id = b.marca_id ")
			  .append("left join estado e on e.codibge = bpe.uf ")
			  .append("where bpe.activo = 1 ")
			  .append("and bpe.tipoamb = :tipoamb ")
			  .append("and bpe.codstat in ('100','101','102','135','150') ");

		if(empresaId != null) {
			sQuery.append("and m.empresa_id = :empresaId ");
		}
		if(dtVendaInicio != null && dtVendaFim != null) {
			sQuery.append("and b.fechorventa between to_date(:dtVendaInicio,'dd/mm/yyyy hh24:mi') and to_date(:dtVendaFim,'dd/mm/yyyy hh24:mi') ");
		}
		if(estadoId != null) {
			sQuery.append("and e.estado_id = :estadoId ");
		}
		
		Query qr = getSession().createSQLQuery(sQuery.toString())
				   			   .addScalar("chbpe", StringType.INSTANCE)
				   			   .addScalar("tipoevento", StringType.INSTANCE)
				   			   .addScalar("chbpe", StringType.INSTANCE)
				   			   .addScalar("numBpe", StringType.INSTANCE)
				   			   .addScalar("numserieBpe", StringType.INSTANCE)
				   			   .addScalar("xmlEnvio", StringType.INSTANCE)
				   			   .addScalar("xmlResposta", StringType.INSTANCE)
				   			   .addScalar("fechorventa", TimestampType.INSTANCE)
				   			   .setResultTransformer(new AliasToBeanResultTransformer(BPeVO.class));
		
		qr.setParameter("tipoamb", getAmbiente());
		if(empresaId != null) {
			qr.setParameter("empresaId", empresaId);
		}
		if(dtVendaInicio != null && dtVendaFim != null) {
			qr.setParameter("dtVendaInicio", DateUtil.getStringDate(DateUtil.inicioFecha(dtVendaInicio), "dd/MM/yyyy HH:mm"));
			qr.setParameter("dtVendaFim", DateUtil.getStringDate(DateUtil.fimFecha(dtVendaFim), "dd/MM/yyyy HH:mm"));
		}
		if(estadoId != null) {
			qr.setParameter("estadoId", estadoId);
		}
		
		return qr.list();
	}
	
	public String getAmbiente() {
		ConstanteService constanteService = (ConstanteService) AppContext.getApplicationContext().getBean("constanteService");
		Constante contante = constanteService.buscarPorNomeConstante("BPE_AMBIENTE");
		String valorConstante = contante == null ? null : contante.getValorconstante();
		if(valorConstante != null) {
			return valorConstante;
		}
		return "1";
	}
	
}