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.ResultSetMetaData;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.jdbc.Work;
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.FiscalDAO;
import com.rjconsultores.ventaboletos.entidad.Aidf;
import com.rjconsultores.ventaboletos.entidad.Constante;
import com.rjconsultores.ventaboletos.entidad.EsquemaCorrida;
import com.rjconsultores.ventaboletos.entidad.Estado;
import com.rjconsultores.ventaboletos.service.ConstanteService;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.utilerias.MoneyHelper;
import com.rjconsultores.ventaboletos.utilerias.StringHelper;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.utilerias.UtiliteriasFiscal;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoBPR;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoBPRBase;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoECF;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoECFBase;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoECFTipoCCF;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoECFTipoCFC;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoECFTipoICF;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoECFTipoPRC;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoRMDTipoBPS;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoRMDTipoDBP;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoRMDTipoPAR;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoRMDTipoRMD;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoRMDTipoSeqBPS;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoRMDTipoSeqDBP;
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.utilerias.impressaormd.vo.DetalhadoRMD;
import com.rjconsultores.ventaboletos.utilerias.impressaormd.vo.ImpressaoRMD;
import com.rjconsultores.ventaboletos.vo.impressaofiscal.ImportacionFiscalReducaoZVO;
import com.rjconsultores.ventaboletos.vo.impressaofiscal.ImportacionFiscalVO;
import com.rjconsultores.ventaboletos.vo.impressaofiscal.ImportacionManualFiscalVO;
import com.rjconsultores.ventaboletos.vo.impressaofiscal.ImportacionNaoFiscalVO;
import com.rjconsultores.ventaboletos.vo.impressaofiscal.ItemFiscalVO;
import com.rjconsultores.ventaboletos.vo.impressaofiscal.SituacaoTributaria;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;
import com.rjconsultores.ventaboletos.web.utilerias.spring.AppContext;

@Repository("fiscalDAO")
public class FiscalHibernateDAO extends HibernateDaoSupport implements FiscalDAO {
	private static final String DATE_FORMAT_FISCAL = "yyyyMMdd";
	private static final String DATE_FORMAT_DMY = "dd/MM/yyyy";

	private static final String CODIGO_INDICADOR_CONTR_PREVIDENCIARIA = "00000060";

	private static final Logger log = LogManager.getLogger(FiscalHibernateDAO.class);

	@Autowired
	private DataSource dataSource;

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

	private boolean isEstadoTodos(Integer estadoId) {
		if (estadoId == -1 || estadoId == null)
			return true;
		else
			return false;
	}

	@Override
	public List<ImportacionManualFiscalVO> buscaDatosFiscaisECFManual(Date inicio, Date fim, Integer empresaId, Integer estadoId, Connection connection, boolean isBoletoHist) throws SQLException {
		PreparedStatement stmt = null;
		ResultSet rset = null;

		StringBuilder sql = new StringBuilder();
		sql.append("select distinct ");
		sql.append(" 	(case when r2.numserie20 is null then '' else r2.numserie20 end) || imp.numserie20 as numImpressora, ");
		sql.append(" 	coalesce(b.numfoliosistema, (case when r4.caja_id is null then '000001' else r4.coo end)) as coo, ");
		sql.append("	to_char(b.feccreacion, 'yyyymmdd') as dataEmissao, ");
		sql.append("	r4.cpfcnpjcliente as cnpjCliente, ");
		sql.append("	b.caja_id as boletoId, ");
		sql.append("	b.empresacorrida_id as empresaId, ");
		sql.append("	b.numseriepreimpresa as serie, ");
		sql.append("    a.subserie as subSerie, ");
		sql.append("    a.docfiscal as aidf, ");
		sql.append("	(case when s.aliasorigen_id is null then eo.estado_id else eos.estado_id end) as estadoIdOrigen, ");
		sql.append("	(case when s.aliasorigen_id is null then co.codibge else cos.codibge end) as origenId, ");
		sql.append("	(case when s.aliasorigen_id is null then co.codibge else cos.codibge end) as origenUf, ");
		sql.append("	(case when s.aliasdestino_id is null then ed.estado_id else eds.estado_id end) as estadoIdDestino, ");
		sql.append("	(case when s.aliasdestino_id is null then cd.codibge else cds.codibge end) as destinoId, ");
		sql.append("	(case when s.aliasdestino_id is null then cd.codibge else cds.codibge end) as destinoUf, ");
		sql.append("	imp.numcnpj as cnpjImpressora, ");
		sql.append("	imp.numserie as numpdv, ");
		sql.append("	r5.totparcial as repTributado, ");
		sql.append("	r5.imptotalliquido as valorItem, ");
		sql.append("	r5.tipopassagem as tipoPassagem, ");
		sql.append("	r5.numitem as numItem, ");
		sql.append("	r5.codproduto as codProduto, ");
		sql.append("	imp.modelo as modeloImpressora, ");
		sql.append("	b.usuario_id as numCaixa, ");
		sql.append("	b.preciopagado as importetarifa, ");
		sql.append("	cs.descclase AS claseServicio, ");
		sql.append("	translate(imp.numcnpj, ' / - . ', ' ') as cnpjEcf, ");
		sql.append("    coalesce(ei.icms, eos.icms) as icms, ");
		sql.append("    ei.porctributo as porctributo, ");
		sql.append("	case when b.indstatusboleto = 'V' or b.motivocancelacion_id is null THEN 'N' ELSE 'C' END status, ");
		sql.append("	r4.indcancelamento AS indcancelamento, ");
		sql.append("	b.preciopagado as valorTotal, ");
		sql.append("    case b.importetaxaembarque when 0 then null else b.importetaxaembarque end as importetaxaembarque, ");
		sql.append("    case b.importepedagio when 0 then null else b.importepedagio end as importepedagio, ");
		sql.append("    case b.importeoutros when 0 then null else b.importeoutros end as importeoutros, ");
		sql.append("    case b.importeseguro when 0 then null else b.importeseguro end as importeseguro ");

		if (isBoletoHist)
			sql.append("from caja_hist b ");
		else
			sql.append("from caja b ");

		sql.append("  left join fiscal_r4 r4 on r4.caja_id = b.caja_id ");
		sql.append("  left join fiscal_r5 r5 on r4.numserie20 = r5.numserie20 and r4.coo = r5.coo and r4.datamov = r5.datamov and r4.contador = r5.contador ");
		sql.append("  left join fiscal_impressora imp on imp.numserie = b.serieimpfiscal ");
		sql.append("  left join fiscal_r2 r2 on r2.numserie20 = imp.numserie20 and r2.datamov = to_char(b.feccreacion, 'YYYYMMDD') ");
		sql.append("  left join clase_servicio cs on cs.claseservicio_id = b.claseservicio_id ");
		sql.append("  join marca m on b.marca_id = m.marca_id ");
		sql.append("  join empresa e on e.empresa_id = m.empresa_id ");
		sql.append("  left join aidf a on a.aidf_id = b.aidf_id ");
		sql.append("  join punto_venta pv on pv.puntoventa_id = b.puntoventa_id ");
		sql.append("  join ciudad ce on ce.ciudad_id = e.ciudad_id ");
		sql.append("  join estado ee on ee.estado_id = ce.estado_id ");
		sql.append("  join parada po on po.parada_id = b.origen_id ");
		sql.append("  join ciudad co on co.ciudad_id = po.ciudad_id ");
		sql.append("  join estado eo on eo.estado_id = co.estado_id ");
		sql.append("  join parada pd on pd.parada_id = b.destino_id ");
		sql.append("  join ciudad cd on cd.ciudad_id = pd.ciudad_id ");
		sql.append("  join estado ed on ed.estado_id = cd.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("  left join estado ae on ae.estado_id = a.estado_id ");
		sql.append("  left join inscricao_estadual ie on e.empresa_id = ie.empresa_id ");
		sql.append("                 and ie.estado_id = (case when s.aliasorigen_id is null then eo.estado_id else eos.estado_id end) and ie.activo = 1 ");
		sql.append("  left join ciudad cie on cie.ciudad_id = ie.ciudad_id ");
		sql.append("  left join estado eie on eie.estado_id = cie.estado_id ");
		sql.append("  left join empresa_imposto ei on ei.empresa_id = b.empresacorrida_id ");
		sql.append("                 and ei.estado_id = (case when s.aliasorigen_id is null then eo.estado_id else eos.estado_id end) and ei.activo = 1 ");
		sql.append("where ((b.tipoventa_id = 3 and b.indstatusboleto in ('V', 'C') and b.indreimpresion = 0) ");
		sql.append("        or (b.tipoventa_id in (12,18) and b.indstatusboleto = 'E' and b.numfoliosistema = b.numfoliopreimpreso)) ");
		sql.append("   and (b.motivocancelacion_id is null or b.motivocancelacion_id <> 35)  ");
		sql.append("   and b.feccreacion >= to_date(:DATE_INICIO,'DD/MM/YYYY HH24:MI:SS') and b.feccreacion <= to_date(:DATE_FIM,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append("   and b.empresacorrida_id = ? ");
		sql.append(isEstadoTodos(estadoId) ? "" : " and (case when s.aliasorigen_id is null then eo.estado_id else eos.estado_id end)  = ? ");
		sql.append("ORDER  BY dataEmissao, coo, modeloImpressora ");

		List<ImportacionManualFiscalVO> listManuais = new ArrayList<ImportacionManualFiscalVO>();

		stmt = connection.prepareStatement(sql.toString());
		stmt.setFetchSize(100);
		stmt.setString(1, DateUtil.getStringDate(inicio, DATE_FORMAT_DMY) + " 00:00:00");
		stmt.setString(2, DateUtil.getStringDate(fim, DATE_FORMAT_DMY) + " 23:59:59");
		stmt.setInt(3, empresaId);

		if (!isEstadoTodos(estadoId))
			stmt.setInt(4, estadoId);

		rset = stmt.executeQuery();
		while (rset.next()) {

			ImportacionManualFiscalVO item = new ImportacionManualFiscalVO();

			item.setNumImpressora(rset.getString("numImpressora"));
			item.setCoo(rset.getString("coo"));
			item.setBoletoId(rset.getLong("boletoId"));
			item.setEmpresaId(rset.getInt("empresaId"));
			item.setDataEmissao(rset.getString("dataEmissao"));
			item.setValorTotal(rset.getBigDecimal("valorTotal"));
			item.setNumItem(rset.getString("numItem"));
			item.setCodProduto(rset.getString("codProduto"));
			item.setNumpdv(rset.getString("numpdv"));
			item.setRepTributado(rset.getString("repTributado"));
			item.setTipoPassagem(rset.getString("tipoPassagem"));
			item.setValorItem(rset.getBigDecimal("valorItem"));
			item.setOrigenId(rset.getInt("origenId"));

			Integer origenIbge = rset.getInt("origenUf");
			item.setOrigenUf(origenIbge == null ? null : origenIbge.toString());

			item.setDestinoId(rset.getInt("destinoId"));

			Integer destinoIbge = rset.getInt("destinoUf");
			item.setDestinoUf(destinoIbge == null ? null : destinoIbge.toString());

			item.setModeloImpressora(rset.getString("modeloImpressora"));
			item.setNumCaixa(rset.getString("numCaixa"));
			item.setStatus(rset.getString("status"));
			item.setSerie(rset.getString("serie"));
			item.setIcms(rset.getBigDecimal("icms"));
			item.setPorctributo(rset.getBigDecimal("porctributo"));
			item.setEstadoIdOrigen(rset.getInt("estadoIdOrigen"));
			item.setEstadoIdDestino(rset.getInt("estadoIdDestino"));
			item.setImportetaxaembarque(rset.getBigDecimal("importetaxaembarque"));
			item.setImportepedagio(rset.getBigDecimal("importepedagio"));
			item.setImporteoutros(rset.getBigDecimal("importeoutros"));
			item.setImporteseguro(rset.getBigDecimal("importeseguro"));
			item.setSubSerie(rset.getString("subSerie"));
			item.setAidf(rset.getString("aidf"));
			item.setClaseServicio(rset.getString("claseServicio"));

			listManuais.add(item);
		}

		return listManuais;

	}

	private String sqlFiscaisReducaoZPendencia(boolean isEstadoTodos) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT r2.datamov              AS datamov, ");
		sql.append("       r2.numreducoes          AS numreducoes, ");
		sql.append("       r2.crz                  AS crz, ");
		sql.append("       r2.numserie20           AS numserie20, ");
		sql.append("       r2.coo                  AS coo, ");
		sql.append("       r2.cro                  AS cro, ");
		sql.append("       r2.cooinicial           AS cooinicial, ");
		sql.append("       r2.coofinal             AS coofinal, ");
		sql.append("       r2.vendabrutadiaria     AS vendabrutadiaria, ");
		sql.append("       r2.datareducao          AS datareducao, ");
		sql.append("       r2.horareducao          AS horareducao, ");
		sql.append("       r3.totparcial           AS aliquota, ");
		sql.append("       r3.valoracumulado       AS imposto, ");
		sql.append("       ifi.numserie            AS numpdv, ");
		sql.append("       TRANSLATE(t2.cnpj, ' / - . ', ' ') AS cnpj,");
		sql.append("       r2.totgeral             AS gtFinal, ");
		sql.append("       anterior.totgeral       AS gtInicial, ");
		sql.append("       CASE WHEN r3.totparcial = 'Can-T' THEN 'CANCELADO' ");
		sql.append("           WHEN r3.totparcial = 'DT' THEN 'DESCONTO' ELSE '' END AS status ");
		sql.append("FROM   fiscal_r2 r2 ");
		sql.append("       inner join fiscal_impressora ifi ");
		sql.append("              ON ifi.numserie20 = r2.numserie20 ");
		sql.append("       inner join fiscal_r3 r3 ");
		sql.append("               ON r3.crz = r2.crz ");
		sql.append("                  AND r2.numserie20 = r3.numserie20 ");
		sql.append("                  AND r3.datamov = r2.datamov ");
		sql.append("                  AND r3.fiscalimpressora_id = ifi.fiscalimpressora_id ");
		sql.append("       inner join fiscal_t2 t2 ");
		sql.append("              ON ifi.fiscalimpressora_id = t2.fiscalimpressora_id ");
		sql.append("       inner join empresa e ON ( t2.cnpj = e.cnpjnumero  ) or ");
		sql.append("             ( t2.cnpj in  ");
		sql.append("              (select TRANSLATE(cnpj, ' / - . ', ' ') from inscricao_estadual where empresa_id = ? and activo = 1 )) ");
		sql.append("       inner join inscricao_estadual ie ON e.empresa_id = ie.empresa_id, ");
		sql.append("       (SELECT numserie20, crz, totgeral ");
		sql.append("        FROM   fiscal_r2) anterior ");
		sql.append("WHERE  r2.datamov BETWEEN ? AND ? ");
		sql.append("       AND r2.activo = 1 ");
		sql.append("       AND e.empresa_id = ? ");
		sql.append(isEstadoTodos ? "" : " AND ie.estado_id = ? ");
		sql.append("       AND r3.totparcial IN (");
		sql.append("'" + SituacaoTributaria.CANCELADO.getValue() + "'").append(", ");
		sql.append("'" + SituacaoTributaria.DESCONTO.getValue() + "'").append(")");
		sql.append("       AND anterior.numserie20 = r2.numserie20 ");
		sql.append("       AND anterior.crz = r2.crz - 1 ");
		sql.append("       AND (SELECT MAX(fiscalr4_id) FROM fiscal_r4 r4 WHERE r4.numserie20 = r2.numserie20 ");
		sql.append("                      AND r4.datamov = r2.datamov) IS NOT NULL ");
		sql.append("GROUP  BY r2.datamov, ");
		sql.append("          r2.numreducoes, ");
		sql.append("          r2.crz, ");
		sql.append("          r2.numserie20, ");
		sql.append("          r2.coo, ");
		sql.append("          r2.cro, ");
		sql.append("          r2.cooinicial, ");
		sql.append("          r2.coofinal, ");
		sql.append("          r2.vendabrutadiaria, ");
		sql.append("          r2.datareducao, ");
		sql.append("          r2.horareducao, ");
		sql.append("          r3.totparcial, ");
		sql.append("          r3.valoracumulado, ");
		sql.append("          ifi.numserie, ");
		sql.append("          t2.cnpj, ");
		sql.append("          r2.totgeral, ");
		sql.append("          anterior.totgeral ");
		sql.append("ORDER  BY r2.datamov, ");
		sql.append("          numserie20, ");
		sql.append("          crz, ");
		sql.append("          r2.numreducoes, ");
		sql.append("          r3.totparcial desc ");
		return sql.toString();
	}

	private String sqlFiscaisReducaoZPendenciaInconcistencias(boolean isEstadoTodos) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT r2.datamov              AS datamov, ");
		sql.append("       r2.numreducoes          AS numreducoes, ");
		sql.append("       r2.crz                  AS crz, ");
		sql.append("       r2.numserie20           AS numserie20, ");
		sql.append("       r2.coo                  AS coo, ");
		sql.append("       r2.cro                  AS cro, ");
		sql.append("       r2.cooinicial           AS cooinicial, ");
		sql.append("       r2.coofinal             AS coofinal, ");
		sql.append("       r2.vendabrutadiaria     AS vendabrutadiaria, ");
		sql.append("       r2.datareducao          AS datareducao, ");
		sql.append("       r2.horareducao          AS horareducao, ");
		sql.append("       r3.totparcial           AS aliquota, ");
		sql.append("       r3.valoracumulado       AS imposto, ");
		sql.append("       ifi.numserie            AS numpdv, ");
		sql.append("       t2.cnpj                 AS cnpj,");
		sql.append("       r2.totgeral             AS gtFinal, ");
		sql.append("       anterior.totgeral       AS gtInicial, ");
		sql.append("       'INCONSISTENTE' AS status ");
		sql.append("FROM   fiscal_r2 r2 ");
		sql.append("       inner join fiscal_impressora ifi ");
		sql.append("              ON ifi.numserie20 = r2.numserie20 ");
		sql.append("       inner join fiscal_r3 r3 ");
		sql.append("               ON r3.crz = r2.crz ");
		sql.append("                  AND r2.numserie20 = r3.numserie20 ");
		sql.append("                  AND r3.datamov = r2.datamov ");
		sql.append("                  AND r3.fiscalimpressora_id = ifi.fiscalimpressora_id ");
		sql.append("       inner join fiscal_t2 t2 ");
		sql.append("              ON ifi.fiscalimpressora_id = t2.fiscalimpressora_id ");
		sql.append("       inner join empresa e ON ( t2.cnpj = e.cnpjnumero ) or ");
		sql.append("             ( t2.cnpj in  ");
		sql.append("              (select TRANSLATE(cnpj, ' / - . ', ' ') from inscricao_estadual where empresa_id = ? and activo = 1 )) ");
		sql.append("       inner join inscricao_estadual ie ON e.empresa_id = ie.empresa_id, ");
		sql.append("       (SELECT numserie20, crz, totgeral ");
		sql.append("        FROM   fiscal_r2) anterior ");
		sql.append("WHERE  r2.datamov BETWEEN ? AND ? ");
		sql.append("       AND r2.activo = 1 ");
		sql.append("       AND e.empresa_id = ? ");
		sql.append(isEstadoTodos ? "" : " AND ie.estado_id = ? ");
		sql.append("       AND r3.totparcial  not in (");
		sql.append("'" + SituacaoTributaria.NAO_FISCAL.getValue() + "'").append(")");
		sql.append("       AND anterior.numserie20 = r2.numserie20 ");
		sql.append("       AND anterior.crz = r2.crz - 1 ");
		sql.append("       AND (SELECT MAX(fiscalr4_id) FROM fiscal_r4 r4 WHERE r4.numserie20 = r2.numserie20 ");
		sql.append("                      AND r4.datamov = r2.datamov) IS NULL ");
		sql.append("GROUP  BY r2.datamov, ");
		sql.append("          r2.numreducoes, ");
		sql.append("          r2.crz, ");
		sql.append("          r2.numserie20, ");
		sql.append("          r2.coo, ");
		sql.append("          r2.cro, ");
		sql.append("          r2.cooinicial, ");
		sql.append("          r2.coofinal, ");
		sql.append("          r2.vendabrutadiaria, ");
		sql.append("          r2.datareducao, ");
		sql.append("          r2.horareducao, ");
		sql.append("          r3.totparcial, ");
		sql.append("          r3.valoracumulado, ");
		sql.append("          ifi.numserie, ");
		sql.append("          t2.cnpj, ");
		sql.append("          r2.totgeral, ");
		sql.append("          anterior.totgeral ");
		sql.append("ORDER  BY r2.datamov, ");
		sql.append("          numserie20, ");
		sql.append("          crz, ");
		sql.append("          r2.numreducoes, ");
		sql.append("          r3.totparcial desc ");
		return sql.toString();
	}

	private String sqlFiscaisReducaoZ(boolean isEstadoTodos) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT r2.datamov              AS datamov, ");
		sql.append("       r2.numreducoes          AS numreducoes, ");
		sql.append("       r2.crz                  AS crz, ");
		sql.append("       r2.numserie20           AS numserie20, ");
		sql.append("       r2.coo                  AS coo, ");
		sql.append("       r2.cro                  AS cro, ");
		sql.append("       r2.cooinicial           AS cooinicial, ");
		sql.append("       r2.coofinal             AS coofinal, ");
		sql.append("       r2.vendabrutadiaria     AS vendabrutadiaria, ");
		sql.append("       r2.datareducao          AS datareducao, ");
		sql.append("       r2.horareducao          AS horareducao, ");
		sql.append("       r3.totparcial           AS aliquota, ");
		sql.append("       r3.valoracumulado       AS imposto, ");
		sql.append("       ifi.numserie            AS numpdv, ");
		sql.append("       t2.cnpj                 AS cnpj,");
		sql.append("       r2.totgeral             AS gtFinal, ");
		sql.append("       anterior.totgeral       AS gtInicial, ");
		sql.append("       'NORMAL' AS status ");
		sql.append("FROM   fiscal_r2 r2 ");
		sql.append("       inner join fiscal_impressora ifi ");
		sql.append("              ON ifi.numserie20 = r2.numserie20 ");
		sql.append("       inner join fiscal_r3 r3 ");
		sql.append("               ON r3.crz = r2.crz ");
		sql.append("                  AND r2.numserie20 = r3.numserie20 ");
		sql.append("                  AND r3.datamov = r2.datamov ");
		sql.append("                  AND r3.fiscalimpressora_id = ifi.fiscalimpressora_id ");
		sql.append("       inner join fiscal_t2 t2 ");
		sql.append("              ON ifi.fiscalimpressora_id = t2.fiscalimpressora_id ");
		sql.append("       inner join empresa e ON ( t2.cnpj  = e.cnpjnumero ) or ");
		sql.append("             (t2.cnpj in  ");
		sql.append("              (select TRANSLATE(cnpj, ' / - . ', ' ') from inscricao_estadual where empresa_id = ? and activo = 1 )) ");
		sql.append("       inner join inscricao_estadual ie ON e.empresa_id = ie.empresa_id, ");
		sql.append("       (SELECT numserie20, datamov, crz, totgeral ");
		sql.append("        FROM   fiscal_r2) anterior ");
		sql.append("WHERE  r2.datamov BETWEEN ? AND ? ");
		sql.append("       AND r2.activo = 1 ");
		sql.append("       AND e.empresa_id = ? ");
		sql.append(isEstadoTodos ? "" : " AND ie.estado_id = ? ");
		sql.append("       AND r3.totparcial  not in (");
		sql.append("'" + SituacaoTributaria.NAO_FISCAL.getValue() + "'").append(")");
		sql.append("       AND anterior.numserie20 = r2.numserie20 ");
		sql.append("       AND anterior.datamov = r2.datamov - 1 ");
		sql.append("       AND to_number(anterior.crz) = to_number(r2.crz) - 1 ");
		sql.append("       AND r2.vendabrutadiaria > 0 ");
		sql.append("GROUP  BY r2.datamov, ");
		sql.append("          r2.numreducoes, ");
		sql.append("          r2.crz, ");
		sql.append("          r2.numserie20, ");
		sql.append("          r2.coo, ");
		sql.append("          r2.cro, ");
		sql.append("          r2.cooinicial, ");
		sql.append("          r2.coofinal, ");
		sql.append("          r2.vendabrutadiaria, ");
		sql.append("          r2.datareducao, ");
		sql.append("          r2.horareducao, ");
		sql.append("          r3.totparcial, ");
		sql.append("          r3.valoracumulado, ");
		sql.append("          ifi.numserie, ");
		sql.append("          t2.cnpj, ");
		sql.append("          r2.totgeral, ");
		sql.append("          anterior.totgeral ");
		sql.append("ORDER  BY r2.datamov, ");
		sql.append("          numserie20, ");
		sql.append("          crz, ");
		sql.append("          r2.numreducoes, ");
		// TODO: No ambiente de produção a ordenação so vem correta quando declarado para vir como desc
		// contrario aos outros servidores que deve ser asc
		sql.append("          r3.totparcial desc ");
		return sql.toString();
	}

	@Override
	public List<ImportacionFiscalReducaoZVO> buscaDatosFiscaisReducaoZ(Date inicio, Date fim, Integer empresaId, Integer estadoId, boolean isPendencias, Connection connection) throws SQLException {
		if (isPendencias) {
			List<ImportacionFiscalReducaoZVO> list = new ArrayList<ImportacionFiscalReducaoZVO>();
			list.addAll(montarItensReducaoZ(inicio, fim, empresaId, estadoId, sqlFiscaisReducaoZPendencia(isEstadoTodos(estadoId)), connection));
			list.addAll(montarItensReducaoZ(inicio, fim, empresaId, estadoId, sqlFiscaisReducaoZPendenciaInconcistencias(isEstadoTodos(estadoId)), connection));
			return list;

		} else {
			return montarItensReducaoZ(inicio, fim, empresaId, estadoId, sqlFiscaisReducaoZ(isEstadoTodos(estadoId)), connection);
		}
	}

	private List<ImportacionFiscalReducaoZVO> montarItensReducaoZ(Date inicio, Date fim, Integer empresaId, Integer estadoId, String sql, Connection connection) throws SQLException {

		List<ImportacionFiscalReducaoZVO> listRedZ = new ArrayList<ImportacionFiscalReducaoZVO>();
		PreparedStatement stmt = connection.prepareStatement(sql);
		stmt.setFetchSize(100);
		stmt.setInt(1, empresaId);
		stmt.setString(2, DateUtil.getStringDate(inicio, DATE_FORMAT_FISCAL));
		stmt.setString(3, DateUtil.getStringDate(fim, DATE_FORMAT_FISCAL));
		stmt.setInt(4, empresaId);

		if (!isEstadoTodos(estadoId))
			stmt.setInt(5, estadoId);

		ResultSet rset = stmt.executeQuery();
		while (rset.next()) {

			ImportacionFiscalReducaoZVO item = new ImportacionFiscalReducaoZVO();
			item.setDatamov(rset.getString("datamov"));
			item.setNumreducoes(rset.getString("numreducoes"));
			item.setCrz(rset.getString("crz"));
			item.setNumserie20(rset.getString("numserie20"));
			item.setCoo(rset.getString("coo"));
			item.setCro(rset.getString("cro"));
			item.setCooinicial(rset.getString("cooinicial"));
			item.setCoofinal(rset.getString("coofinal"));
			item.setVendabrutadiaria(rset.getBigDecimal("vendabrutadiaria"));
			item.setDatareducao(rset.getString("datareducao"));
			item.setHorareducao(rset.getString("horareducao"));
			item.setAliquota(rset.getString("aliquota"));
			item.setImposto(rset.getBigDecimal("imposto"));
			item.setNumpdv(rset.getString("numpdv"));
			item.setCnpj(rset.getString("cnpj"));
			item.setGtFinal(rset.getBigDecimal("gtFinal"));
			item.setGtInicial(rset.getBigDecimal("gtInicial"));
			item.setStatus(rset.getString("status"));
			listRedZ.add(item);
		}

		return listRedZ;
	}

	private String sqlFiscaisECFCancelados(boolean isEstadoTodos, boolean isBoletoHist) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT DISTINCT r4.numserie20 as numImpressora, ");
		sql.append("		   r4.coo as coo, ");
		sql.append("	       r4.imptotalliquido as valorTotal, ");
		sql.append("	       r4.datamov as dataEmissao, ");
		sql.append("	       r4.cpfcnpjcliente as cnpjCliente, ");
		sql.append("	       r4.boleto_id as boletoId, ");
		sql.append("	       me.empresa_id as empresaId, ");
		sql.append("	       co.codibge as origenId, ");
		sql.append("           eo.codibge as origenUf, ");
		sql.append("           cd.codibge as destinoId, ");
		sql.append("           ed.codibge as destinoUf, ");
		sql.append("	       fi.numcnpj as cnpjImpressora, ");
		sql.append("           fi.numserie as numpdv, ");
		sql.append("	       r5.totparcial as repTributado, ");
		sql.append("	       r5.imptotalliquido as valorItem, ");
		sql.append("	       r5.tipopassagem as tipoPassagem, ");
		sql.append("	       r5.numitem as numItem, ");
		sql.append("           r5.codproduto as codProduto, ");
		sql.append("	       fi.modelo as modeloImpressora, ");
		sql.append("           r4.usuario_id as numCaixa, ");
		sql.append("           cajb.preciopagado as importetarifa, ");
		sql.append("	       cajb.importetaxaembarque as importetaxaembarque, ");
		sql.append("	       cajb.importepedagio as importepedagio, ");
		sql.append("	       cajb.importeseguro as importeseguro, ");
		sql.append("           'C' as status, ");
		sql.append("           cajb.motivocancelacion_id as motivocancelacion, ");
		sql.append("           ee.impingreso as valorMulta, ");
		sql.append("	       cs.descclase as claseServicio, ");
		sql.append("           translate(fi.numcnpj, ' / - . ', ' ') as cnpjEcf ");

		sql.append(" FROM ");
		if (isBoletoHist)
			sql.append(" caja_hist caj ");
		else
			sql.append(" caja caj ");

		sql.append(" INNER JOIN ");
		if (isBoletoHist)
			sql.append(" caja_hist cajb ");
		else
			sql.append(" caja cajb ");

		sql.append("		   on (((cajb.feccorrida = caj.feccorrida) or (cajb.feccorrida is null and caj.feccorrida is null)) ");
		sql.append("                 and ((cajb.numasiento = caj.numasiento) or (cajb.numasiento is null and caj.numasiento is null)) ");
		sql.append("                 and cajb.numfoliosistema = caj.numfoliosistema and cajb.origen_id = caj.origen_id and cajb.destino_id=caj.destino_id ");
		sql.append("                 and ((cajb.tipoventa_id not in (5,12,18,81,41,49) ");
		sql.append("                 and (cajb.indstatusboleto = 'V' or (cajb.indstatusboleto = 'T' and cajb.indreimpresion=0) )) ");
		sql.append("                 or (cajb.tipoventa_id in (5,12,18,81,41,49) and cajb.indstatusboleto = 'E')) ) ");
		sql.append("           INNER JOIN fiscal_r4 r4 on r4.caja_id =  cajb.caja_id ");
		sql.append("	       LEFT JOIN fiscal_r5 r5 ON r4.numserie20 = r5.numserie20 and r4.coo = r5.coo ");
		sql.append("                 and r4.datamov = r5.datamov and r4.contador = r5.contador ");
		sql.append("           INNER JOIN fiscal_impressora fi ON fi.numserie20 = r4.numserie20 ");
		sql.append("           INNER JOIN marca me ON me.marca_id = cajb.marca_id ");
		sql.append("	       INNER JOIN clase_servicio cs ON cs.claseservicio_id = cajb.claseservicio_id ");
		sql.append("	       LEFT JOIN evento_extra ee on ee.boleto_id = r4.boleto_id and ee.tipoeventoextra_id in (42) ");
		sql.append("           LEFT JOIN alias_servico ase ON ase.origen_id = cajb.origen_id ");
		sql.append("                 and ase.destino_id = caj.destino_id and ase.ruta_id = cajb.ruta_id and ase.activo = 1 and ase.corrida_id is null ");
		sql.append("           INNER JOIN parada o ON coalesce(ase.aliasorigen_id, cajb.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, cajb.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(" WHERE caj.feccreacion >= to_date(:DATE_INICIO,'DD/MM/YYYY HH24:MI:SS') and caj.feccreacion <= to_date(:DATE_FIM,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append("           and me.empresa_id = :EMPRESA_ID ");
		sql.append(isEstadoTodos ? "" : " AND eo.estado_id = :ESTADO_ID ");
		sql.append("           and caj.motivocancelacion_id IN (31,32,10,37,99,36) ");
		sql.append("           and caj.indcancelacion = 1 ");
		sql.append("           and caj.indstatusboleto = 'C' ");
		sql.append("           and r4.indcancelamento = 'N' ");
		sql.append("           and caj.num_bpe is null ");
		sql.append("		ORDER BY r4.datamov, ");
		sql.append("		   r4.numserie20, ");
		sql.append("		   r4.coo, ");
		sql.append("		   r5.numitem ");
		return sql.toString();
	}

	private String sqlFiscaisECF(boolean isEstadoTodos, boolean isBoletoHist) {

		StringBuilder sql = new StringBuilder();
		sql.append("select distinct ");
		sql.append(" 	(case when r2.numserie20 is null then 'X' else '' end) || imp.numserie20 as numImpressora, ");
		sql.append(" 	(case when r4.caja_id is null then '000001' else r4.coo end) as coo, ");
		sql.append("	r4.imptotalliquido as valorTotal, ");
		sql.append("	to_char(c.feccreacion, 'yyyymmdd') as dataEmissao, ");
		sql.append("	r4.cpfcnpjcliente as cnpjCliente, ");
		sql.append("	c.caja_id as boletoId, ");
		sql.append("	(case when s.aliasorigen_id is null then co.codibge else cos.codibge end) as origenId, ");
		sql.append("	(case when s.aliasorigen_id is null then co.codibge else cos.codibge end) as origenUf, ");
		sql.append("	(case when s.aliasdestino_id is null then cd.codibge else cds.codibge end) as destinoId, ");
		sql.append("	(case when s.aliasdestino_id is null then cd.codibge else cds.codibge end) as destinoUf, ");
		sql.append("	imp.numcnpj as cnpjImpressora, ");
		sql.append("	imp.numserie as numpdv, ");
		sql.append("	r5.totparcial as repTributado, ");
		sql.append("	r5.imptotalliquido as valorItem, ");
		sql.append("	r5.tipopassagem as tipoPassagem, ");
		sql.append("	r5.numitem as numItem, ");
		sql.append("	r5.codproduto as codProduto, ");
		sql.append("	imp.modelo as modeloImpressora, ");
		sql.append("	c.usuario_id as numCaixa, ");
		sql.append("	c.preciopagado as importetarifa, ");
		sql.append("	c.importetaxaembarque as importetaxaembarque, ");
		sql.append("	c.importepedagio as importepedagio, ");
		sql.append("	c.importeseguro as importeseguro, ");
		sql.append("	cs.descclase AS claseServicio, ");
		sql.append("	translate(imp.numcnpj, ' / - . ', ' ') as cnpjEcf, ");
		sql.append("	(case when s.aliasorigen_id is null then ei.icms else eis.icms end) as impostoEstado, ");
		sql.append("	'N' as status, ");
		sql.append("	r4.indcancelamento AS indcancelamento ");

		if (isBoletoHist)
			sql.append(" from caja_hist c ");
		else
			sql.append(" from caja c ");

		sql.append(" join ruta r on r.ruta_id = c.ruta_id ");
		sql.append(" join parada po on po.parada_id = c.origen_id ");
		sql.append(" join ciudad co on co.ciudad_id = po.ciudad_id ");
		sql.append(" join estado eo on eo.estado_id = co.estado_id ");
		sql.append(" join parada pd on pd.parada_id = c.destino_id ");
		sql.append(" join ciudad cd on cd.ciudad_id = pd.ciudad_id ");
		sql.append(" join estado ed on ed.estado_id = cd.estado_id ");
		sql.append(" join empresa_imposto ei on ei.empresa_id = c.empresacorrida_id and ei.estado_id = eo.estado_id ");
		sql.append(" join fiscal_impressora imp on imp.numserie = c.serieimpfiscal ");
		sql.append(" left join clase_servicio cs on cs.claseservicio_id = c.claseservicio_id ");
		sql.append(" left join estado e on e.estado_id = imp.estadolocal_id ");
		sql.append(" left join alias_servico s on s.origen_id = c.origen_id and s.destino_id = c.destino_id and (s.corrida_id = c.corrida_id or s.corrida_id is null) and s.ruta_id = c.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(" left join empresa_imposto eis on eis.empresa_id = c.empresacorrida_id and eis.estado_id = eos.estado_id ");
		sql.append(" left join fiscal_r4 r4 on r4.caja_id = c.caja_id ");
		sql.append(" left join fiscal_r5 r5 on r4.numserie20 = r5.numserie20 and r4.coo = r5.coo and r4.datamov = r5.datamov and r4.contador = r5.contador ");
		sql.append(" left join fiscal_r2 r2 on r2.numserie20 = imp.numserie20 and r2.datamov = to_char(c.feccreacion, 'YYYYMMDD') ");
		sql.append(" where c.activo = 1 and po.activo = 1 and co.activo = 1 and eo.activo = 1 and ei.activo = 1 ");
		sql.append(" and coalesce(case when s.aliasorigen_id is null then ei.activo else eis.activo end, 0) = 1 ");
		sql.append(" and c.serieimpfiscal is not null ");
		sql.append(" and c.num_bpe is null ");
		sql.append(" and ((c.indreimpresion = 0 and c.motivocancelacion_id is null 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 ((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)) > 0 ");
		sql.append(" and c.feccreacion >= to_date(:DATE_INICIO,'DD/MM/YYYY HH24:MI:SS') and c.feccreacion <= to_date(:DATE_FIM,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append(" and c.empresacorrida_id = :EMPRESA_ID ");
		sql.append(isEstadoTodos ? "" : " and ((case when s.aliasorigen_id is null then eo.estado_id else eos.estado_id end) = :ESTADO_ID )");
		sql.append("order by dataEmissao, numImpressora, coo, numItem");
		return sql.toString();
	}

	private String sqlFiscaisECFPendenciasDesconto(boolean isEstadoTodos) {

		StringBuilder sql = new StringBuilder();
		sql.append("	SELECT r4.numserie20 as numImpressora, ");
		sql.append("		   r4.coo as coo, ");
		sql.append("           r4.imptotalliquido as valorTotal, ");
		sql.append("           r4.datamov as dataEmissao, ");
		sql.append("		   r4.cpfcnpjcliente as cnpjCliente, ");
		sql.append("		   fi.numcnpj as cnpjImpressora, ");
		sql.append("           fi.numserie as numpdv, ");
		sql.append("		   r5.totparcial as repTributado, ");
		sql.append("		   r5.imptotalliquido as valorItem, ");
		sql.append("		   r5.tipopassagem as tipoPassagem, ");
		sql.append("		   r5.numitem as numItem, ");
		sql.append("		   r5.codproduto as codProduto, ");
		sql.append("		   fi.modelo as modeloImpressora, ");
		sql.append("		   r4.usuario_id as numCaixa, ");
		sql.append("           r5.impdesconto as desconto, ");
		sql.append("		   'DESCONTO' as status");
		sql.append("	FROM   fiscal_r4 r4 ");
		sql.append("	       INNER JOIN boleto b ON b.boleto_id = r4.boleto_id ");
		sql.append("           INNER JOIN marca m ON m.marca_id = b.marca_id ");
		sql.append("           LEFT JOIN alias_servico ase ON ase.origen_id = b.origen_id ");
		sql.append("                 and ase.destino_id = b.destino_id and ase.ruta_id = b.ruta_id and ase.activo = 1 and ase.corrida_id is null ");
		sql.append("           INNER JOIN parada o ON coalesce(ase.aliasorigen_id, b.origen_id) = o.parada_id ");
		sql.append("           INNER JOIN ciudad co ON o.ciudad_id = co.ciudad_id ");

		sql.append("		   INNER JOIN fiscal_r5 r5 ON r4.numserie20 = r5.numserie20 AND r4.coo = r5.coo ");
		sql.append("                               AND r4.datamov = r5.datamov AND  r4.contador = r5.contador ");
		sql.append("		   LEFT JOIN fiscal_impressora fi ON fi.numserie20 = r4.numserie20 AND fi.fiscalimpressora_id = r5.fiscalimpressora_id ");
		sql.append("   WHERE  r4.datamov BETWEEN :STR_INICIO AND :STR_FIM ");
		sql.append("           AND m.empresa_id = :EMPRESA_ID ");
		sql.append(isEstadoTodos ? "" : " AND co.estado_id = :ESTADO_ID ");
		sql.append(" 	       AND r5.impdesconto <> 0 ");
		sql.append("	GROUP  BY r4.numserie20, r4.coo, r4.datamov, r4.cpfcnpjcliente, ");
		sql.append("       	   r4.imptotalliquido, fi.numcnpj, fi.numserie, r5.impdesconto, ");
		sql.append("		   r5.totparcial, r5.imptotalliquido, r5.tipopassagem, ");
		sql.append("		   r5.numitem, r5.codproduto, fi.modelo, r4.usuario_id ");
		sql.append("	ORDER BY r4.datamov, r4.numserie20, r4.coo, r5.numitem ");
		return sql.toString();
	}

	private String sqlFiscaisECFPendenciasCancelado(boolean isEstadoTodos) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT  r4.numserie20 as numImpressora, ");
		sql.append("	    r4.coo as coo, ");
		sql.append("        r4.imptotalliquido as valorTotal, ");
		sql.append("        r4.datamov as dataEmissao, ");
		sql.append("	    r4.cpfcnpjcliente as cnpjCliente, ");
		sql.append("	    b.boleto_id as boletoId, ");
		sql.append("	    m.empresa_id as empresaId, ");
		sql.append("	    fi.numcnpj as cnpjImpressora, ");
		sql.append("        fi.numserie as numpdv, ");
		sql.append("	    r5.totparcial as repTributado, ");
		sql.append("	    r5.imptotalliquido as valorItem, ");
		sql.append("	    r5.tipopassagem as tipoPassagem, ");
		sql.append("	    r5.numitem as numItem, ");
		sql.append("	    r5.codproduto as codProduto, ");
		sql.append("	    fi.modelo as modeloImpressora, ");
		sql.append("		r4.usuario_id as numCaixa, ");
		sql.append("		b.preciopagado as importetarifa, ");
		sql.append("		b.importetaxaembarque as importetaxaembarque, ");
		sql.append("		b.importepedagio as importepedagio, ");
		sql.append("		b.importeseguro as importeseguro, ");
		sql.append("        translate(fi.numcnpj, ' / - . ', ' ') as cnpjEcf, ");
		sql.append("        r4.indcancelamento, ");
		sql.append("        'CANCELADO' as status ");
		sql.append("FROM    fiscal_r4 r4 ");
		sql.append("        INNER JOIN fiscal_r5 r5 ON r4.numserie20 = r5.numserie20 AND r4.coo = r5.coo ");
		sql.append("                               AND r4.datamov = r5.datamov AND  r4.contador = r5.contador ");
		sql.append("        INNER JOIN fiscal_impressora fi ON fi.numserie20 = r4.numserie20 AND fi.fiscalimpressora_id = r5.fiscalimpressora_id ");
		sql.append("        INNER JOIN boleto b ON b.boleto_id = r4.boleto_id ");
		sql.append("        INNER JOIN marca m ON m.marca_id = b.marca_id ");
		sql.append("        LEFT JOIN alias_servico ase ON ase.origen_id = b.origen_id ");
		sql.append("                 and ase.destino_id = b.destino_id and ase.ruta_id = b.ruta_id and ase.activo = 1 and ase.corrida_id is null ");
		sql.append("        INNER JOIN parada o ON coalesce(ase.aliasorigen_id, b.origen_id) = o.parada_id ");
		sql.append("        INNER JOIN ciudad co ON o.ciudad_id = co.ciudad_id ");
		sql.append("WHERE  r4.datamov BETWEEN :STR_INICIO AND :STR_FIM ");
		sql.append("        AND m.empresa_id = :EMPRESA_ID ");
		sql.append(isEstadoTodos ? "" : " AND co.estado_id = :ESTADO_ID ");
		sql.append("        AND r4.indcancelamento = 'S' ");
		sql.append("        AND (SELECT r3.numserie20 FROM fiscal_r3 r3 where r3.numserie20 = r4.numserie20");
		sql.append("                   AND r3.datamov = r4.datamov AND r3.totparcial IN ('Can-T')) IS NOT NULL ");
		sql.append("GROUP BY  r4.numserie20, r4.coo, r4.datamov, ");
		sql.append("	      r4.cpfcnpjcliente, r4.imptotalliquido, ");
		sql.append("	      b.boleto_id, m.empresa_id, fi.numcnpj, ");
		sql.append("	      fi.numserie, r5.impdesconto, r5.totparcial, ");
		sql.append("	      r5.imptotalliquido, r5.tipopassagem, r5.numitem, ");
		sql.append("	      r5.codproduto, fi.modelo, r4.usuario_id, ");
		sql.append("	      b.preciopagado, b.importetaxaembarque, b.importepedagio, ");
		sql.append("	      b.importeseguro, fi.numcnpj, r4.indcancelamento, r4.indcancelamento ");
		sql.append("ORDER BY r4.datamov, r4.numserie20, r4.coo, r5.numitem ");
		return sql.toString();
	}

	private String sqlFiscaisECFPendenciasGratuidade(boolean isEstadoTodos) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT  r4.numserie20 as numImpressora, ");
		sql.append("	    r4.coo as coo, ");
		sql.append("        r4.imptotalliquido as valorTotal, ");
		sql.append("        r4.datamov as dataEmissao, ");
		sql.append("	    r4.cpfcnpjcliente as cnpjCliente, ");
		sql.append("	    b.boleto_id as boletoId, ");
		sql.append("	    m.empresa_id as empresaId, ");
		sql.append("	    fi.numcnpj as cnpjImpressora, ");
		sql.append("        fi.numserie as numpdv, ");
		sql.append("	    r5.totparcial as repTributado, ");
		sql.append("	    r5.imptotalliquido as valorItem, ");
		sql.append("	    r5.tipopassagem as tipoPassagem, ");
		sql.append("	    r5.numitem as numItem, ");
		sql.append("	    r5.codproduto as codProduto, ");
		sql.append("	    fi.modelo as modeloImpressora, ");
		sql.append("		r4.usuario_id as numCaixa, ");
		sql.append("		b.preciopagado as importetarifa, ");
		sql.append("		b.importetaxaembarque as importetaxaembarque, ");
		sql.append("		b.importepedagio as importepedagio, ");
		sql.append("		b.importeseguro as importeseguro, ");
		sql.append("        translate(fi.numcnpj, ' / - . ', ' ') as cnpjEcf, ");
		sql.append("        r4.indcancelamento, ");
		sql.append("        'GRATUIDADE' as status ");
		sql.append("FROM    fiscal_r4 r4 ");
		sql.append("        INNER JOIN fiscal_r5 r5 ON r4.numserie20 = r5.numserie20 AND r4.coo = r5.coo ");
		sql.append("                               AND r4.datamov = r5.datamov AND  r4.contador = r5.contador ");
		sql.append("        INNER JOIN fiscal_impressora fi ON fi.numserie20 = r4.numserie20 AND fi.fiscalimpressora_id = r5.fiscalimpressora_id ");
		sql.append("        INNER JOIN boleto b ON b.boleto_id = r4.boleto_id ");
		sql.append("        INNER JOIN marca m ON m.marca_id = b.marca_id ");
		sql.append("        LEFT JOIN alias_servico ase ON ase.origen_id = b.origen_id ");
		sql.append("                 and ase.destino_id = b.destino_id and ase.ruta_id = b.ruta_id and ase.activo = 1 and ase.corrida_id is null ");
		sql.append("        INNER JOIN parada o ON coalesce(ase.aliasorigen_id, b.origen_id) = o.parada_id ");
		sql.append("        INNER JOIN ciudad co ON o.ciudad_id = co.ciudad_id ");
		sql.append("WHERE   r4.datamov BETWEEN :STR_INICIO AND :STR_FIM ");
		sql.append("        AND m.empresa_id = :EMPRESA_ID ");
		sql.append(isEstadoTodos ? "" : " AND co.estado_id = :ESTADO_ID ");
		sql.append("        AND r5.imptotalliquido = 1 ");
		sql.append("        AND b.preciopagado = 0 ");
		sql.append("GROUP BY  r4.numserie20, r4.coo, r4.datamov, ");
		sql.append("	      r4.cpfcnpjcliente, r4.imptotalliquido, ");
		sql.append("	      b.boleto_id, m.empresa_id, fi.numcnpj, ");
		sql.append("	      fi.numserie, r5.impdesconto, r5.totparcial, ");
		sql.append("	      r5.imptotalliquido, r5.tipopassagem, r5.numitem, ");
		sql.append("	      r5.codproduto, fi.modelo, r4.usuario_id, ");
		sql.append("	      b.preciopagado, b.importetaxaembarque, b.importepedagio, ");
		sql.append("	      b.importeseguro, fi.numcnpj, r4.indcancelamento, r4.indcancelamento ");
		sql.append("ORDER BY r4.datamov, r4.numserie20, r4.coo, r5.numitem ");
		return sql.toString();
	}

	private String sqlFiscaisECFPendenciasInconsistente(boolean isEstadoTodos) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT  r4.numserie20 as numImpressora, ");
		sql.append("	    r4.coo as coo, ");
		sql.append("        r4.imptotalliquido as valorTotal, ");
		sql.append("        r4.datamov as dataEmissao, ");
		sql.append("	    r4.cpfcnpjcliente as cnpjCliente, ");
		sql.append("	    b.boleto_id as boletoId, ");
		sql.append("	    m.empresa_id as empresaId, ");
		sql.append("	    fi.numcnpj as cnpjImpressora, ");
		sql.append("        fi.numserie as numpdv, ");
		sql.append("	    r5.totparcial as repTributado, ");
		sql.append("	    r5.imptotalliquido as valorItem, ");
		sql.append("	    r5.tipopassagem as tipoPassagem, ");
		sql.append("	    r5.numitem as numItem, ");
		sql.append("	    r5.codproduto as codProduto, ");
		sql.append("	    fi.modelo as modeloImpressora, ");
		sql.append("		r4.usuario_id as numCaixa, ");
		sql.append("		b.preciopagado as importetarifa, ");
		sql.append("		b.importetaxaembarque as importetaxaembarque, ");
		sql.append("		b.importepedagio as importepedagio, ");
		sql.append("		b.importeseguro as importeseguro, ");
		sql.append("        translate(fi.numcnpj, ' / - . ', ' ') as cnpjEcf, ");
		sql.append("        r4.indcancelamento, ");
		sql.append("        'INCONSISTENTE' as status ");
		sql.append("FROM    fiscal_r4 r4 ");
		sql.append("        LEFT JOIN fiscal_r5 r5 ON r4.numserie20 = r5.numserie20 AND r4.coo = r5.coo ");
		sql.append("                               AND r4.datamov = r5.datamov AND  r4.contador = r5.contador ");
		sql.append("        LEFT JOIN fiscal_impressora fi ON fi.numserie20 = r4.numserie20 AND fi.fiscalimpressora_id = r5.fiscalimpressora_id ");
		sql.append("        INNER JOIN boleto b ON b.boleto_id = r4.boleto_id ");
		sql.append("        INNER JOIN marca m ON m.marca_id = b.marca_id ");
		sql.append("        LEFT JOIN alias_servico ase ON ase.origen_id = b.origen_id ");
		sql.append("                 and ase.destino_id = b.destino_id and ase.ruta_id = b.ruta_id and ase.activo = 1 and ase.corrida_id is null ");
		sql.append("        INNER JOIN parada o ON coalesce(ase.aliasorigen_id, b.origen_id) = o.parada_id ");
		sql.append("        INNER JOIN ciudad co ON o.ciudad_id = co.ciudad_id ");
		sql.append("WHERE  r4.datamov BETWEEN :STR_INICIO AND :STR_FIM ");
		sql.append("        AND m.empresa_id = :EMPRESA_ID ");
		sql.append(isEstadoTodos ? "" : " AND co.estado_id = :ESTADO_ID ");
		sql.append("        AND r4.indcancelamento = 'S' ");
		sql.append("        AND (SELECT MAX(r3.numserie20) FROM fiscal_r3 r3 where r3.numserie20 = r4.numserie20");
		sql.append("                   AND r3.datamov = r4.datamov AND r3.totparcial IN ('Can-T', 'DT')) IS NULL ");
		sql.append("GROUP BY  r4.numserie20, r4.coo, r4.datamov, ");
		sql.append("	      r4.cpfcnpjcliente, r4.imptotalliquido, ");
		sql.append("	      b.boleto_id, m.empresa_id, fi.numcnpj, ");
		sql.append("	      fi.numserie, r5.impdesconto, r5.totparcial, ");
		sql.append("	      r5.imptotalliquido, r5.tipopassagem, r5.numitem, ");
		sql.append("	      r5.codproduto, fi.modelo, r4.usuario_id, ");
		sql.append("	      b.preciopagado, b.importetaxaembarque, b.importepedagio, ");
		sql.append("	      b.importeseguro, fi.numcnpj, r4.indcancelamento, r4.indcancelamento ");
		sql.append("ORDER BY r4.datamov, r4.numserie20, r4.coo, r5.numitem ");
		return sql.toString();
	}

	@Override
	public List<ImportacionFiscalVO> buscaDatosFiscaisECF(Date inicio, Date fim, Integer empresaId, Integer estadoId, boolean isNormal, boolean isCancelados, boolean isPendencias, Connection connection, boolean isBoletoHist) throws SQLException {

		if (isNormal) {
			return montarItensECF(inicio, fim, empresaId, estadoId, connection, sqlFiscaisECF(isEstadoTodos(estadoId), isBoletoHist), true);

		} else if (isCancelados) {
			return montarItensECF(inicio, fim, empresaId, estadoId, connection, sqlFiscaisECFCancelados(isEstadoTodos(estadoId), isBoletoHist), true);

		} else if (isPendencias) {

			List<ImportacionFiscalVO> list = new ArrayList<ImportacionFiscalVO>();
			list.addAll(montarItensECF(inicio, fim, empresaId, estadoId, connection, sqlFiscaisECFPendenciasCancelado(isEstadoTodos(estadoId)), false));
			list.addAll(montarItensECF(inicio, fim, empresaId, estadoId, connection, sqlFiscaisECFPendenciasDesconto(isEstadoTodos(estadoId)), false));
			list.addAll(montarItensECF(inicio, fim, empresaId, estadoId, connection, sqlFiscaisECFPendenciasInconsistente(isEstadoTodos(estadoId)), false));
			list.addAll(montarItensECF(inicio, fim, empresaId, estadoId, connection, sqlFiscaisECFPendenciasGratuidade(isEstadoTodos(estadoId)), false));
			return list;

		}
		return null;
	}

	private List<ImportacionFiscalVO> montarItensECF(Date inicio, Date fim, Integer empresaId, Integer estadoId, Connection connection, String sql, boolean isDate) throws SQLException {

		boolean isEstadoTodos = isEstadoTodos(estadoId);

		NamedParameterStatement stmt = new NamedParameterStatement(connection, sql);
		stmt.getStatement().setFetchSize(100);

		stmt.setInt("EMPRESA_ID", empresaId);
		if (isDate) {
			stmt.setString("DATE_INICIO", DateUtil.getStringDate(inicio, DATE_FORMAT_DMY) + " 00:00:00");
			stmt.setString("DATE_FIM", DateUtil.getStringDate(fim, DATE_FORMAT_DMY) + " 23:59:59");
		} else {
			stmt.setString("STR_INICIO", DateUtil.getStringDate(inicio, DATE_FORMAT_FISCAL));
			stmt.setString("STR_FIM", DateUtil.getStringDate(fim, DATE_FORMAT_FISCAL));
		}

		if (!isEstadoTodos) {
			stmt.setInt("ESTADO_ID", estadoId);
		}

		List<ImportacionFiscalVO> list = new ArrayList<ImportacionFiscalVO>();
		ImportacionFiscalVO fiscal = null;
		String codProduto = null;

		List<String> columns = new ArrayList<String>();
		ResultSetMetaData rsMetaData = stmt.getStatement().getMetaData();
		for (int i = 1; i <= rsMetaData.getColumnCount(); i++) {
			columns.add(rsMetaData.getColumnName(i).toLowerCase());
		}

		ResultSet rset = stmt.executeQuery();
		while (rset.next()) {

			ItemFiscalVO item = new ItemFiscalVO();
			item.setNumImpressora(columns.contains("numimpressora") ? rset.getString("numImpressora") : null);
			item.setCoo(columns.contains("coo") ? rset.getString("coo") : null);
			item.setBoletoId(columns.contains("boletoid") ? rset.getLong("boletoId") : null);
			item.setEmpresaId(columns.contains("empresaid") ? rset.getInt("empresaId") : null);
			item.setDataEmissao(columns.contains("dataemissao") ? rset.getString("dataEmissao") : null);
			item.setCnpjCliente(columns.contains("cnpjcliente") ? rset.getString("cnpjCliente") : null);
			item.setCnpjImpressora(columns.contains("cnpjimpressora") ? rset.getString("cnpjImpressora") : null);
			item.setOrigenId(columns.contains("origenid") ? rset.getInt("origenId") : null);

			Integer origenIbge = (columns.contains("origenuf") ? rset.getInt("origenUf") : null);
			item.setOrigenUf(origenIbge == null ? null : origenIbge.toString());

			item.setDestinoId(columns.contains("destinoid") ? rset.getInt("destinoId") : null);

			Integer destinoIbge = (columns.contains("destinouf") ? rset.getInt("destinoUf") : null);
			item.setDestinoUf(destinoIbge == null ? null : destinoIbge.toString());

			item.setNumpdv(columns.contains("numpdv") ? rset.getString("numpdv") : null);
			item.setNumItem(columns.contains("numitem") ? rset.getString("numItem") : null);
			item.setCodProduto(columns.contains("codproduto") ? rset.getString("codProduto") : null);
			item.setRepTributado(columns.contains("reptributado") ? rset.getString("repTributado") : null);
			item.setTipoPassagem(columns.contains("tipopassagem") ? rset.getString("tipoPassagem") : null);
			item.setModeloImpressora(columns.contains("modeloimpressora") ? rset.getString("modeloImpressora") : null);
			item.setNumCaixa(columns.contains("numcaixa") ? rset.getString("numCaixa") : null);
			item.setStatus(columns.contains("status") ? rset.getString("status") : null);
			item.setClaseServicio(columns.contains("claseservicio") ? rset.getString("claseServicio") : null);
			item.setMotivocancelacion(columns.contains("motivocancelacion") ? rset.getInt("motivocancelacion") : null);
			item.setValorMulta(columns.contains("valormulta") ? rset.getBigDecimal("valorMulta") : null);
			item.setImpostoEstado(columns.contains("impostoestado") ? rset.getBigDecimal("impostoEstado") : null);
			item.setDesconto(columns.contains("desconto") ? rset.getBigDecimal("desconto") : null);
			item.setIndcancelamento(columns.contains("indcancelamento") ? rset.getString("indcancelamento") : null);

			// TODO: Estes atributos foram criados, por motivo de divergencia no valorTotal com o valor unitario na tabela FISCAL_R5
			item.setValorTarifa(columns.contains("importetarifa") ? rset.getBigDecimal("importetarifa") : null);
			item.setValorPedagio(columns.contains("importepedagio") ? rset.getBigDecimal("importepedagio") : null);
			item.setValorEmbarque(columns.contains("importetaxaembarque") ? rset.getBigDecimal("importetaxaembarque") : null);
			item.setValorSeguro(columns.contains("importeseguro") ? rset.getBigDecimal("importeseguro") : null);

			ImportacionFiscalVO novoFiscal = item;

			codProduto = item.getCodProduto();
			if (codProduto != null) {
				codProduto = codProduto.toString().replace("-", "").replace("TA", "").replace("TX", "").replace("PE", "").replace("SE", "");
			} else {
				String boleto = item.getBoletoId().toString();
				codProduto = boleto.substring(boleto.length() - 8) + "F" + boleto.substring(boleto.length() - 2);
			}

			if (fiscal == null) {
				fiscal = item;
			} else if (!novoFiscal.equals(fiscal)) {
				List<ItemFiscalVO> itensFiscais = validaItensFiscais(fiscal, codProduto);
				fiscal.setItensFiscais(itensFiscais);
				list.add(fiscal);
				fiscal = item;
			}

			fiscal.getItensFiscais().add(item);

		}

		if (fiscal != null) {
			List<ItemFiscalVO> itensFiscais = validaItensFiscais(fiscal, codProduto);
			fiscal.setItensFiscais(itensFiscais);
			list.add(fiscal);
		}

		return list;
	}

	private boolean validaValorExiste(BigDecimal valor) {
		if (valor == null) {
			return Boolean.FALSE;
		} else if (valor.equals(BigDecimal.ZERO)) {
			return Boolean.FALSE;
		} else {
			return Boolean.TRUE;
		}
	}

	private List<ItemFiscalVO> validaItensFiscais(ImportacionFiscalVO fiscal, String codProduto) {

		boolean temTarifa = validaValorExiste(fiscal.getValorTarifa());
		boolean temPedagio = validaValorExiste(fiscal.getValorPedagio());
		boolean temEmbarque = validaValorExiste(fiscal.getValorEmbarque());
		boolean temSeguro = validaValorExiste(fiscal.getValorSeguro());

		boolean tarifaCriada = false;
		boolean pedagioCriada = false;
		boolean embarqueCriada = false;
		boolean seguroCriada = false;

		boolean inconsistencia = false;

		List<ItemFiscalVO> itensFiscais = new ArrayList<ItemFiscalVO>();
		for (ItemFiscalVO item : fiscal.getItensFiscais()) {

			String codigoProduto = item.getCodProduto();
			if (codigoProduto != null) {
				if (codigoProduto.indexOf("TA") >= 0)
					tarifaCriada = true;

				if (codigoProduto.indexOf("TX") >= 0)
					embarqueCriada = true;

				if (codigoProduto.indexOf("PE") >= 0)
					pedagioCriada = true;

				if (codigoProduto.indexOf("SE") >= 0)
					seguroCriada = true;
			} else {
				inconsistencia = true;
				break;
			}

			itensFiscais.add(item);
		}

		int numeroItem = 1;
		if (temTarifa && !tarifaCriada) {
			ItemFiscalVO novoTarifa = new ItemFiscalVO(fiscal);
			novoTarifa.setCodProduto(codProduto + "-TA");
			novoTarifa.setTipoPassagem("E");
			novoTarifa.setValorItem(fiscal.getValorTarifa());
			novoTarifa.setRepTributado("N1");
			novoTarifa.setNumItem(StringHelper.preencherZeroEsquerda((numeroItem++) + "", 3));
			novoTarifa.setInconsistencia(inconsistencia);
			itensFiscais.add(novoTarifa);
		}

		if (temEmbarque && !embarqueCriada) {
			ItemFiscalVO novoEmbarque = new ItemFiscalVO(fiscal);
			novoEmbarque.setCodProduto(codProduto + "-TX");
			novoEmbarque.setTipoPassagem("E");
			novoEmbarque.setValorItem(fiscal.getValorEmbarque());
			novoEmbarque.setRepTributado("N1");
			novoEmbarque.setNumItem(StringHelper.preencherZeroEsquerda((numeroItem++) + "", 3));
			novoEmbarque.setInconsistencia(inconsistencia);
			itensFiscais.add(novoEmbarque);
		}

		if (temPedagio && !pedagioCriada) {
			ItemFiscalVO novoPedagio = new ItemFiscalVO(fiscal);
			novoPedagio.setCodProduto(codProduto + "-PE");
			novoPedagio.setTipoPassagem("E");
			novoPedagio.setValorItem(fiscal.getValorPedagio());
			novoPedagio.setRepTributado("N1");
			novoPedagio.setNumItem(StringHelper.preencherZeroEsquerda((numeroItem++) + "", 3));
			novoPedagio.setInconsistencia(inconsistencia);
			itensFiscais.add(novoPedagio);
		}

		if (temSeguro && !seguroCriada) {
			ItemFiscalVO novoSeguro = new ItemFiscalVO(fiscal);
			novoSeguro.setCodProduto(codProduto + "-SE");
			novoSeguro.setTipoPassagem("E");
			novoSeguro.setValorItem(fiscal.getValorSeguro());
			novoSeguro.setRepTributado("N1");
			novoSeguro.setNumItem(StringHelper.preencherZeroEsquerda((numeroItem++) + "", 3));
			novoSeguro.setInconsistencia(inconsistencia);
			itensFiscais.add(novoSeguro);
		}

		return itensFiscais;
	}

	private int gerarRegistroP2(List<EsquemaCorrida> lsEsquemaCorrida, Date dataDe, Date dataAte) throws SQLException {
		Integer[] idsCorrida = getIdsCorrida(lsEsquemaCorrida);

		StringBuilder sb = new StringBuilder("");
		sb.append(" INSERT INTO FISCAL_P2 (CODPRODUTO,descricao,valorunitario_ta,valorunitario_tx,valorunitario_pe,valorunitario_ot,valorunitario_se,empresa_id,estado_origem,estado_aliascorrida,estado_aliasgeral, ncm) ");
		sb.append("                                                                                                                                                                                                                                                          ");
		sb.append(" select DISTINCT                                                                                                                                                                                                                                                ");
		sb.append("   CODPRODUTO(t.origen_id , t.destino_id , rc.ruta_id) AS CODPRODUTO,                                                                                                                                                                                           ");
		sb.append("   concat(concat(concat(concat(concat(po.cveparada, '-'),pd.cveparada),'('),v.nombvia),')') as descricao,                                                                                                                                                                                                                                    ");
		sb.append("   tr.precio as valorunitario_ta,                                                                                                                                                                                                                               ");
		sb.append("   tr.importetaxaembarque as valorunitario_tx,                                                                                                                                                                                                                  ");
		sb.append("   tr.importepedagio as valorunitario_pe,                                                                                                                                                                                                                       ");
		sb.append("   tr.importeoutros as valorunitario_ot,                                                                                                                                                                                                                        ");
		sb.append("   tr.importeseguro as valorunitario_se,                                                                                                                                                                                                                        ");
		sb.append("   c.empresacorrida_id as empresa_id,                                                                                                                                                                                                                           ");
		sb.append("   co.estado_id as estado_origem,                                                                                                                                                                                                                               ");
		sb.append("   cas1.estado_id as estado_aliascorrida,                                                                                                                                                                                                                       ");
		sb.append("   cas2.estado_id as estado_aliasgeral,                                                                                                                                                                                                                         ");
		sb.append("   '1040311' as ncm                                                                                                                                                                                                                         					   ");
		sb.append("                                                                                                                                                                                                                                                                ");
		sb.append(" from                                                                                                                                                                                                                                                           ");
		sb.append("   ruta_combinacion rc                                                                                                                                                                                                                                          ");
		sb.append("   inner join tramo t on t.tramo_id = rc.tramo_id                                                                                                                                                                                                               ");
		sb.append("   inner join via v on v.via_id = t.via_id 																																																					   ");
		sb.append("   inner join parada po on po.parada_id = t.origen_id                                                                                                                                                                                                           ");
		sb.append("   inner join parada pd on pd.parada_id = t.destino_id                                                                                                                                                                                                          ");
		sb.append("   inner join corrida c on c.ruta_id = rc.ruta_id                                                                                                                                                                                                               ");
		sb.append("   inner join corrida_tramo cto on cto.corrida_id = c.corrida_id and cto.feccorrida = c.feccorrida and t.origen_id = cto.origen_id                                                                                                                              ");
		sb.append("   inner join corrida_tramo ctd on ctd.corrida_id = c.corrida_id and ctd.feccorrida = c.feccorrida and t.destino_id = ctd.destino_id                                                                                                                            ");
		sb.append("   inner join tarifa tr on tr.ruta_id = rc.ruta_id and tr.origen_id = t.origen_id and tr.destino_id = t.destino_id                                                                                                                                              ");
		sb.append("   inner join vigencia_tarifa vt on vt.vigenciatarifa_id = tr.vigenciatarifa_id                                                                                                                                                                                 ");
		sb.append("   inner join ciudad co on co.ciudad_id = po.ciudad_id                                                                                                                                                                                                          ");
		sb.append("   left join alias_servico as1 on as1.corrida_id = as1.corrida_id and as1.origen_id = t.origen_id and as1.destino_id = t.destino_id and as1.ruta_id = rc.ruta_id                                                                                                ");
		sb.append("   left join parada pas1 on pas1.parada_id = as1.aliasorigen_id                                                                                                                                                                                                 ");
		sb.append("   left join ciudad cas1 on cas1.ciudad_id = pas1.ciudad_id                                                                                                                                                                                                     ");
		sb.append("   left join alias_servico as2 on as2.corrida_id is null and as2.origen_id = t.origen_id and as2.destino_id = t.destino_id and as2.ruta_id = rc.ruta_id                                                                                                         ");
		sb.append("   left join parada pas2 on pas2.parada_id = as2.aliasorigen_id                                                                                                                                                                                                 ");
		sb.append("   left join ciudad cas2 on cas2.ciudad_id = pas2.ciudad_id                                                                                                                                                                                                     ");
		sb.append(" where                                                                                                                                                                                                                                                          ");
		sb.append("   rc.activo = 1                                                                                                                                                                                                                                                ");
		sb.append("   and cto.activo = 1                                                                                                                                                                                                                                           ");
		sb.append("   and ctd.activo = 1                                                                                                                                                                                                                                           ");
		sb.append("   and tr.activo = 1                                                                                                                                                                                                                                            ");
		sb.append("   and cto.fechorsalida between vt.feciniciovigencia and vt.fecfinvigencia                                                                                                                                                                                      ");
		sb.append("   and c.feccorrida between :datIni and :datFim                                                                                                                                                                   ");
		sb.append("   and c.corrida_id in (:corridaId)                                                                                                                                                                                                                                ");
		sb.append("   and CODPRODUTO(t.origen_id , t.destino_id , rc.ruta_id) not in (select codproduto from fiscal_p2) ");
		// sb.append(" and ROWNUM < 50 ");

		int qtd = 0;

		Connection connection = null;
		try {
			connection = dataSource.getConnection();

			connection.setAutoCommit(false);

			PreparedStatement ps = connection.prepareStatement(sb.toString());

			ps.setDate(1, new java.sql.Date(dataDe.getTime()));
			ps.setDate(2, new java.sql.Date(dataAte.getTime()));
			ps.setString(3, StringUtils.join(idsCorrida, ","));

			qtd = ps.executeUpdate();

			connection.commit();
		} catch (Throwable t) {
			connection.rollback();
		} finally {
			if (connection != null) {
				connection.close();
			}
		}

		return qtd;

	}

	private Integer[] getIdsCorrida(List<EsquemaCorrida> lsEsquemaCorrida) {
		Integer[] idsCorrida = new Integer[lsEsquemaCorrida.size()];
		int i = 0;
		for (EsquemaCorrida ec : lsEsquemaCorrida) {
			idsCorrida[i] = ec.getNumCorrida();
			i++;
		}
		return idsCorrida;
	}

	private int gerarRegistroF2(List<EsquemaCorrida> lsEsquemaCorrida, Date dataDe, Date dataAte) throws SQLException {
		StringBuilder sb = new StringBuilder("");
		sb.append(" INSERT INTO FISCAL_F2 (cnpj, codigo_local_emissao,identificacao_linha, descricao_linha, data_partida, hora_partida, codigo_tipo_viagem) ");
		sb.append(" select distinct oc.cnpj, t.origen_id as codigo_local_emissao, r.prefixo as identificacao_linha, concat(concat(po.cveparada, '-'),pd.cveparada) as descricao, to_char(cto.fechorsalida, 'YYYYMMdd') as data_partida, to_char(cto.fechorsalida, 'hh24miss') as hora_partida, (case nvl(c.tiposervicio_id, 0) when 2 then '01' else '00' end) as codigo_tipo_viagem ");
		sb.append(" from                                                                                                                                                                                                                                                                                                                               ");
		sb.append("   ruta_combinacion rc                                                                                                                                                                                                                                                                                                              ");
		sb.append("   inner join ruta r on r.ruta_id = rc.ruta_id                                                                                                                                                                                                                                                                                      ");
		sb.append("   inner join orgao_concedente oc on oc.orgaoconcedente_id = r.orgaoconcedente_id                                                                                                                                                                                                                                                   ");
		sb.append("   inner join tramo t on t.tramo_id = rc.tramo_id                                                                                                                                                                                                                                                                                   ");
		sb.append("   inner join parada po on po.parada_id = t.origen_id                                                                                                                                                                                                                                                                               ");
		sb.append("   inner join parada pd on pd.parada_id = t.destino_id                                                                                                                                                                                                                                                                              ");
		sb.append("   inner join corrida c on c.ruta_id = rc.ruta_id                                                                                                                                                                                                                                                                                   ");
		sb.append("   inner join corrida_tramo cto on cto.corrida_id = c.corrida_id and cto.feccorrida = c.feccorrida and t.origen_id = cto.origen_id                                                                                                                                                                                                  ");
		sb.append("   inner join corrida_tramo ctd on ctd.corrida_id = c.corrida_id and ctd.feccorrida = c.feccorrida and t.destino_id = ctd.destino_id                                                                                                                                                                                                ");
		sb.append("   inner join tarifa tr on tr.ruta_id = rc.ruta_id and tr.origen_id = t.origen_id and tr.destino_id = t.destino_id                                                                                                                                                                                                                  ");
		sb.append("   inner join vigencia_tarifa vt on vt.vigenciatarifa_id = tr.vigenciatarifa_id                                                                                                                                                                                                                                                     ");
		sb.append("   inner join punto_venta pv on pv.empresa_id = c.empresacorrida_id                                                                                                                                                                                                                                                                 ");
		sb.append(" where                                                                                                                                                                                                                                                                                                                              ");
		sb.append("   rc.activo = 1                                                                                                                                                                                                                                                                                                                    ");
		sb.append("   and cto.activo = 1                                                                                                                                                                                                                                                                                                               ");
		sb.append("   and ctd.activo = 1                                                                                                                                                                                                                                                                                                               ");
		sb.append("   and cto.fechorsalida between vt.feciniciovigencia and vt.fecfinvigencia                                                                                                                                                                                                                                                          ");
		sb.append("   and c.feccorrida between :datIni and :datFim                                                                                                                                                                                                                                       ");
		sb.append("   and c.corrida_id in (:corridaId)                                                                                                                                                                                                                                       ");
		// sb.append(" and ROWNUM < 2 ");

		Integer[] idsCorrida = getIdsCorrida(lsEsquemaCorrida);
		Connection connection = null;

		int qtd = 0;

		try {
			connection = dataSource.getConnection();

			connection.setAutoCommit(false);

			PreparedStatement ps = connection.prepareStatement(sb.toString());

			ps.setDate(1, new java.sql.Date(dataDe.getTime()));
			ps.setDate(2, new java.sql.Date(dataAte.getTime()));
			ps.setString(3, StringUtils.join(idsCorrida, ","));

			qtd = ps.executeUpdate();

			connection.commit();

		} catch (Throwable t) {
			connection.rollback();
		} finally {
			if (connection != null) {
				connection.close();
			}
		}

		return qtd;
	}

	@Override
	public int gerarRegistroP2_F2(List<EsquemaCorrida> lsEsquemaCorrida, Date dataDe, Date dataAte) throws SQLException {
		int gerarRegistroP2 = this.gerarRegistroP2(lsEsquemaCorrida, dataDe, dataAte);
		int gerarRegistroF2 = this.gerarRegistroF2(lsEsquemaCorrida, dataDe, dataAte);
		return gerarRegistroP2 + gerarRegistroF2;
	}

	@Override
	public List<ImportacionNaoFiscalVO> buscaDatosNaoFiscais(Date inicio, Date fim, Integer empresaId, Integer estadoId, Connection connection) throws SQLException {
		PreparedStatement stmt = null;
		ResultSet rset = null;

		StringBuilder sQuery = new StringBuilder();
		sQuery.append("SELECT TEE.TIPOEVENTOEXTRA_ID AS TIPOEVENTOEXTRAID, TEE.DESCTIPOEVENTO AS DESCTIPOEVENTO, ")
				.append("     TRUNC(CD.FECHORVTA) AS FECHORVTA, SUM(CD.PRECIO) AS TOTAL ")
				.append("FROM TIPO_EVENTO_EXTRA TEE ")
				.append("JOIN EVENTO_EXTRA EE ON TEE.TIPOEVENTOEXTRA_ID = EE.TIPOEVENTOEXTRA_ID ")
				.append("JOIN PUNTO_VENTA PV ON PV.PUNTOVENTA_ID = EE.PUNTOVENTA_ID ")
				.append("JOIN PARADA PA ON PA.PARADA_ID = PV.PARADA_ID ")
				.append("JOIN CIUDAD CI ON CI.CIUDAD_ID = PA.CIUDAD_ID ")
				.append("JOIN ESTADO ES ON ES.ESTADO_ID = CI.ESTADO_ID ")
				.append("LEFT JOIN CAJA_DIVERSOS CD ON EE.EVENTOEXTRA_ID = CD.EVENTOEXTRA_ID ")
				.append("WHERE TEE.ACTIVO = 1 ")
				.append("AND EE.EMPRESA_ID = ? ")
				.append("AND TRUNC(CD.FECHORVTA) BETWEEN ? AND ? ")
				.append(isEstadoTodos(estadoId) ? "" : " AND ES.ESTADO_ID = ? ")
				.append("GROUP BY TEE.TIPOEVENTOEXTRA_ID, TEE.DESCTIPOEVENTO, TRUNC(CD.FECHORVTA) ")
				.append("ORDER BY TRUNC(CD.FECHORVTA), TEE.DESCTIPOEVENTO ");

		stmt = connection.prepareStatement(sQuery.toString());
		stmt.setInt(1, empresaId);
		stmt.setDate(2, new java.sql.Date(inicio.getTime()));
		stmt.setDate(3, new java.sql.Date(fim.getTime()));

		if (!isEstadoTodos(estadoId))
			stmt.setInt(4, estadoId);

		rset = stmt.executeQuery();
		List<ImportacionNaoFiscalVO> importacionNaoFiscalVOs = new ArrayList<ImportacionNaoFiscalVO>();
		while (rset.next()) {
			ImportacionNaoFiscalVO importacionNaoFiscal = new ImportacionNaoFiscalVO();
			importacionNaoFiscal.setTipoeventoextraId(rset.getInt("TIPOEVENTOEXTRAID"));
			importacionNaoFiscal.setDesctipoevento(rset.getString("DESCTIPOEVENTO"));
			importacionNaoFiscal.setFechorvta(rset.getDate("FECHORVTA"));
			importacionNaoFiscal.setTotal(rset.getBigDecimal("TOTAL"));

			importacionNaoFiscalVOs.add(importacionNaoFiscal);
		}

		return importacionNaoFiscalVOs;

	}

	@Override
	public ExportacaoECF buscarRegistroECF(Connection connection, Date inicio, Date fim, Integer empresaId, String cveestado) {
		ExportacaoECF exportacaoECF = new ExportacaoECF();

		StringBuilder sb = new StringBuilder();
		sb.append(" select distinct");
		sb.append(" 	(case when r2.numserie20 is null then 'X' else '' end) || imp.numserie20 as ecf,");
		sb.append(" 	(case when r2.numserie20 is null then 'X' else '' end) || imp.numserie as numserie,");
		sb.append(" 	(case when r2.numserie20 is null then '000001' else r2.cooinicial end) as cooinicial,");
		sb.append(" 	(case when r2.numserie20 is null then '000001' else r2.coofinal end) as coofinal,");
		sb.append(" 	(case when r2.numserie20 is null then '000001' else r2.crz end) as crz,");
		sb.append(" 	(case when r2.numserie20 is null then '000001' else r2.cro end) as cro,");
		sb.append("  	(case when r2.numserie20 is null then '000001' else r2.coo end) as r2_coo,");
		sb.append(" 	to_char(c.feccreacion, 'yyyymmdd') as datamov,");
		sb.append(" 	(case when r4.caja_id is null then '000001' else r4.coo end) as r4_coo,");
		sb.append(" 	(case when s.aliasorigen_id is null then ei.codestabelecimento else eis.codestabelecimento end) as codestabelecimento,");
		sb.append(" 	e.codestabelecimento as codestabelecimentoimpressora,");
		sb.append(" 	imp.numeroidentificacao as numeroidentificacao,");
		sb.append(" 	(case when (coalesce(case when s.aliasorigen_id is null then po.regionmetropolitana_id else pos.regionmetropolitana_id end, -1) = coalesce(case when s.aliasorigen_id is null then pd.regionmetropolitana_id else pds.regionmetropolitana_id end, -2)) then 1 else 0 end) as isenta,");
		sb.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,");
		sb.append(" 	(case when s.aliasorigen_id is null then co.codibge else cos.codibge end) as municipio_origem,");
		sb.append(" 	(case when s.aliasorigen_id is null then eo.cveestado else eos.cveestado end) as estado_origem,");
		sb.append(" 	(case when s.aliasdestino_id is null then cd.codibge else cds.codibge end) as municipio_destino,");
		sb.append(" 	(case when s.aliasdestino_id is null then ed.cveestado else eds.cveestado end) as estado_destino,");
		sb.append(" 	(case when s.aliasorigen_id is null then ei.porcredbaseicms else eis.porcredbaseicms end) as red_base_calc_icms,");
		sb.append(" 	(case when s.aliasorigen_id is null then ei.porcredmunicipal else eis.porcredmunicipal end) as porc_red_municipal,");
		sb.append(" 	(case when s.aliasorigen_id is null then ei.porcredestadual else eis.porcredestadual end) as porc_red_estadual,");
		sb.append(" 	(case when s.aliasorigen_id is null then ei.tributacaoimportacao else eis.tributacaoimportacao end) as tributacao_importacao,");
		sb.append(" 	coalesce(c.preciopagado,0) + coalesce(c.importetaxaembarque,0) + coalesce(c.importeseguro,0) + coalesce(c.importepedagio,0) + coalesce(c.importeoutros,0) as valortotal,");
		sb.append(" 	c.numfoliosistema as numfoliosistema,");
		sb.append(" 	c.caja_id");
		sb.append(" from caja c");
		sb.append(" join ruta r on r.ruta_id = c.ruta_id");
		sb.append(" join parada po on po.parada_id = c.origen_id and po.activo = 1 ");
		sb.append(" join ciudad co on co.ciudad_id = po.ciudad_id and co.activo = 1 ");
		sb.append(" join estado eo on eo.estado_id = co.estado_id and eo.activo = 1 ");
		sb.append(" join parada pd on pd.parada_id = c.destino_id");
		sb.append(" join ciudad cd on cd.ciudad_id = pd.ciudad_id");
		sb.append(" join estado ed on ed.estado_id = cd.estado_id");
		sb.append(" join empresa_imposto ei on ei.empresa_id = c.empresacorrida_id and ei.estado_id = eo.estado_id and ei.activo = 1 ");
		sb.append(" join fiscal_impressora imp on imp.numserie = c.serieimpfiscal");
		sb.append(" left join estado e on e.estado_id = imp.estadolocal_id");
		sb.append(" left join alias_servico s on s.origen_id = c.origen_id and s.destino_id = c.destino_id and (s.corrida_id = c.corrida_id or s.corrida_id is null) and s.ruta_id = c.ruta_id and s.activo = 1 ");
		sb.append(" left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" left join estado eos on eos.estado_id = cos.estado_id");
		sb.append(" left join parada pds on pds.parada_id = s.aliasdestino_id");
		sb.append(" left join ciudad cds on cds.ciudad_id = pds.ciudad_id");
		sb.append(" left join estado eds on eds.estado_id = cds.estado_id");
		sb.append(" left join empresa_imposto eis on eis.empresa_id = c.empresacorrida_id and eis.estado_id = eos.estado_id");
		sb.append(" left join fiscal_r4 r4 on r4.caja_id = c.caja_id");
		sb.append(" left join fiscal_r2 r2 on r2.numserie20 = imp.numserie20 and r2.datamov = to_char(c.feccreacion, 'YYYYMMDD')");
		sb.append(" where c.activo = 1 ");
		sb.append(" and coalesce(case when s.aliasorigen_id is null then ei.activo else eis.activo end, 0) = 1 ");
		sb.append(" and c.serieimpfiscal is not null ");
		sb.append(" and ((c.indreimpresion = 0 and c.motivocancelacion_id is null and c.numfoliosistema is not null) or (c.indstatusboleto = 'E' and c.indreimpresion = 1)) ");
		sb.append(" and (coalesce(c.preciopagado,0) + coalesce(c.importetaxaembarque,0) + coalesce(c.importeseguro,0) + coalesce(c.importepedagio,0) + coalesce(c.importeoutros,0)) > 0 ");
		sb.append(" and ((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)) > 0 ");
		sb.append(" and c.feccreacion >= to_date(?,'DD/MM/YYYY HH24:MI:SS') and c.feccreacion <= to_date(?,'DD/MM/YYYY HH24:MI:SS') ");
		sb.append(" and c.empresacorrida_id = ? ");
		sb.append(" and c.num_bpe is null ");
		sb.append(" and ((case when s.aliasorigen_id is null then eo.cveestado else eos.cveestado end) = ?) ");

		try {
			PreparedStatement ps = connection.prepareStatement(sb.toString());
			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);

			ResultSet rs = ps.executeQuery();

			ExportacaoECFBase registro = null;

			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");
				}

				registro = new ExportacaoECFBase();
				registro.setEcf(rs.getString("ecf"));
				registro.setNumeroSerie(rs.getString("numserie"));
				registro.setCooInicial(Integer.valueOf(rs.getString("cooinicial")));
				registro.setCooFinal(Integer.valueOf(rs.getString("coofinal")));
				registro.setContadorReducao(Integer.valueOf(rs.getString("crz")));
				registro.setCro(Integer.valueOf(rs.getString("cro")));
				registro.setCooReducaoZ(Integer.valueOf(rs.getString("r2_coo")));
				registro.setDataEmissao(rs.getString("datamov"));
				registro.setCoo(Integer.valueOf(rs.getString("r4_coo")));
				registro.setEstabelecimento(rs.getString("codestabelecimento"));
				registro.setEstabelecimentoECF(rs.getString("codestabelecimentoimpressora"));
				registro.setNumeroIdentificacaoECF(rs.getString("numeroidentificacao") == null || rs.getString("numeroidentificacao").isEmpty() ? "0" : rs.getString("numeroidentificacao"));
				registro.setUfOrigem(rs.getString("estado_origem"));
				registro.setMunicipioOrigem(Integer.valueOf(rs.getString("municipio_origem")));
				registro.setMunicipioDestino(Integer.valueOf(rs.getString("municipio_destino")));
				registro.setUfDestino(rs.getString("estado_destino"));
				registro.setReducaoBaseCalcICMS(rs.getBigDecimal("red_base_calc_icms"));
				registro.setPorcReducaoMunicipal(rs.getBigDecimal("porc_red_municipal"));
				registro.setPorcReducaoEstadual(rs.getBigDecimal("porc_red_estadual"));
				registro.setTributacaoImportacao(rs.getBigDecimal("tributacao_importacao"));
				registro.setNumFolioSistema(rs.getString("numFolioSistema"));
				registro.setInfoPadraoBilhetePassagem(CODIGO_INDICADOR_CONTR_PREVIDENCIARIA);

				registro.setIsenta(rs.getInt("isenta"));
				registro.setValorTributado(valortributado);
				registro.setValorTotal(valortotal);

				exportacaoECF.getListaRegistroECF().add(registro);
			}

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

			exportacaoECF.gerarListas();

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

		return exportacaoECF;
	}

	public void limparCache(Connection connection) {

		ConstanteService constanteService = (ConstanteService) AppContext.getApplicationContext().getBean("constanteService");
		Constante contante = constanteService.buscarPorNomeConstante("LIMPA_CACHE_RELATORIOS");
		String command = null;
		if ((contante != null && (StringUtils.isNotBlank(contante.getValorconstante())))) {
			command = contante.getValorconstante();

			PreparedStatement pstmt = null;
			try {
				pstmt = connection.prepareStatement(command);
				pstmt.executeBatch();
			} catch (Exception e) {
				log.error("", e);
			} finally {
				try {
					if (pstmt != null && !pstmt.isClosed()) {
						pstmt.close();
					}
				} catch (Exception e) {
					log.error("", e);
				}
			}
		}
	}

	@Deprecated
	@Override
	public List<ExportacaoECFTipoCFC> buscarRegistroECFTipoCFC(Connection connection, Date inicio, Date fim, Integer empresaId, String cveestado) {
		List<ExportacaoECFTipoCFC> retorno = new ArrayList<ExportacaoECFTipoCFC>();

		StringBuilder sb = new StringBuilder();
		sb.append(" select ecf, numserie, datamov, cooinicial, coofinal, crz, cro, coo, codestabelecimento, codestabelecimentoimpressora, numeroidentificacao, estadoorigem, sum(totalisenta) as totalisenta, sum(vendabrutadiaria) as vendabrutadiaria, sum(totgeral) as totgeral, sum(totalvenda) as totalvenda");
		sb.append(" from (");
		sb.append(" 	select distinct");
		sb.append(" 		imp.numserie20 as ecf,");
		sb.append(" 		imp.numserie as numserie,");
		sb.append(" 		r2.datamov as datamov,");
		sb.append(" 		r2.cooinicial as cooinicial,");
		sb.append(" 		r2.coofinal as coofinal,");
		sb.append(" 		r2.crz as crz,");
		sb.append(" 		r2.cro as cro,");
		sb.append(" 		r2.coo as coo,");
		sb.append(" 		CASE WHEN s.aliasorigen_id IS NULL THEN ei.codestabelecimento ELSE eis.codestabelecimento END as codestabelecimento,");
		sb.append(" 		e.codestabelecimento as codestabelecimentoimpressora,");
		sb.append(" 		imp.numeroidentificacao as numeroidentificacao,");
		sb.append(" 		(CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) as estadoorigem,");
		sb.append(" 		coalesce((");
		sb.append(" 			select sum((coalesce(to_number(r4i.imptotalliquido), 0) / 100 - coalesce((select sum(to_number(r5x.imptotalliquido) / 100) from fiscal_r5 r5x where r5x.contador = r4i.contador and r5x.numserie20 = r4i.numserie20 and r5x.totparcial like 'N1'), 0)))");
		sb.append(" 			from fiscal_r4 r4i");
		sb.append(" 			join caja ci on ci.caja_id = r4i.caja_id");
		sb.append(" 			join parada poi on poi.parada_id = ci.origen_id");
		sb.append(" 			join parada pdi on pdi.parada_id = ci.destino_id");
		sb.append(" 			left join alias_servico si on si.origen_id = ci.origen_id and si.destino_id = ci.destino_id and (si.corrida_id = ci.corrida_id or si.corrida_id is null) and si.ruta_id = ci.ruta_id");
		sb.append(" 			left join parada posi on posi.parada_id = si.aliasorigen_id");
		sb.append(" 			left join parada pdsi on pdsi.parada_id = si.aliasdestino_id");
		sb.append(" 			where r4i.numserie20 = r4.numserie20 and r4i.datamov = r2.datamov");
		sb.append(" 			and (nvl(case when si.aliasorigen_id is null then poi.regionmetropolitana_id else posi.regionmetropolitana_id end, -1) = nvl(case when si.aliasorigen_id is null then pdi.regionmetropolitana_id else pdsi.regionmetropolitana_id end, -2))");
		sb.append(" 		), 0) as totalisenta,");
		sb.append(" 		to_number(r2.vendabrutadiaria)/100 as vendabrutadiaria,");
		sb.append(" 		to_number(r2.totgeral)/100 as totgeral,");
		sb.append(" 		(");
		sb.append(" 		    (to_number(coalesce(r4.imptotalliquido,'0')) / 100) - ");
		sb.append(" 		    coalesce((");
		sb.append(" 		        select sum(to_number(coalesce(r5x.imptotalliquido,'0')) / 100)");
		sb.append(" 		        from fiscal_r5 r5x");
		sb.append(" 		        where r5x.contador = r4.contador and r5x.numserie20 = r4.numserie20 and r5x.totparcial like 'N1'");
		sb.append(" 		    ), 0)");
		sb.append(" 		) as totalvenda,");
		sb.append(" 		b.boleto_id as caja_id");
		sb.append(" 	from fiscal_r4 r4");
		sb.append(" 	join fiscal_r2 r2 on r2.numserie20 = r4.numserie20 and r2.datamov = r4.datamov");
		sb.append(" 	join fiscal_impressora imp on imp.numserie20 = r4.numserie20");
		sb.append(" 	join boleto b on b.boleto_id = r4.boleto_id");
		sb.append(" 	join parada po on po.parada_id = b.origen_id");
		sb.append(" 	join ciudad co on co.ciudad_id = po.ciudad_id");
		sb.append(" 	join estado eo on eo.estado_id = co.estado_id");
		sb.append(" 	join empresa_imposto ei on ei.empresa_id = b.empresacorrida_id and ei.estado_id = co.estado_id");
		sb.append(" 	left join alias_servico s on s.origen_id = b.origen_id and s.destino_id = b.destino_id and (s.corrida_id = b.corrida_id or s.corrida_id is null) and s.ruta_id = b.ruta_id");
		sb.append(" 	left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" 	left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" 	left join estado eos on eos.estado_id = cos.estado_id");
		sb.append(" 	left join empresa_imposto eis on eis.empresa_id = b.empresacorrida_id and eis.estado_id = cos.estado_id");
		sb.append(" 	left join estado e on e.estado_id = imp.estadolocal_id");
		sb.append(" 	where b.activo = 1");
		sb.append(" 	and nvl(CASE WHEN s.aliasorigen_id IS NULL THEN ei.activo ELSE eis.activo END, 0) = 1");
		sb.append(" 	and coalesce(r4.indcancelamento, 'N') <> 'S'");
		sb.append(" 	and r4.datamov >= ? and r4.datamov <= ?");
		sb.append(" 	and b.empresacorrida_id = ?");
		sb.append(" 	and ((CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) = ?)");
		sb.append(" 	UNION");
		sb.append(" 	select distinct");
		sb.append(" 		(case when r2.numserie20 is null then 'X' else '' end) || imp.numserie20 as ecf,");
		sb.append(" 		(case when r2.numserie20 is null then 'X' else '' end) || imp.numserie as numserie,");
		sb.append(" 		to_char(c.feccreacion, 'YYYYMMDD') as datamov,");
		sb.append(" 		case when r2.numserie20 is null then '000001' else r2.cooinicial end as cooinicial,");
		sb.append(" 		case when r2.numserie20 is null then '000001' else r2.coofinal end as coofinal,");
		sb.append(" 		case when r2.numserie20 is null then '0000' else r2.crz end as crz,");
		sb.append(" 		case when r2.numserie20 is null then '0000' else r2.cro end as cro,");
		sb.append(" 		case when r2.numserie20 is null then '000000' else r2.coo end as coo,");
		sb.append(" 		CASE WHEN s.aliasorigen_id IS NULL THEN ei.codestabelecimento ELSE eis.codestabelecimento END as codestabelecimento,");
		sb.append(" 		e.codestabelecimento as codestabelecimentoimpressora,");
		sb.append(" 		imp.numeroidentificacao as numeroidentificacao,");
		sb.append(" 		CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END as estadoorigem,");
		sb.append(" 		(");
		sb.append(" 			select nvl(sum(ci.preciopagado), 0)");
		sb.append(" 			from caja ci");
		sb.append(" 			join parada poi on poi.parada_id = ci.origen_id");
		sb.append(" 			join parada pdi on pdi.parada_id = ci.destino_id");
		sb.append(" 			left join alias_servico si on si.origen_id = ci.origen_id and si.destino_id = ci.destino_id and (si.corrida_id = ci.corrida_id or si.corrida_id is null) and si.ruta_id = ci.ruta_id");
		sb.append(" 			left join parada posi on posi.parada_id = si.aliasorigen_id");
		sb.append(" 			left join parada pdsi on pdsi.parada_id = si.aliasdestino_id");
		sb.append(" 			where ci.caja_id = c.caja_id");
		sb.append(" 			and (nvl(case when si.aliasorigen_id is null then poi.regionmetropolitana_id else posi.regionmetropolitana_id end, -1) = nvl(case when si.aliasorigen_id is null then pdi.regionmetropolitana_id else pdsi.regionmetropolitana_id end, -2))");
		sb.append(" 		) as totalisenta,");
		sb.append(" 		0 as vendabrutadiaria,");
		sb.append(" 		(");
		sb.append(" 			select nvl(sum(ci.preciopagado + ci.importetaxaembarque + ci.importeseguro + ci.importepedagio + ci.importeoutros), 0)");
		sb.append(" 			from caja ci");
		sb.append(" 			where ci.caja_id = c.caja_id");
		sb.append(" 		) as totgeral,");
		sb.append(" 		(");
		sb.append(" 			select nvl(sum(ci.preciopagado), 0)");
		sb.append(" 			from caja ci");
		sb.append(" 			where ci.caja_id = c.caja_id");
		sb.append(" 		) as totalvenda,");
		sb.append(" 		c.caja_id");
		sb.append(" 	from caja c");
		sb.append(" 	join parada po on po.parada_id = c.origen_id");
		sb.append(" 	join ciudad co on co.ciudad_id = po.ciudad_id");
		sb.append(" 	join estado eo on eo.estado_id = co.estado_id");
		sb.append(" 	join empresa_imposto ei on ei.empresa_id = c.empresacorrida_id and ei.estado_id = co.estado_id");
		sb.append(" 	join fiscal_impressora imp on imp.numserie = c.serieimpfiscal");
		sb.append(" 	left join alias_servico s on s.origen_id = c.origen_id and s.destino_id = c.destino_id and (s.corrida_id = c.corrida_id or s.corrida_id is null) and s.ruta_id = c.ruta_id");
		sb.append(" 	left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" 	left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" 	left join estado eos on eos.estado_id = cos.estado_id");
		sb.append(" 	left join empresa_imposto eis on eis.empresa_id = c.empresacorrida_id and eis.estado_id = cos.estado_id");
		sb.append(" 	left join fiscal_r4 r4 on r4.caja_id = c.caja_id");
		sb.append(" 	left join estado e on e.estado_id = imp.estadolocal_id");
		sb.append(" 	left join fiscal_r2 r2 on r2.numserie20 = imp.numserie20 and r2.datamov = to_char(c.feccreacion, 'YYYYMMDD')");
		sb.append(" 	where c.activo = 1 and po.activo = 1 and co.activo = 1 and eo.activo = 1 and ei.activo = 1");
		sb.append(" 	and c.serieimpfiscal is not null and r4.caja_id is null");
		sb.append(" 	and ((c.indreimpresion = 0 and c.motivocancelacion_id is null and c.numfoliosistema is not null) or (c.indstatusboleto = 'E' and c.indreimpresion = 1))");
		sb.append(" 	and coalesce(CASE WHEN s.aliasorigen_id IS NULL THEN ei.activo ELSE eis.activo END, 0) = 1");
		sb.append(" 	and c.feccreacion >= TO_DATE(?,'DD/MM/YYYY HH24:MI:SS') and c.feccreacion <= TO_DATE(?,'DD/MM/YYYY HH24:MI:SS')");
		sb.append(" 	and c.empresacorrida_id = ?");
		sb.append(" 	and ((CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) = ?)");
		sb.append(" )");
		sb.append(" having sum(totalvenda) > 0");
		sb.append(" group by ecf, numserie, datamov, cooinicial, coofinal, crz, cro, coo, codestabelecimento, codestabelecimentoimpressora, numeroidentificacao, estadoorigem");
		sb.append(" order by datamov");

		try {
			PreparedStatement ps = connection.prepareStatement(sb.toString());
			ps.setString(1, DateUtil.getStringDate(inicio, DATE_FORMAT_FISCAL));
			ps.setString(2, DateUtil.getStringDate(fim, DATE_FORMAT_FISCAL));
			ps.setLong(3, Long.valueOf(empresaId));
			ps.setString(4, cveestado);
			ps.setString(5, DateUtil.getStringDate(inicio, DATE_FORMAT_DMY + " 00:00:00"));
			ps.setString(6, DateUtil.getStringDate(fim, DATE_FORMAT_DMY + " 23:59:59"));
			ps.setLong(7, Long.valueOf(empresaId));
			ps.setString(8, cveestado);

			ResultSet rs = ps.executeQuery();

			ExportacaoECFTipoCFC registro = null;

			while (rs.next()) {
				BigDecimal totalIsenta = BigDecimal.ZERO;
				BigDecimal totalvenda = BigDecimal.ZERO;

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

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

				registro = new ExportacaoECFTipoCFC();
				registro.setEstabelecimento(rs.getString("codestabelecimento"));
				registro.setDataEmissao(rs.getString("datamov"));
				registro.setNumeroIdentificacaoECF(rs.getString("numeroidentificacao") == null || rs.getString("numeroidentificacao").isEmpty() ? "0" : rs.getString("numeroidentificacao"));
				registro.setEcf(rs.getString("ecf"));
				registro.setCooReducaoZ(Integer.valueOf(rs.getString("coo")));
				registro.setCooInicial(Integer.valueOf(rs.getString("cooinicial")));
				registro.setCooFinal(Integer.valueOf(rs.getString("coofinal")));
				registro.setContadorReducao(Integer.valueOf(rs.getString("crz")));
				registro.setCro(Integer.valueOf(rs.getString("cro")));
				registro.setValorTotal(totalvenda);
				registro.setValorIsentas(totalIsenta);
				registro.setEstabelecimentoECF(rs.getString("codestabelecimentoimpressora"));
				registro.setNumeroSerie(rs.getString("numserie"));
				registro.setInfoPadraoBilhetePassagem(CODIGO_INDICADOR_CONTR_PREVIDENCIARIA);

				retorno.add(registro);
			}

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

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

		return retorno;
	}

	@Deprecated
	@Override
	public List<ExportacaoECFTipoCCF> buscarRegistroECFTipoCCF(Connection connection, Date inicio, Date fim, Integer empresaId, String cveestado) {
		List<ExportacaoECFTipoCCF> retorno = new ArrayList<ExportacaoECFTipoCCF>();

		StringBuilder sb = new StringBuilder();
		sb.append(" select ecf, datamov, coo, sum(valortarifa) as valortarifa, sum(preciopagado) as preciopagado, municipio_origem, estado_origem, municipio_destino, estado_destino, red_base_calc_icms, porc_red_municipal, porc_red_estadual, tributacao_importacao, isenta, numfoliosistema, sum(valortotal) as valortotal");
		sb.append(" from (");
		sb.append(" 	select distinct");
		sb.append(" 	  r4.numserie20 as ecf,");
		sb.append(" 	  r4.datamov as datamov,");
		sb.append(" 	  r4.coo as coo,");
		sb.append(" 	  (");
		sb.append(" 		  (to_number(coalesce(r4.imptotalliquido,'0')) / 100) - ");
		sb.append(" 		  coalesce((");
		sb.append(" 		      select sum(to_number(coalesce(r5x.imptotalliquido,'0')) / 100)");
		sb.append(" 		      from fiscal_r5 r5x");
		sb.append(" 		      where r5x.contador = r4.contador and r5x.numserie20 = r4.numserie20 and r5x.totparcial like 'N1'");
		sb.append(" 		  ), 0)");
		sb.append(" 	  ) as valortarifa,");
		sb.append(" 	  c.preciopagado as preciopagado,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN co.codibge ELSE cos.codibge END) as municipio_origem,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) as estado_origem,");
		sb.append(" 	  (CASE WHEN s.aliasdestino_id IS NULL THEN cd.codibge ELSE cds.codibge END) as municipio_destino,");
		sb.append(" 	  (CASE WHEN s.aliasdestino_id IS NULL THEN ed.cveestado ELSE eds.cveestado END) as estado_destino,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredbaseicms ELSE eis.porcredbaseicms END) as red_base_calc_icms,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredmunicipal ELSE eis.porcredmunicipal END) as porc_red_municipal,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredestadual ELSE eis.porcredestadual END) as porc_red_estadual,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.tributacaoimportacao ELSE eis.tributacaoimportacao END) as tributacao_importacao,");
		sb.append(" 	  (CASE WHEN (nvl((CASE WHEN s.aliasorigen_id IS NULL THEN po.regionmetropolitana_id ELSE pos.regionmetropolitana_id END),-1) = nvl((CASE WHEN s.aliasdestino_id IS NULL THEN pd.regionmetropolitana_id ELSE pds.regionmetropolitana_id END),-2)) THEN 1 ELSE 0 END) as isenta,");
		sb.append(" 	  to_number(r4.impsubtotal)/100 as valortotal,");
		sb.append(" 	  b.numfoliosistema as numfoliosistema,");
		sb.append(" 	  b.boleto_id as caja_id");
		sb.append(" 	from fiscal_r4 r4");
		sb.append(" 	left join fiscal_r5 r5 on r5.numserie20 = r4.numserie20 and r5.coo = r4.coo and r5.totparcial not like 'N1'");
		sb.append(" 	left join caja c on c.caja_id = r4.caja_id");
		sb.append(" 	join fiscal_r2 r2 on r2.numserie20 = r4.numserie20 and r2.datamov = r4.datamov");
		sb.append(" 	join boleto b on b.boleto_id = r4.boleto_id");
		sb.append(" 	join parada po on po.parada_id = b.origen_id");
		sb.append(" 	join ciudad co on co.ciudad_id = po.ciudad_id");
		sb.append(" 	join estado eo on eo.estado_id = co.estado_id");
		sb.append(" 	join parada pd on pd.parada_id = b.destino_id");
		sb.append(" 	join ciudad cd on cd.ciudad_id = pd.ciudad_id");
		sb.append(" 	join estado ed on ed.estado_id = cd.estado_id");
		sb.append(" 	join empresa_imposto ei on ei.empresa_id = b.empresacorrida_id and ei.estado_id = eo.estado_id");
		sb.append(" 	left join alias_servico s on s.origen_id = b.origen_id and s.destino_id = b.destino_id and (s.corrida_id = b.corrida_id or s.corrida_id is null) and s.ruta_id = b.ruta_id");
		sb.append(" 	left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" 	left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" 	left join estado eos on eos.estado_id = cos.estado_id");
		sb.append(" 	left join parada pds on pds.parada_id = s.aliasdestino_id");
		sb.append(" 	left join ciudad cds on cds.ciudad_id = pds.ciudad_id");
		sb.append(" 	left join estado eds on eds.estado_id = cds.estado_id");
		sb.append(" 	left join empresa_imposto eis on eis.empresa_id = b.empresacorrida_id and eis.estado_id = eos.estado_id");
		sb.append(" 	where coalesce(r4.indcancelamento, 'N') <> 'S' and nvl(CASE WHEN s.aliasorigen_id IS NULL THEN ei.activo ELSE eis.activo END, 0) = 1 and b.activo = 1 and r4.datamov >= ? and r4.datamov <= ? and b.empresacorrida_id = ? and ((CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) = ?)");
		sb.append(" 	UNION");
		sb.append(" 	select distinct");
		sb.append(" 	  (case when r2.numserie20 is null then 'X' else '' end) || imp.numserie20 as ecf,");
		sb.append(" 	  to_char(c.feccreacion, 'YYYYMMDD') as datamov,");
		sb.append(" 	  '000001' as coo,");
		sb.append(" 	  c.preciopagado as valortarifa,");
		sb.append(" 	  c.preciopagado as preciopagado,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN co.codibge ELSE cos.codibge END) as municipio_origem,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) as estado_origem,");
		sb.append(" 	  (CASE WHEN s.aliasdestino_id IS NULL THEN cd.codibge ELSE cds.codibge END) as municipio_destino,");
		sb.append(" 	  (CASE WHEN s.aliasdestino_id IS NULL THEN ed.cveestado ELSE eds.cveestado END) as estado_destino,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredbaseicms ELSE eis.porcredbaseicms END) as red_base_calc_icms,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredmunicipal ELSE eis.porcredmunicipal END) as porc_red_municipal,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredestadual ELSE eis.porcredestadual END) as porc_red_estadual,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.tributacaoimportacao ELSE eis.tributacaoimportacao END) as tributacao_importacao,");
		sb.append(" 	  (CASE WHEN (nvl((CASE WHEN s.aliasorigen_id IS NULL THEN po.regionmetropolitana_id ELSE pos.regionmetropolitana_id END),-1) = nvl((CASE WHEN s.aliasdestino_id IS NULL THEN pd.regionmetropolitana_id ELSE pds.regionmetropolitana_id END),-2)) THEN 1 ELSE 0 END) as isenta,");
		sb.append(" 	  c.preciopagado + c.importetaxaembarque + c.importeseguro + c.importepedagio + c.importeoutros as valortotal,");
		sb.append(" 	  c.numfoliosistema as numfoliosistema,");
		sb.append(" 	  c.caja_id");
		sb.append(" 	from caja c");
		sb.append(" 	join parada po on po.parada_id = c.origen_id");
		sb.append(" 	join ciudad co on co.ciudad_id = po.ciudad_id");
		sb.append(" 	join estado eo on eo.estado_id = co.estado_id");
		sb.append(" 	join parada pd on pd.parada_id = c.destino_id");
		sb.append(" 	join ciudad cd on cd.ciudad_id = pd.ciudad_id");
		sb.append(" 	join estado ed on ed.estado_id = cd.estado_id");
		sb.append(" 	join empresa_imposto ei on ei.empresa_id = c.empresacorrida_id and ei.estado_id = eo.estado_id");
		sb.append(" 	join fiscal_impressora imp on imp.numserie = c.serieimpfiscal");
		sb.append(" 	left join alias_servico s on s.origen_id = c.origen_id and s.destino_id = c.destino_id and (s.corrida_id = c.corrida_id or s.corrida_id is null) and s.ruta_id = c.ruta_id");
		sb.append(" 	left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" 	left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" 	left join estado eos on eos.estado_id = cos.estado_id");
		sb.append(" 	left join parada pds on pds.parada_id = s.aliasdestino_id");
		sb.append(" 	left join ciudad cds on cds.ciudad_id = pds.ciudad_id");
		sb.append(" 	left join estado eds on eds.estado_id = cds.estado_id");
		sb.append(" 	left join empresa_imposto eis on eis.empresa_id = c.empresacorrida_id and eis.estado_id = eos.estado_id");
		sb.append(" 	left join fiscal_r4 r4 on r4.caja_id = c.caja_id");
		sb.append(" 	left join fiscal_r2 r2 on r2.numserie20 = imp.numserie20 and r2.datamov = to_char(c.feccreacion, 'YYYYMMDD')");
		sb.append(" 	where c.activo = 1 and po.activo = 1 and co.activo = 1 and eo.activo = 1 and ei.activo = 1");
		sb.append(" 	and coalesce(CASE WHEN s.aliasorigen_id IS NULL THEN ei.activo ELSE eis.activo END, 0) = 1");
		sb.append(" 	and c.serieimpfiscal is not null and r4.caja_id is null");
		sb.append(" 	and ((c.indreimpresion = 0 and c.motivocancelacion_id is null and c.numfoliosistema is not null) or (c.indstatusboleto = 'E' and c.indreimpresion = 1))");
		sb.append(" 	and (c.preciopagado + c.importetaxaembarque + c.importeseguro + c.importepedagio + c.importeoutros) > 0");
		sb.append(" 	and c.feccreacion >= TO_DATE(?,'DD/MM/YYYY HH24:MI:SS') and c.feccreacion <= TO_DATE(?,'DD/MM/YYYY HH24:MI:SS')");
		sb.append(" 	and c.empresacorrida_id = ?");
		sb.append(" 	and ((CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) = ?)");
		sb.append(" ) ");
		sb.append(" group by ecf, datamov, coo, municipio_origem, estado_origem, municipio_destino, estado_destino, red_base_calc_icms, porc_red_municipal, porc_red_estadual, tributacao_importacao, isenta, numfoliosistema");

		try {
			PreparedStatement ps = connection.prepareStatement(sb.toString());
			ps.setString(1, DateUtil.getStringDate(inicio, DATE_FORMAT_FISCAL));
			ps.setString(2, DateUtil.getStringDate(fim, DATE_FORMAT_FISCAL));
			ps.setLong(3, Long.valueOf(empresaId));
			ps.setString(4, cveestado);
			ps.setString(5, DateUtil.getStringDate(inicio, DATE_FORMAT_DMY + " 00:00:00"));
			ps.setString(6, DateUtil.getStringDate(fim, DATE_FORMAT_DMY + " 23:59:59"));
			ps.setLong(7, Long.valueOf(empresaId));
			ps.setString(8, cveestado);

			ResultSet rs = ps.executeQuery();

			ExportacaoECFTipoCCF registro = null;

			while (rs.next()) {
				BigDecimal valorTributado = BigDecimal.ZERO;

				if (rs.getString("valortarifa") != null) {
					valorTributado = BigDecimal.valueOf(Double.valueOf(rs.getString("valortarifa")));
				} else {
					valorTributado = rs.getBigDecimal("preciopagado");

					log.info("Tarifa nao encontrada na R5. (ECF: " + rs.getString("ecf") + " / DATAMOV: " + rs.getString("datamov") + " / COO: " + rs.getString("coo") + ")");
				}

				registro = new ExportacaoECFTipoCCF();
				registro.setEcf(rs.getString("ecf"));
				registro.setDataEmissao(rs.getString("datamov"));
				registro.setCoo(Integer.valueOf(rs.getString("coo")));
				registro.setValorServico(valorTributado);
				registro.setDescontoGlobal(null);
				registro.setCodigoParticipante(null);
				registro.setSituacaoCOO(0); // 0 - Documento Regular; 2 - Documento Cancelado
				registro.setAcrescimo(null);
				registro.setNumFolioSistema(rs.getString("numFolioSistema"));

				registro.setCodigoSituacaoTribColunaB(null);

				// 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
				if (rs.getInt("isenta") == 1) {
					registro.setCodigoSituacaoTribColunaB(40);
				}

				registro.setUfOrigem(rs.getString("estado_origem"));
				registro.setMunicipioOrigem(Integer.valueOf(rs.getString("municipio_origem")));
				registro.setUfDestino(rs.getString("estado_destino"));

				// IM=5357; serviço IE= 6357
				if (rs.getString("estado_origem").equals(rs.getString("estado_destino"))) {
					registro.setCfop(5357);
				} else {
					registro.setCfop(6357);
				}

				// 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
				if (registro.getCodigoSituacaoTribColunaB() == null) {
					registro.setCodigoSituacaoTribColunaB(rs.getInt("red_base_calc_icms") == 0 ? 0 : 20);
				}

				// TODO: Mudança para o valor tributado (Email no dia 9 de agosto de 2017 08:28)
				BigDecimal valorTotal = valorTributado; // BigDecimal.valueOf(Double.valueOf(rs.getString("valortotal")));

				BigDecimal red_base_calc_icms = rs.getBigDecimal("red_base_calc_icms");
				// BigDecimal porc_red_municipal = rs.getBigDecimal("porc_red_municipal");
				// BigDecimal porc_red_estadual = rs.getBigDecimal("porc_red_estadual");
				BigDecimal tributacao_importacao = rs.getBigDecimal("tributacao_importacao");
				BigDecimal valorBaseCalculoICMS = BigDecimal.ZERO;

				if ("30|40|41|50|60".contains(registro.getCodigoSituacaoTribColunaB().toString())) {
					tributacao_importacao = BigDecimal.ZERO;
				}

				if (red_base_calc_icms != null) {
					valorBaseCalculoICMS = valorTotal.subtract(valorTotal.multiply(red_base_calc_icms.divide(BigDecimal.valueOf(100d))));
				} else {
					// if (tributacao_importacao != null) {
					// if (rs.getString("estado_origem").equals(rs.getString("estado_destino"))) {
					// if (porc_red_municipal != null) {
					// BigDecimal porc = tributacao_importacao.subtract(tributacao_importacao.multiply(porc_red_municipal.divide(BigDecimal.valueOf(100d))));
					// valorBaseCalculoICMS = valorTotal.multiply(porc.divide(BigDecimal.valueOf(100d)));
					// }
					// } else {
					// if (porc_red_estadual != null) {
					// BigDecimal porc = tributacao_importacao.subtract(tributacao_importacao.multiply(porc_red_estadual.divide(BigDecimal.valueOf(100d))));
					// valorBaseCalculoICMS = valorTotal.multiply(porc.divide(BigDecimal.valueOf(100d)));
					// }
					// }
					// }

					// Email 17/02/2017
					valorBaseCalculoICMS = valorTotal;
				}

				if (rs.getInt("isenta") == 1) {
					valorBaseCalculoICMS = null;
				}

				registro.setValorTotal(valorTotal);

				// 1 - Demais; 2 - Região Metropolitanao ou seja, quando o campo CSTB for "40", esse campo deve vir "2". Do contrário, deve vir "1"
				registro.setTributacaoICMS(registro.getCodigoSituacaoTribColunaB() == 40 ? 2 : 1);

				registro.setValorBaseCalculoICMS(valorBaseCalculoICMS);
				registro.setAliquotaICMS(tributacao_importacao);

				if (valorTotal.doubleValue() != 0) {
					retorno.add(registro);
				}
			}

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

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

		return retorno;
	}

	@Deprecated
	@Override
	public List<ExportacaoECFTipoICF> buscarRegistroECFTipoICF(Connection connection, Date inicio, Date fim, Integer empresaId, String cveestado) {
		List<ExportacaoECFTipoICF> retorno = new ArrayList<ExportacaoECFTipoICF>();

		StringBuilder sb = new StringBuilder();
		sb.append(" select ecf, datamov, coo, municipio_origem, estado_origem, municipio_destino, estado_destino, red_base_calc_icms, porc_red_municipal, porc_red_estadual, tributacao_importacao, isenta, sum(valortotal) as valortotal");
		sb.append(" from (");
		sb.append(" 	select distinct");
		sb.append(" 	  r4.numserie20 as ecf,");
		sb.append(" 	  r4.datamov as datamov,");
		sb.append(" 	  r4.coo as coo,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN co.codibge ELSE cos.codibge END) as municipio_origem,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) as estado_origem,");
		sb.append(" 	  (CASE WHEN s.aliasdestino_id IS NULL THEN cd.codibge ELSE cds.codibge END) as municipio_destino,");
		sb.append(" 	  (CASE WHEN s.aliasdestino_id IS NULL THEN ed.cveestado ELSE eds.cveestado END) as estado_destino,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredbaseicms ELSE eis.porcredbaseicms END) as red_base_calc_icms,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredmunicipal ELSE eis.porcredmunicipal END) as porc_red_municipal,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredestadual ELSE eis.porcredestadual END) as porc_red_estadual,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.tributacaoimportacao ELSE eis.tributacaoimportacao END) as tributacao_importacao,");
		sb.append(" 	  (CASE WHEN (nvl((CASE WHEN s.aliasorigen_id IS NULL THEN po.regionmetropolitana_id ELSE pos.regionmetropolitana_id END),-1) = nvl((CASE WHEN s.aliasdestino_id IS NULL THEN pd.regionmetropolitana_id ELSE pds.regionmetropolitana_id END),-2)) THEN 1 ELSE 0 END) as isenta,");
		sb.append(" 	  (");
		sb.append(" 		  (to_number(coalesce(r4.imptotalliquido,'0')) / 100) - ");
		sb.append(" 		  coalesce((");
		sb.append(" 		      select sum(to_number(coalesce(r5x.imptotalliquido,'0')) / 100)");
		sb.append(" 		      from fiscal_r5 r5x");
		sb.append(" 		      where r5x.contador = r4.contador and r5x.numserie20 = r4.numserie20 and r5x.totparcial like 'N1'");
		sb.append(" 		  ), 0)");
		sb.append(" 	  ) as valortotal");
		sb.append(" 	from fiscal_r4 r4");
		sb.append(" 	join fiscal_r2 r2 on r2.numserie20 = r4.numserie20 and r2.datamov = r4.datamov");
		sb.append(" 	join boleto b on b.boleto_id = r4.boleto_id");
		sb.append(" 	join parada po on po.parada_id = b.origen_id");
		sb.append(" 	join ciudad co on co.ciudad_id = po.ciudad_id");
		sb.append(" 	join estado eo on eo.estado_id = co.estado_id");
		sb.append(" 	join parada pd on pd.parada_id = b.destino_id");
		sb.append(" 	join ciudad cd on cd.ciudad_id = pd.ciudad_id");
		sb.append(" 	join estado ed on ed.estado_id = cd.estado_id");
		sb.append(" 	join empresa_imposto ei on ei.empresa_id = b.empresacorrida_id and ei.estado_id = eo.estado_id");
		sb.append(" 	left join alias_servico s on s.origen_id = b.origen_id and s.destino_id = b.destino_id and (s.corrida_id = b.corrida_id or s.corrida_id is null) and s.ruta_id = b.ruta_id");
		sb.append(" 	left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" 	left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" 	left join estado eos on eos.estado_id = cos.estado_id");
		sb.append(" 	left join parada pds on pds.parada_id = s.aliasdestino_id");
		sb.append(" 	left join ciudad cds on cds.ciudad_id = pds.ciudad_id");
		sb.append(" 	left join estado eds on eds.estado_id = cds.estado_id");
		sb.append(" 	left join empresa_imposto eis on eis.empresa_id = b.empresacorrida_id and eis.estado_id = eos.estado_id");
		sb.append(" 	where coalesce(r4.indcancelamento, 'N') <> 'S' and nvl(CASE WHEN s.aliasorigen_id IS NULL THEN ei.activo ELSE eis.activo END, 0) = 1 and b.activo = 1 and r4.datamov >= ? and r4.datamov <= ? and b.empresacorrida_id = ? and ((CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) = ?)");
		sb.append(" 	UNION");
		sb.append(" 	select distinct");
		sb.append(" 	  (case when r2.numserie20 is null then 'X' else '' end) || imp.numserie20 as ecf,");
		sb.append(" 	  to_char(c.feccreacion, 'YYYYMMDD') as datamov,");
		sb.append(" 	  '000001' as coo,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN co.codibge ELSE cos.codibge END) as municipio_origem,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) as estado_origem,");
		sb.append(" 	  (CASE WHEN s.aliasdestino_id IS NULL THEN cd.codibge ELSE cds.codibge END) as municipio_destino,");
		sb.append(" 	  (CASE WHEN s.aliasdestino_id IS NULL THEN ed.cveestado ELSE eds.cveestado END) as estado_destino,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredbaseicms ELSE eis.porcredbaseicms END) as red_base_calc_icms,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredmunicipal ELSE eis.porcredmunicipal END) as porc_red_municipal,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredestadual ELSE eis.porcredestadual END) as porc_red_estadual,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.tributacaoimportacao ELSE eis.tributacaoimportacao END) as tributacao_importacao,");
		sb.append(" 	  (CASE WHEN (nvl((CASE WHEN s.aliasorigen_id IS NULL THEN po.regionmetropolitana_id ELSE pos.regionmetropolitana_id END),-1) = nvl((CASE WHEN s.aliasdestino_id IS NULL THEN pd.regionmetropolitana_id ELSE pds.regionmetropolitana_id END),-2)) THEN 1 ELSE 0 END) as isenta,");
		sb.append(" 	  (c.preciopagado) as valortotal");
		sb.append(" 	from caja c");
		sb.append(" 	join parada po on po.parada_id = c.origen_id");
		sb.append(" 	join ciudad co on co.ciudad_id = po.ciudad_id");
		sb.append(" 	join estado eo on eo.estado_id = co.estado_id");
		sb.append(" 	join parada pd on pd.parada_id = c.destino_id");
		sb.append(" 	join ciudad cd on cd.ciudad_id = pd.ciudad_id");
		sb.append(" 	join estado ed on ed.estado_id = cd.estado_id");
		sb.append(" 	join empresa_imposto ei on ei.empresa_id = c.empresacorrida_id and ei.estado_id = eo.estado_id");
		sb.append(" 	join fiscal_impressora imp on imp.numserie = c.serieimpfiscal");
		sb.append(" 	left join alias_servico s on s.origen_id = c.origen_id and s.destino_id = c.destino_id and (s.corrida_id = c.corrida_id or s.corrida_id is null) and s.ruta_id = c.ruta_id");
		sb.append(" 	left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" 	left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" 	left join estado eos on eos.estado_id = cos.estado_id");
		sb.append(" 	left join parada pds on pds.parada_id = s.aliasdestino_id");
		sb.append(" 	left join ciudad cds on cds.ciudad_id = pds.ciudad_id");
		sb.append(" 	left join estado eds on eds.estado_id = cds.estado_id");
		sb.append(" 	left join empresa_imposto eis on eis.empresa_id = c.empresacorrida_id and eis.estado_id = eos.estado_id");
		sb.append(" 	left join fiscal_r4 r4 on r4.caja_id = c.caja_id");
		sb.append(" 	left join fiscal_r2 r2 on r2.numserie20 = imp.numserie20 and r2.datamov = to_char(c.feccreacion, 'YYYYMMDD')");
		sb.append(" 	where c.activo = 1 and po.activo = 1 and co.activo = 1 and eo.activo = 1 and ei.activo = 1");
		sb.append(" 	and coalesce(CASE WHEN s.aliasorigen_id IS NULL THEN ei.activo ELSE eis.activo END, 0) = 1");
		sb.append(" 	and ((c.indreimpresion = 0 and c.motivocancelacion_id is null and c.numfoliosistema is not null) or (c.indstatusboleto = 'E' and c.indreimpresion = 1))");
		sb.append(" 	and (c.preciopagado) > 0");
		sb.append(" 	and c.serieimpfiscal is not null and r4.caja_id is null");
		sb.append(" 	and c.feccreacion >= TO_DATE(?,'DD/MM/YYYY HH24:MI:SS') and c.feccreacion <= TO_DATE(?,'DD/MM/YYYY HH24:MI:SS')");
		sb.append(" 	and c.empresacorrida_id = ?");
		sb.append(" 	and ((CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) = ?)");
		sb.append(" )");
		sb.append(" group by ecf, datamov, coo, municipio_origem, estado_origem, municipio_destino, estado_destino, red_base_calc_icms, porc_red_municipal, porc_red_estadual, tributacao_importacao, isenta");
		sb.append(" order by ecf, datamov");

		try {
			PreparedStatement ps = connection.prepareStatement(sb.toString());
			ps.setString(1, DateUtil.getStringDate(inicio, DATE_FORMAT_FISCAL));
			ps.setString(2, DateUtil.getStringDate(fim, DATE_FORMAT_FISCAL));
			ps.setLong(3, Long.valueOf(empresaId));
			ps.setString(4, cveestado);
			ps.setString(5, DateUtil.getStringDate(inicio, DATE_FORMAT_DMY + " 00:00:00"));
			ps.setString(6, DateUtil.getStringDate(fim, DATE_FORMAT_DMY + " 23:59:59"));
			ps.setLong(7, Long.valueOf(empresaId));
			ps.setString(8, cveestado);

			ResultSet rs = ps.executeQuery();

			ExportacaoECFTipoICF registro = null;

			Map<String, ExportacaoECFTipoICF> group = new HashMap<String, ExportacaoECFTipoICF>();

			while (rs.next()) {
				BigDecimal valorTotal = rs.getBigDecimal("valortotal");

				if (valorTotal == null || valorTotal.doubleValue() == 0) {
					continue;
				}

				BigDecimal red_base_calc_icms = MoneyHelper.instanciar(rs.getBigDecimal("red_base_calc_icms"));
				BigDecimal porc_red_municipal = MoneyHelper.instanciar(rs.getBigDecimal("porc_red_municipal"));
				BigDecimal porc_red_estadual = MoneyHelper.instanciar(rs.getBigDecimal("porc_red_estadual"));
				BigDecimal tributacao_importacao = MoneyHelper.instanciar(rs.getBigDecimal("tributacao_importacao"));
				BigDecimal valorBaseCalculoICMS = BigDecimal.ZERO;

				if (red_base_calc_icms != null) {
					BigDecimal aRed_base_calc_icms = MoneyHelper.dividir(red_base_calc_icms, BigDecimal.valueOf(100d));
					valorBaseCalculoICMS = MoneyHelper.subtrair(valorTotal, MoneyHelper.multiplicar(valorTotal, aRed_base_calc_icms));
				} else {
					// if (tributacao_importacao != null) {
					// if (rs.getString("estado_origem").equals(rs.getString("estado_destino"))) {
					// if (porc_red_municipal != null) {
					// BigDecimal aPorc_red_municipal = MoneyHelper.dividir(porc_red_municipal, BigDecimal.valueOf(100d));
					// BigDecimal porc = MoneyHelper.subtrair(tributacao_importacao, MoneyHelper.multiplicar(tributacao_importacao, aPorc_red_municipal));
					// BigDecimal aPorc = MoneyHelper.dividir(porc, BigDecimal.valueOf(100d));
					//
					// valorBaseCalculoICMS = MoneyHelper.multiplicar(valorTotal, aPorc);
					// }
					// } else {
					// if (porc_red_estadual != null) {
					// BigDecimal aPorc_red_estadual = MoneyHelper.dividir(porc_red_estadual, BigDecimal.valueOf(100d));
					// BigDecimal porc = MoneyHelper.subtrair(tributacao_importacao, MoneyHelper.multiplicar(tributacao_importacao, aPorc_red_estadual));
					// BigDecimal aPorc = MoneyHelper.dividir(porc, BigDecimal.valueOf(100d));
					//
					// valorBaseCalculoICMS = MoneyHelper.multiplicar(valorTotal, aPorc);
					// }
					// }
					// }

					// Email 17/02/2017
					valorBaseCalculoICMS = valorTotal;
				}

				BigDecimal valorICMSDebitado = BigDecimal.ZERO;

				if (tributacao_importacao != null) {
					BigDecimal aTributacao_importacao = MoneyHelper.dividir(tributacao_importacao, BigDecimal.valueOf(100d));
					valorICMSDebitado = MoneyHelper.multiplicar(valorBaseCalculoICMS, aTributacao_importacao);
				}

				BigDecimal valorICMSIsento = BigDecimal.ZERO;
				BigDecimal valorICMSOutros = MoneyHelper.subtrair(valorTotal, valorBaseCalculoICMS);

				String ecf = rs.getString("ecf");
				String datamov = rs.getString("datamov");
				String ufDestino = "";
				String ufOrigem = "";
				Integer municipioOrigem = 0;
				Integer cfop = 0; // IM=5357; serviço IE= 6357

				// 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
				Integer codigoSituacaoTribColunaB = null;

				if (rs.getInt("isenta") == 1) {
					codigoSituacaoTribColunaB = 40;

					valorICMSOutros = valorTotal;
				}

				ufDestino = rs.getString("estado_destino");
				ufOrigem = rs.getString("estado_origem");
				municipioOrigem = rs.getInt("municipio_origem");

				// IM=5357; serviço IE= 6357
				if (rs.getString("estado_origem").equals(rs.getString("estado_destino"))) {
					cfop = 5357;
				} else {
					cfop = 6357;
				}

				// 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
				if (codigoSituacaoTribColunaB == null) {
					codigoSituacaoTribColunaB = rs.getInt("red_base_calc_icms") == 0 ? 0 : 20;
				}

				if (codigoSituacaoTribColunaB == 40) {
					tributacao_importacao = BigDecimal.ZERO;
					valorBaseCalculoICMS = BigDecimal.ZERO;
					valorICMSDebitado = BigDecimal.ZERO;
					valorICMSOutros = BigDecimal.ZERO;

					valorICMSIsento = valorTotal;
				}

				String key = ecf + "|" + datamov + "|" + ufDestino + "|" + cfop.toString() + "|" + codigoSituacaoTribColunaB.toString();

				if (group.containsKey(key)) {
					registro = group.get(key);

					valorTotal = MoneyHelper.somar(valorTotal, registro.getValorTotal());
					valorBaseCalculoICMS = MoneyHelper.somar(valorBaseCalculoICMS, registro.getValorBaseCalculoICMS());
					valorICMSDebitado = MoneyHelper.somar(valorICMSDebitado, registro.getValorICMSDebitado());
					valorICMSIsento = MoneyHelper.somar(valorICMSIsento, registro.getValorICMSIsento());
					valorICMSOutros = MoneyHelper.somar(valorICMSOutros, registro.getValorICMSOutros());
				} else {
					registro = new ExportacaoECFTipoICF();
					registro.setEcf(ecf);
					registro.setDataEmissao(datamov);
					registro.setUfDestino(ufDestino);
					registro.setCfop(cfop); // IM=5357; serviço IE= 6357
					registro.setCodigoSituacaoTribColunaB(codigoSituacaoTribColunaB); // 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
					registro.setAliquotaICMS(tributacao_importacao);
					registro.setUfOrigem(ufOrigem);
					registro.setMunicipioOrigem(municipioOrigem);

					registro.setRedutorBaseCalculoIcms(red_base_calc_icms);
					registro.setRedutorMunicipalIcms(porc_red_municipal);
					registro.setRedutorEstadualIcms(porc_red_estadual);

					group.put(key, registro);
				}

				registro.setValorTotal(valorTotal);
				registro.setValorBaseCalculoICMS(valorBaseCalculoICMS);
				registro.setValorICMSDebitado(valorICMSDebitado);
				registro.setValorICMSIsento(valorICMSIsento);
				registro.setValorICMSOutros(valorICMSOutros);
			}

			for (Map.Entry<String, ExportacaoECFTipoICF> entry : group.entrySet()) {
				retorno.add(entry.getValue());
			}

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

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

		return retorno;
	}

	@Deprecated
	@Override
	public List<ExportacaoECFTipoPRC> buscarRegistroECFTipoPRC(final Connection conn, final Date inicio, final Date fim, final Integer empresaId, final String cveestado) {
		final List<ExportacaoECFTipoPRC> retorno = new ArrayList<ExportacaoECFTipoPRC>();

		final StringBuilder sb = new StringBuilder();
		sb.append(" select ecf, datamov, municipio_origem, estado_origem, estado_destino, red_base_calc_icms, porc_red_municipal, porc_red_estadual, tributacao_importacao, SUM(valortotal) as valortotal");
		sb.append(" from (");
		sb.append(" 	select distinct");
		sb.append(" 	  r4.coo as coo,");
		sb.append(" 	  r4.numserie20 as ecf,");
		sb.append(" 	  r4.datamov as datamov,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN co.codibge ELSE cos.codibge END) as municipio_origem,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) as estado_origem,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ed.cveestado ELSE eds.cveestado END) as estado_destino,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredbaseicms ELSE eis.porcredbaseicms END) as red_base_calc_icms,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredmunicipal ELSE eis.porcredmunicipal END) as porc_red_municipal,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredestadual ELSE eis.porcredestadual END) as porc_red_estadual,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.tributacaoimportacao ELSE eis.tributacaoimportacao END) as tributacao_importacao,");
		sb.append(" 	  (");
		sb.append(" 		  (to_number(coalesce(r4.imptotalliquido,'0')) / 100) - ");
		sb.append(" 		  coalesce((");
		sb.append(" 		      select sum(to_number(coalesce(r5x.imptotalliquido,'0')) / 100)");
		sb.append(" 		      from fiscal_r5 r5x");
		sb.append(" 		      where r5x.contador = r4.contador and r5x.numserie20 = r4.numserie20 and r5x.totparcial like 'N1'");
		sb.append(" 		  ), 0)");
		sb.append(" 	  ) as valortotal,");
		sb.append(" 	  b.boleto_id as caja_id");
		sb.append(" 	from fiscal_r4 r4");
		sb.append(" 	join fiscal_r2 r2 on r2.numserie20 = r4.numserie20 and r2.datamov = r4.datamov");
		sb.append(" 	join boleto b on b.boleto_id = r4.boleto_id");
		sb.append(" 	join parada po on po.parada_id = b.origen_id");
		sb.append(" 	join ciudad co on co.ciudad_id = po.ciudad_id");
		sb.append(" 	join estado eo on eo.estado_id = co.estado_id");
		sb.append(" 	join parada pd on pd.parada_id = b.destino_id");
		sb.append(" 	join ciudad cd on cd.ciudad_id = pd.ciudad_id");
		sb.append(" 	join estado ed on ed.estado_id = cd.estado_id");
		sb.append(" 	join empresa_imposto ei on ei.empresa_id = b.empresacorrida_id and ei.estado_id = eo.estado_id");
		sb.append(" 	left join alias_servico s on s.origen_id = b.origen_id and s.destino_id = b.destino_id and (s.corrida_id = b.corrida_id or s.corrida_id is null) and s.ruta_id = b.ruta_id");
		sb.append(" 	left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" 	left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" 	left join estado eos on eos.estado_id = cos.estado_id");
		sb.append(" 	left join parada pds on pds.parada_id = s.aliasdestino_id");
		sb.append(" 	left join ciudad cds on cds.ciudad_id = pds.ciudad_id");
		sb.append(" 	left join estado eds on eds.estado_id = cds.estado_id");
		sb.append(" 	left join empresa_imposto eis on eis.empresa_id = b.empresacorrida_id and eis.estado_id = eos.estado_id");
		sb.append(" 	where coalesce(r4.indcancelamento, 'N') <> 'S' and nvl(CASE WHEN s.aliasorigen_id IS NULL THEN ei.activo ELSE eis.activo END, 0) = 1 and b.activo = 1 and r4.datamov >= ? and r4.datamov <= ? and b.empresacorrida_id = ? and ((CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) = ?)");
		sb.append(" 	UNION");
		sb.append(" 	select distinct");
		sb.append(" 	  '000001' as coo,");
		sb.append(" 	  (case when r2.numserie20 is null then 'X' else '' end) || imp.numserie20 as ecf,");
		sb.append(" 	  to_char(c.feccreacion, 'YYYYMMDD') as datamov,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN co.codibge ELSE cos.codibge END) as municipio_origem,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) as estado_origem,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ed.cveestado ELSE eds.cveestado END) as estado_destino,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredbaseicms ELSE eis.porcredbaseicms END) as red_base_calc_icms,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredmunicipal ELSE eis.porcredmunicipal END) as porc_red_municipal,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredestadual ELSE eis.porcredestadual END) as porc_red_estadual,");
		sb.append(" 	  (CASE WHEN s.aliasorigen_id IS NULL THEN ei.tributacaoimportacao ELSE eis.tributacaoimportacao END) as tributacao_importacao,");
		sb.append(" 	  c.preciopagado as valortotal,");
		sb.append(" 	  c.caja_id");
		sb.append(" 	from caja c");
		sb.append(" 	join parada po on po.parada_id = c.origen_id");
		sb.append(" 	join ciudad co on co.ciudad_id = po.ciudad_id");
		sb.append(" 	join estado eo on eo.estado_id = co.estado_id");
		sb.append(" 	join parada pd on pd.parada_id = c.destino_id");
		sb.append(" 	join ciudad cd on cd.ciudad_id = pd.ciudad_id");
		sb.append(" 	join estado ed on ed.estado_id = cd.estado_id");
		sb.append(" 	join empresa_imposto ei on ei.empresa_id = c.empresacorrida_id and ei.estado_id = eo.estado_id");
		sb.append(" 	join fiscal_impressora imp on imp.numserie = c.serieimpfiscal");
		sb.append(" 	left join alias_servico s on s.origen_id = c.origen_id and s.destino_id = c.destino_id and (s.corrida_id = c.corrida_id or s.corrida_id is null) and s.ruta_id = c.ruta_id");
		sb.append(" 	left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" 	left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" 	left join estado eos on eos.estado_id = cos.estado_id");
		sb.append(" 	left join parada pds on pds.parada_id = s.aliasdestino_id");
		sb.append(" 	left join ciudad cds on cds.ciudad_id = pds.ciudad_id");
		sb.append(" 	left join estado eds on eds.estado_id = cds.estado_id");
		sb.append(" 	left join empresa_imposto eis on eis.empresa_id = c.empresacorrida_id and eis.estado_id = eos.estado_id");
		sb.append(" 	left join fiscal_r4 r4 on r4.caja_id = c.caja_id");
		sb.append(" 	left join fiscal_r2 r2 on r2.numserie20 = imp.numserie20 and r2.datamov = to_char(c.feccreacion, 'YYYYMMDD')");
		sb.append(" 	where c.activo = 1 and po.activo = 1 and co.activo = 1 and eo.activo = 1 and ei.activo = 1");
		sb.append(" 	and coalesce(CASE WHEN s.aliasorigen_id IS NULL THEN ei.activo ELSE eis.activo END, 0) = 1");
		sb.append(" 	and ((c.indreimpresion = 0 and c.motivocancelacion_id is null and c.numfoliosistema is not null) or (c.indstatusboleto = 'E' and c.indreimpresion = 1))");
		sb.append(" 	and (c.preciopagado) > 0");
		sb.append(" 	and c.serieimpfiscal is not null and r4.caja_id is null");
		sb.append(" 	and c.feccreacion >= TO_DATE(?,'DD/MM/YYYY HH24:MI:SS') and c.feccreacion <= TO_DATE(?,'DD/MM/YYYY HH24:MI:SS')");
		sb.append(" 	and c.empresacorrida_id = ?");
		sb.append(" 	and ((CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) = ?)");
		sb.append(" ) group by ecf, datamov, municipio_origem, estado_origem, estado_destino, red_base_calc_icms, porc_red_municipal, porc_red_estadual, tributacao_importacao");

		Session session = null;

		try {
			session = getSessionFactory().openSession();

			session.doWork(new Work() {
				@Override
				public void execute(Connection connection) throws SQLException {
					PreparedStatement ps = connection.prepareStatement(sb.toString());
					ps.setString(1, DateUtil.getStringDate(inicio, DATE_FORMAT_FISCAL));
					ps.setString(2, DateUtil.getStringDate(fim, DATE_FORMAT_FISCAL));
					ps.setLong(3, Long.valueOf(empresaId));
					ps.setString(4, cveestado);
					ps.setString(5, DateUtil.getStringDate(inicio, DATE_FORMAT_DMY + " 00:00:00"));
					ps.setString(6, DateUtil.getStringDate(fim, DATE_FORMAT_DMY + " 23:59:59"));
					ps.setLong(7, Long.valueOf(empresaId));
					ps.setString(8, cveestado);

					ResultSet rs = ps.executeQuery();

					ExportacaoECFTipoPRC registro = null;

					Map<String, ExportacaoECFTipoPRC> group = new HashMap<String, ExportacaoECFTipoPRC>();

					while (rs.next()) {
						BigDecimal valorTotal = rs.getBigDecimal("valortotal");

						BigDecimal red_base_calc_icms = MoneyHelper.instanciar(rs.getBigDecimal("red_base_calc_icms"));
						// BigDecimal porc_red_municipal = MoneyHelper.instanciar(rs.getBigDecimal("porc_red_municipal"));
						// BigDecimal porc_red_estadual = MoneyHelper.instanciar(rs.getBigDecimal("porc_red_estadual"));
						BigDecimal tributacao_importacao = MoneyHelper.instanciar(rs.getBigDecimal("tributacao_importacao"));
						BigDecimal valorBaseCalculoICMS = BigDecimal.ZERO;

						if (tributacao_importacao != null) {
							tributacao_importacao = MoneyHelper.dividir(tributacao_importacao, BigDecimal.valueOf(100d));
						}

						if (red_base_calc_icms != null) {
							BigDecimal aRed_base_calc_icms = MoneyHelper.dividir(red_base_calc_icms, BigDecimal.valueOf(100d));
							valorBaseCalculoICMS = MoneyHelper.subtrair(valorTotal, MoneyHelper.multiplicar(valorTotal, aRed_base_calc_icms));
						} else {
							// if (tributacao_importacao != null) {
							// if (rs.getString("estado_origem").equals(rs.getString("estado_destino"))) {
							// if (porc_red_municipal != null) {
							// BigDecimal aPorc_red_municipal = MoneyHelper.dividir(porc_red_municipal, BigDecimal.valueOf(100d));
							// BigDecimal porc = MoneyHelper.subtrair(tributacao_importacao, MoneyHelper.multiplicar(tributacao_importacao, aPorc_red_municipal));
							//
							// BigDecimal aPorc = MoneyHelper.dividir(porc, BigDecimal.valueOf(100d));
							// valorBaseCalculoICMS = MoneyHelper.multiplicar(valorTotal, aPorc);
							// }
							// } else {
							// if (porc_red_estadual != null) {
							// BigDecimal aPorc_red_estadual = MoneyHelper.dividir(porc_red_estadual, BigDecimal.valueOf(100d));
							// BigDecimal porc = MoneyHelper.subtrair(tributacao_importacao, MoneyHelper.multiplicar(tributacao_importacao, aPorc_red_estadual));
							//
							// BigDecimal aPorc = MoneyHelper.dividir(porc, BigDecimal.valueOf(100d));
							// valorBaseCalculoICMS = MoneyHelper.multiplicar(valorTotal, aPorc);
							// }
							// }
							// }

							// Email 17/02/2017
							valorBaseCalculoICMS = valorTotal;
						}

						BigDecimal valorICMS = BigDecimal.ZERO;

						if (tributacao_importacao != null) {
							valorICMS = MoneyHelper.multiplicar(valorBaseCalculoICMS, tributacao_importacao);
						}

						String key = rs.getString("ecf") + "|" + rs.getString("datamov") + "|" + rs.getString("estado_origem") + "|" + rs.getString("municipio_origem");

						if (group.containsKey(key)) {
							registro = group.get(key);

							registro.setValorTotal(MoneyHelper.somar(registro.getValorTotal(), valorTotal));
							registro.setValorBaseCalculoICMS(MoneyHelper.somar(registro.getValorBaseCalculoICMS(), valorBaseCalculoICMS));
							registro.setValorICMS(MoneyHelper.somar(registro.getValorICMS(), valorICMS));

						} else {
							registro = new ExportacaoECFTipoPRC();
							registro.setEcf(rs.getString("ecf"));
							registro.setDataEmissao(rs.getString("datamov"));
							registro.setUfOrigem(rs.getString("estado_origem"));
							registro.setMunicipioOrigem(Integer.valueOf(rs.getString("municipio_origem")));
							registro.setValorTotal(valorTotal);
							registro.setValorBaseCalculoICMS(valorBaseCalculoICMS);
							registro.setValorICMS(valorICMS);
							registro.setTributacao(tributacao_importacao);
						}

						group.put(key, registro);
					}

					for (Map.Entry<String, ExportacaoECFTipoPRC> entry : group.entrySet()) {
						retorno.add(entry.getValue());
					}

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

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

		} finally {
			session.close();

		}

		return retorno;
	}

	@Override
	public ExportacaoBPR buscarRegistroBPR(Connection connection, Date inicio, Date fim, Integer empresaId, String cveestado) {
		ExportacaoBPR exportacaoRMD = new ExportacaoBPR();

		boolean isDif = validaConstanteCustom(empresaId.toString(), "IMPORT_FISCAL_DIF");

		StringBuilder sb = new StringBuilder();
		sb.append(" select distinct");
		sb.append("   eof.estado_id as codigoParticipantePar,");
		sb.append("   eif.codestabelecimento as codigoEstabelecimentoPar,");
		sb.append("   e.nombempresa as nomeParticipante,");
		sb.append("   eof.cveestado as ufParticipante,");
		sb.append("   ie.cnpj as cnpjParticipante,");
		sb.append("   ie.numinscricaoestadual as ieParticipante,");
		sb.append("   ie.logradouro as logradouro,");
		sb.append("   ie.numero as numero,");
		sb.append("   ie.complemento as complemento,");
		sb.append("   ie.bairro as bairro,");
		sb.append("   ie.cep as cep,");
		sb.append("   cast(f.fechorfolio as date) as dataEmissaoRMD,");
		sb.append("   (case when s.aliasorigen_id is null then eo.estado_id else cos.estado_id end) as codigoParticipante,");
		sb.append("   ei.codestabelecimento as codigoEstabelecimento,");
		sb.append("   coalesce(a.acfiscal, 'X') as numeroAIDF,");
		sb.append("   coalesce(a.serie, 'X') as serieAIDF,");
		sb.append("   a.subserie as subSerieAIDF,");
		sb.append("   f.folio as numeroFormularioBilheteAIDF,");
		sb.append("   (case when coalesce(f.indcancelacion, 0) = 1 then 'S' else 'N' end) as documentoCancelado,");
		sb.append("   (case when (case when s.aliasorigen_id is null then eo.estado_id else cos.estado_id end) = ");
		sb.append("           (case when s.aliasorigen_id is null then cd.estado_id else cds.estado_id end) ");
		sb.append("            then ei.codigocontabilmunicipal else ei.codigocontabilestadual end) as codigoContabil,");
		sb.append("   b.feccreacion as dataEmissao,");
		sb.append("   b.numfoliopreimpreso as numeroFormulario,");
		sb.append("   r.acfiscal as numeroAIDFRMD,");
		sb.append("   r.serie as serieAIDFRMD,");
		sb.append("   r.subserie as subSerieAIDFRMD,");
		sb.append("   b.foliormd as numeroRMD,");
		sb.append("   (case when ( coalesce(case when s.aliasorigen_id is null then po.regionmetropolitana_id else pos.regionmetropolitana_id end, -1) = ");
		sb.append(" 	       coalesce(case when s.aliasorigen_id is null then pd.regionmetropolitana_id else pds.regionmetropolitana_id end, -2) ) then 1 else 0 end) as boletoIsento,");
		sb.append("   (case when b.motivocancelacion_id is not null then 1 else 0 end) as boletoCancelado,");
		sb.append("   b.preciopagado as valorPago,");
		sb.append("   (case when s.aliasorigen_id is null then ed.cveestado else eds.cveestado end) as ufDestino,");
		sb.append("   (case when s.aliasorigen_id is null then cd.codibge else cds.codibge end) as municipioDestino,");
		sb.append("   (case when s.aliasorigen_id is null then eo.cveestado else eos.cveestado end) as ufOrigem,");
		sb.append("   (case when s.aliasorigen_id is null then co.codibge else cos.codibge end) as municipioOrigem,");
		sb.append("   cie.codibge as municipioOrigemPadrao,");
		sb.append("   (case when ((case when s.aliasorigen_id is null then eo.cveestado else eos.cveestado end) =");
		sb.append("          (case when s.aliasorigen_id is null then ed.cveestado else eds.cveestado end)) then 5357 else 6357 end) as cfop,");
		sb.append("   ei.porcredbaseicms as reducaoBaseCalcICMS,");
		sb.append("   ei.porcredmunicipal as porcReducaoMunicipal,");
		sb.append("   ei.porcredestadual as porcReducaoEstadual,");
		sb.append("   ei.tributacaoimportacao as tributacaoImportacao,");
		sb.append("   b.rmd_id,");
		sb.append("   coalesce(b.aidf_id, -1),");
		sb.append("   b.caja_id");
		sb.append(" from folio_consumo_rmd f");
		sb.append(" join estado eof on eof.estado_id = f.estado_id");
		sb.append(" join aidf r on r.aidf_id = f.rmd_id");
		sb.append(" join empresa e on e.empresa_id = f.empresa_id");
		sb.append(" join ciudad c on c.ciudad_id = e.ciudad_id");
		sb.append(" left join empresa_imposto eif on eif.activo = 1 and eif.empresa_id = f.empresa_id and eif.estado_id = eof.estado_id");
		sb.append(" left join inscricao_estadual ie on ie.empresa_id = f.empresa_id and ie.estado_id = eof.estado_id and ie.activo = 1");
		sb.append(" left join ciudad cie on cie.ciudad_id = ie.ciudad_id");
		sb.append(" left join caja b on b.activo = 1 and b.rmd_id = f.rmd_id and b.empresacorrida_id = f.empresa_id and b.foliormd = f.folio and to_char(b.fechorventa, 'ddmmyyyy') = to_char(f.fechorfolio, 'ddmmyyyy')");
		sb.append(" left join parada po on po.parada_id = b.origen_id and po.activo = 1 ");
		sb.append(" left join ciudad co on co.ciudad_id = po.ciudad_id and co.activo = 1 ");
		sb.append(" left join estado eo on eo.estado_id = co.estado_id and eo.activo = 1 ");
		sb.append(" left join parada pd on pd.parada_id = b.destino_id");
		sb.append(" left join ciudad cd on cd.ciudad_id = pd.ciudad_id");
		sb.append(" left join estado ed on ed.estado_id = cd.estado_id");
		sb.append(" left join empresa_imposto ei on ei.activo = 1 and ei.empresa_id = b.empresacorrida_id and ei.estado_id = eof.estado_id");
		sb.append(" left join alias_servico s on s.origen_id = b.origen_id and s.destino_id = b.destino_id");
		sb.append("             and (s.corrida_id = b.corrida_id or s.corrida_id is null) and s.ruta_id = b.ruta_id and s.activo = 1 ");
		sb.append(" left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" left join estado eos on eos.estado_id = cos.estado_id");
		sb.append(" left join parada pds on pds.parada_id = s.aliasdestino_id");
		sb.append(" left join ciudad cds on cds.ciudad_id = pds.ciudad_id");
		sb.append(" left join estado eds on eds.estado_id = cds.estado_id");
		sb.append(" left join aidf a on a.aidf_id = b.aidf_id");
		sb.append(" where f.activo = 1 ");
		sb.append("   and f.indinactivo = 0 ");
		sb.append("   and f.indbpr = 1 ");
		sb.append("   and f.fechorfolio >= to_date(?,'DD/MM/YYYY HH24:MI:SS') and f.fechorfolio <= to_date(?,'DD/MM/YYYY HH24:MI:SS') ");
		sb.append("   and f.empresa_id = ? ");
		sb.append("   and eof.cveestado like ? ");
		sb.append("   and (f.indcancelacion = 1 or ( ");

		if (isDif) {
			sb.append("   ((b.tipoventa_id not in (5,12,18,81,82,49,41) and b.indstatusboleto = 'V' and b.indreimpresion  = 0) ");
			sb.append("   or (b.tipoventa_id in (5,12,18,81,82,49,41) ");
			sb.append("   and b.indstatusboleto = 'E' and b.numfoliosistema = b.numfoliopreimpreso)) ");
			sb.append("   and a.aidf_id is not null and b.indcancelacion = 0 ");
			sb.append("   and (b.motivocancelacion_id  is null or b.motivocancelacion_id <> 35) )) ");
		} else {
			sb.append("   ((b.tipoventa_id = 3 and b.indstatusboleto = 'V' and b.indreimpresion = 0) ");
			sb.append("            or (b.tipoventa_id in (12,18) and b.indstatusboleto = 'E' and b.numfoliosistema = b.numfoliopreimpreso)) ");
			sb.append("   and (b.motivocancelacion_id is null or b.motivocancelacion_id <> 35) )) ");
		}

		sb.append(" order by dataEmissaoRMD ");

		try {
			PreparedStatement ps = connection.prepareStatement(sb.toString());
			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);

			ResultSet rs = ps.executeQuery();

			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

			ExportacaoBPRBase registro = null;

			while (rs.next()) {
				String ufDestino = rs.getString("ufDestino");
				String ufOrigem = rs.getString("ufOrigem");
				Integer municipioOrigem = rs.getInt("municipioOrigem");
				Integer municipioDestino = rs.getInt("municipioDestino");
				Integer municipioOrigemPadrao = rs.getInt("municipioOrigemPadrao");
				Integer cfop = rs.getInt("cfop");

				if (ufOrigem != null && ufDestino != null) {
					if (!ufOrigem.equals(cveestado)) {
						if (ufDestino.equals(cveestado)) {
							ufOrigem = cveestado;
							municipioOrigem = municipioDestino;
						} else {
							ufOrigem = cveestado;
							municipioOrigem = municipioOrigemPadrao;
						}

						cfop = (ufOrigem.equals(ufDestino) ? 5357 : 6357);
					}
				}

				registro = new ExportacaoBPRBase();

				// PAR
				registro.setCodigoParticipantePar(rs.getInt("codigoParticipantePar"));
				registro.setCodigoEstabelecimentoPar(rs.getInt("codigoEstabelecimentoPar"));
				registro.setNomeParticipante(rs.getString("nomeParticipante"));
				registro.setUfParticipante(rs.getString("ufParticipante"));
				registro.setCpfParticipante(rs.getString("cnpjParticipante"));
				registro.setIeParticipante(rs.getString("ieParticipante"));
				registro.setLogradouro(rs.getString("logradouro"));
				registro.setNumero(rs.getString("numero"));
				registro.setComplemento(rs.getString("complemento"));
				registro.setBairro(rs.getString("bairro"));
				registro.setCep(rs.getString("cep") == null ? null : Integer.parseInt(rs.getString("cep").replace("-", "").replace(".", "")));

				// RMD
				registro.setDataEmissaoRMD(sdf.format(rs.getDate("dataEmissaoRMD")));
				registro.setCodigoParticipante(rs.getInt("codigoParticipante"));
				registro.setCodigoEstabelecimento(rs.getInt("codigoEstabelecimento"));
				registro.setNumeroAIDF(rs.getString("numeroAIDF"));
				registro.setSerieAIDF(rs.getString("serieAIDF"));
				registro.setSubSerieAIDF(rs.getString("subSerieAIDF"));
				registro.setNumeroFormularioBilheteAIDF(rs.getLong("numeroFormularioBilheteAIDF"));
				registro.setDocumentoCancelado(rs.getString("documentoCancelado").equals("S") ? Boolean.TRUE : Boolean.FALSE);
				registro.setCodigoContabil(rs.getString("codigoContabil"));

				// BPS
				registro.setDataEmissao(rs.getDate("dataEmissao") == null ? null : sdf.format(rs.getDate("dataEmissao")));
				registro.setNumeroFormulario(rs.getLong("numeroFormulario"));
				registro.setNumeroAIDFRMD(rs.getString("numeroAIDFRMD"));
				registro.setSerieAIDFRMD(rs.getString("serieAIDFRMD"));
				registro.setSubSerieAIDFRMD(rs.getString("subSerieAIDFRMD"));
				registro.setNumeroRMD(rs.getInt("numeroRMD"));
				registro.setBoletoIsento(rs.getInt("boletoIsento"));
				registro.setBoletoCancelado(rs.getInt("boletoCancelado"));
				registro.setValorPago(rs.getBigDecimal("valorPago"));

				// DBP
				registro.setUfDestino(ufDestino);
				registro.setUfOrigem(ufOrigem);
				registro.setMunicipioOrigem(municipioOrigem);
				registro.setCfop(cfop);
				registro.setReducaoBaseCalcICMS(rs.getBigDecimal("reducaoBaseCalcICMS"));
				registro.setPorcReducaoMunicipal(rs.getBigDecimal("porcReducaoMunicipal"));
				registro.setPorcReducaoEstadual(rs.getBigDecimal("porcReducaoEstadual"));
				registro.setTributacaoImportacao(rs.getBigDecimal("tributacaoImportacao"));

				exportacaoRMD.getListaRegistroBPR().add(registro);
			}

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

			exportacaoRMD.gerarListas();

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

		return exportacaoRMD;
	}

	@Override
	public List<ExportacaoRMDTipoPAR> buscarRegistroRMDTipoPAR(Connection connection, Date inicio, Date fim, Integer empresaId, String cveestado) {
		List<ExportacaoRMDTipoPAR> retorno = new ArrayList<ExportacaoRMDTipoPAR>();

		StringBuilder sb = new StringBuilder();
		sb.append(" select");
		sb.append("   c.estado_id as cod_participante,");
		sb.append("   ei.codestabelecimento as cod_estabelecimento,");
		sb.append("   e.nombempresa as nombempresa,");
		sb.append("   ess.cveestado as cveestado,");
		sb.append("   ie.cnpj as cnpj,");
		sb.append("   ie.numinscricaoestadual as numinscricaoestadual,");
		sb.append("   ie.logradouro as logradouro,");
		sb.append("   ie.numero as numero,");
		sb.append("   ie.complemento as complemento,");
		sb.append("   ie.bairro as bairro,");
		sb.append("   ie.cep as cep");
		sb.append(" from empresa e");
		sb.append(" join ciudad c on c.ciudad_id = e.ciudad_id");
		sb.append(" join estado es on es.estado_id = c.estado_id");
		sb.append(" left join estado ess on ess.cveestado = ?");
		sb.append(" left join inscricao_estadual ie on ie.empresa_id = e.empresa_id and ie.estado_id = ess.estado_id and ie.activo = 1");
		sb.append(" left join empresa_imposto ei on ei.activo = 1 and ei.empresa_id = e.empresa_id and ei.estado_id = ess.estado_id");
		sb.append(" where e.empresa_id = ?");

		try {
			PreparedStatement ps = connection.prepareStatement(sb.toString());
			ps.setString(1, cveestado);
			ps.setLong(2, Long.valueOf(empresaId));

			ResultSet rs = ps.executeQuery();

			ExportacaoRMDTipoPAR registro = null;

			while (rs.next()) {
				registro = new ExportacaoRMDTipoPAR();
				registro.setCodigoParticipante(rs.getInt("cod_participante"));
				registro.setCodigoEstabelecimento(rs.getInt("cod_estabelecimento"));
				registro.setNomeParticipante(rs.getString("nombempresa"));
				registro.setUfParticipante(rs.getString("cveestado"));
				registro.setCpfParticipante(rs.getString("cnpj"));
				registro.setIeParticipante(rs.getString("numinscricaoestadual"));
				registro.setLogradouro(rs.getString("logradouro"));
				registro.setNumero(rs.getString("numero"));
				registro.setComplemento(rs.getString("complemento"));
				registro.setBairro(rs.getString("bairro"));
				registro.setCep(rs.getString("cep") == null ? null : Integer.parseInt(rs.getString("cep").replace("-", "").replace(".", "")));

				retorno.add(registro);
			}

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

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

		return retorno;
	}

	@Override
	public List<ExportacaoRMDTipoRMD> buscarRegistroRMDTipoRMD(Connection connection, Date inicio, Date fim, Integer empresaId, String cveestado) {
		List<ExportacaoRMDTipoRMD> retorno = new ArrayList<ExportacaoRMDTipoRMD>();

		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

		StringBuilder sb = new StringBuilder();
		sb.append(" select");
		sb.append("   ei.codestabelecimento as cod_estabelecimento,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN eo.estado_id ELSE eos.estado_id END) as cod_participante,");
		sb.append("   a.acfiscal as num_aidf,");
		sb.append("   a.serie as serie,");
		sb.append("   a.subserie as subserie,");
		sb.append("   b.foliormd as num_bilhete,");
		sb.append("   b.foliormd as num_formulario,");
		sb.append("   trunc(b.feccreacion) as data_emissao,");
		sb.append("   'N' as doc_cancelado,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN (CASE WHEN co.estado_id = cd.estado_id THEN ei.codigocontabilmunicipal ELSE ei.codigocontabilestadual END) ELSE (CASE WHEN cos.estado_id = cds.estado_id THEN ei.codigocontabilmunicipal ELSE ei.codigocontabilestadual END) END) as cod_contabil");
		sb.append(" from boleto b");
		sb.append(" join empresa e on e.empresa_id = b.empresacorrida_id");
		sb.append(" join ciudad ce on ce.ciudad_id = e.ciudad_id");
		sb.append(" join parada po on po.parada_id = b.origen_id");
		sb.append(" join ciudad co on co.ciudad_id = po.ciudad_id");
		sb.append(" join estado eo on eo.estado_id = co.estado_id");
		sb.append(" left join alias_servico s on s.origen_id = b.origen_id and s.destino_id = b.destino_id and (s.corrida_id = b.corrida_id or s.corrida_id is null) and s.ruta_id = b.ruta_id and s.activo = 1 ");
		sb.append(" left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" left join estado eos on eos.estado_id = cos.estado_id");
		sb.append(" join parada pd on pd.parada_id = b.destino_id");
		sb.append(" join ciudad cd on cd.ciudad_id = po.ciudad_id");
		sb.append(" left join parada pds on pds.parada_id = s.aliasdestino_id");
		sb.append(" left join ciudad cds on cds.ciudad_id = pds.ciudad_id");
		sb.append(" join aidf a on a.aidf_id = b.rmd_id");
		sb.append(" join empresa_imposto ei on ei.activo = 1 and ei.empresa_id = b.empresacorrida_id and ei.estado_id = (CASE WHEN s.aliasorigen_id IS NULL THEN co.estado_id ELSE cos.estado_id END)");
		sb.append(" where");
		sb.append("   b.activo = 1");
		sb.append("   and b.tipoventa_id = 3");
		sb.append("   and (b.indstatusboleto like 'V')");
		sb.append("   and b.empresacorrida_id = ?");
		sb.append("   and (b.feccreacion >= to_date(?, 'dd/MM/YYYY hh24:mi:ss') and b.feccreacion <= to_date(?, 'dd/MM/YYYY hh24:mi:ss'))");
		sb.append("   and (CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) like ?");
		sb.append(" group by");
		sb.append("   ei.codestabelecimento,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN eo.estado_id ELSE eos.estado_id END),");
		sb.append("   a.acfiscal,");
		sb.append("   a.serie,");
		sb.append("   a.subserie,");
		sb.append("   b.foliormd,");
		sb.append("   trunc(b.feccreacion),");
		sb.append("   'N',");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN (CASE WHEN co.estado_id = cd.estado_id THEN ei.codigocontabilmunicipal ELSE ei.codigocontabilestadual END) ELSE (CASE WHEN cos.estado_id = cds.estado_id THEN ei.codigocontabilmunicipal ELSE ei.codigocontabilestadual END) END)");
		sb.append(" UNION");
		sb.append(" select distinct");
		sb.append("   ei.codestabelecimento as cod_estabelecimento,");
		sb.append("   eo.estado_id as cod_participante,");
		sb.append("   a.acfiscal as num_aidf,");
		sb.append("   a.serie as serie,");
		sb.append("   a.subserie as subserie,");
		sb.append("   f.folio as num_bilhete,");
		sb.append("   f.folio as num_formulario,");
		sb.append("   trunc(f.fechorfolio) as data_emissao,");
		sb.append("   'S' as doc_cancelado,");
		sb.append("   null as cod_contabil");
		sb.append(" from folio_consumo_rmd f");
		sb.append(" join estado eo on eo.estado_id = f.estado_id");
		sb.append(" join empresa_imposto ei on ei.activo = 1 and ei.empresa_id = f.empresa_id and ei.estado_id = eo.estado_id");
		sb.append(" join aidf a on a.aidf_id = f.rmd_id");
		sb.append(" where");
		sb.append("   f.empresa_id = ?");
		sb.append("   and (f.fechorfolio >= to_date(?, 'dd/MM/YYYY hh24:mi:ss') and f.fechorfolio <= to_date(?, 'dd/MM/YYYY hh24:mi:ss'))");
		sb.append("   and eo.cveestado like ?");
		sb.append("   and f.indcancelacion = 1 and f.indbpr = 1 and f.activo = 1");

		try {
			PreparedStatement ps = connection.prepareStatement(sb.toString());
			ps.setLong(1, Long.valueOf(empresaId));
			ps.setString(2, DateUtil.getStringDate(inicio, DATE_FORMAT_DMY) + " 00:00:00");
			ps.setString(3, DateUtil.getStringDate(fim, DATE_FORMAT_DMY) + " 23:59:59");
			ps.setString(4, cveestado);
			ps.setLong(5, Long.valueOf(empresaId));
			ps.setString(6, DateUtil.getStringDate(inicio, DATE_FORMAT_DMY) + " 00:00:00");
			ps.setString(7, DateUtil.getStringDate(fim, DATE_FORMAT_DMY) + " 23:59:59");
			ps.setString(8, cveestado);

			ResultSet rs = ps.executeQuery();

			ExportacaoRMDTipoRMD registro = null;

			while (rs.next()) {
				registro = new ExportacaoRMDTipoRMD();
				registro.setCodigoEstabelecimento(rs.getInt("cod_estabelecimento"));
				registro.setNumeroAIDF(rs.getString("num_aidf"));
				registro.setSerieAIDF(rs.getString("serie"));
				registro.setSubSerieAIDF(rs.getString("subserie"));
				registro.setNumeroBilheteAIDF(rs.getLong("num_bilhete"));
				registro.setNumeroFormularioAIDF(rs.getLong("num_formulario"));
				registro.setDataEmissao(sdf.format(rs.getDate("data_emissao")));
				registro.setCancelado(rs.getString("doc_cancelado").equals("S") ? Boolean.TRUE : Boolean.FALSE);
				registro.setCodigoParticipante(rs.getInt("cod_participante"));
				registro.setCodigoContabil(rs.getString("cod_contabil"));

				retorno.add(registro);
			}

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

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

		return retorno;
	}

	@Override
	@Deprecated
	public List<ExportacaoRMDTipoBPS> buscarRegistroRMDTipoBPS(Connection connection, Date inicio, Date fim, Integer empresaId, String cveestado) {
		List<ExportacaoRMDTipoBPS> retorno = new ArrayList<ExportacaoRMDTipoBPS>();

		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

		StringBuilder sb = new StringBuilder();
		sb.append(" select");
		sb.append("   ei.codestabelecimento as cod_estabelecimento,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN eo.estado_id ELSE eos.estado_id END) as cod_participante,");
		sb.append("   (CASE WHEN b.indstatusboleto like 'C' THEN 1 ELSE 0 END) as cancelado,");
		sb.append("   a.acfiscal as num_aidf,");
		sb.append("   a.serie as serie,");
		sb.append("   a.subserie as subserie,");
		sb.append("   b.feccreacion as data_emissao,");
		sb.append("   b.numfoliopreimpreso as num_formulario,");
		sb.append("   b.preciopagado as valor_total,");
		sb.append("   r.acfiscal as num_aidf_rmd,");
		sb.append("   r.serie as serie_rmd,");
		sb.append("   r.subserie as subserie_rmd,");
		sb.append("   b.foliormd as num_rmd");
		sb.append(" from boleto b");
		sb.append(" join empresa e on e.empresa_id = b.empresacorrida_id");
		sb.append(" join ciudad ce on ce.ciudad_id = e.ciudad_id");
		sb.append(" join parada po on po.parada_id = b.origen_id");
		sb.append(" join ciudad co on co.ciudad_id = po.ciudad_id");
		sb.append(" join estado eo on eo.estado_id = co.estado_id");
		sb.append(" left join alias_servico s on s.origen_id = b.origen_id and s.destino_id = b.destino_id and (s.corrida_id = b.corrida_id or s.corrida_id is null) and s.ruta_id = b.ruta_id");
		sb.append(" left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" left join estado eos on eos.estado_id = cos.estado_id");
		// sb.append(" join aidf a on a.serie = substr(b.numseriepreimpresa, 1, 3) and a.estado_id = (CASE WHEN s.aliasorigen_id IS NULL THEN eo.estado_id ELSE eos.estado_id END)");
		sb.append(" join aidf a on a.aidf_id = b.aidf_id");
		sb.append(" join aidf r on r.aidf_id = b.rmd_id");
		sb.append(" join empresa_imposto ei on ei.activo = 1 and ei.empresa_id = b.empresacorrida_id and ei.estado_id = (CASE WHEN s.aliasorigen_id IS NULL THEN eo.estado_id ELSE eos.estado_id END)");
		sb.append(" where");
		sb.append("   b.activo = 1");
		sb.append("   and b.tipoventa_id = 3");
		sb.append("   and (b.indstatusboleto like 'V' or b.indstatusboleto like 'C')");
		sb.append("   and b.empresacorrida_id = ?");
		sb.append("   and (b.fechorventa >= to_date(?, 'dd/MM/YYYY hh24:mi:ss') and b.fechorventa <= to_date(?, 'dd/MM/YYYY hh24:mi:ss'))");
		sb.append("   and (CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) like ?");
		sb.append(" order by b.feccreacion,a.acfiscal,b.numfoliopreimpreso");

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

			ResultSet rs = ps.executeQuery();

			Map<String, ExportacaoRMDTipoBPS> group = new HashMap<String, ExportacaoRMDTipoBPS>();

			ExportacaoRMDTipoBPS registro = null;

			Long numeroInicial = null;
			Long numeroFinal = null;

			while (rs.next()) {
				String key = sdf.format(rs.getDate("data_emissao")) + "|" + rs.getLong("num_aidf") + "|" + rs.getLong("num_formulario");

				if (group.containsKey(key)) {
					registro = group.get(key);

					numeroInicial = rs.getLong("num_formulario");
					numeroFinal = rs.getLong("num_formulario");

					if (numeroInicial.intValue() > registro.getNumeroInicial().intValue()) {
						numeroInicial = registro.getNumeroInicial();
					}

					if (numeroFinal.intValue() < registro.getNumeroFinal().intValue()) {
						numeroFinal = registro.getNumeroFinal();
					}

				} else {
					registro = new ExportacaoRMDTipoBPS();
					registro.setCodigoEstabelecimento(rs.getInt("cod_estabelecimento"));
					registro.setEspecie("BPR");
					registro.setNumeroAIDF(rs.getLong("num_aidf"));
					registro.setSerieAIDF(rs.getString("serie"));
					registro.setSubSerieAIDF(rs.getString("subserie"));
					registro.setNumeroAIDFRMD(rs.getLong("num_aidf_rmd"));
					registro.setSerieAIDFRMD(rs.getString("serie_rmd"));
					registro.setSubSerieAIDFRMD(rs.getString("subserie_rmd"));
					registro.setNumeroRMD(rs.getInt("num_rmd"));

					registro.setDataEmissao(sdf.format(rs.getDate("data_emissao")));

					registro.setQuantidadeTotal(0);
					registro.setQuantidadeCancelados(0);
					registro.setValorTotal(BigDecimal.ZERO);
					registro.setResumoMovimentoDiario(null);

					numeroInicial = rs.getLong("num_formulario");
					numeroFinal = rs.getLong("num_formulario");
				}

				registro.setNumeroInicial(numeroInicial);
				registro.setNumeroFinal(numeroFinal);

				registro.setQuantidadeTotal(registro.getQuantidadeTotal() + 1);
				registro.setQuantidadeCancelados(registro.getQuantidadeCancelados() + rs.getInt("cancelado"));

				if (rs.getInt("cancelado") == 0) {
					registro.setValorTotal(registro.getValorTotal().add(rs.getBigDecimal("valor_total")));
				}

				group.put(key, registro);
			}

			for (Map.Entry<String, ExportacaoRMDTipoBPS> entry : group.entrySet()) {
				registro = entry.getValue();

				if (registro.getQuantidadeTotal().intValue() == registro.getQuantidadeCancelados().intValue()) {
					registro.setValorTotal(null);
				} else {
					registro.setResumoMovimentoDiario(Boolean.TRUE);
				}

				retorno.add(registro);
			}

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

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

		return retorno;
	}

	@Override
	@Deprecated
	public List<ExportacaoRMDTipoDBP> buscarRegistroRMDTipoDBP(Connection connection, Date inicio, Date fim, Integer empresaId, String cveestado) {
		List<ExportacaoRMDTipoDBP> retorno = new ArrayList<ExportacaoRMDTipoDBP>();

		StringBuilder sb = new StringBuilder();
		sb.append(" select");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) as estado_origem,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN ed.cveestado ELSE eds.cveestado END) as estado_destino,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN co.codibge ELSE cos.codibge END) as municipio_origem,");
		sb.append("   (CASE WHEN ((CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) = (CASE WHEN s.aliasorigen_id IS NULL THEN ed.cveestado ELSE eds.cveestado END)) THEN 5357 ELSE 6357 END) as cod_operacao,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredbaseicms ELSE eis.porcredbaseicms END) as red_base_calc_icms,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredmunicipal ELSE eis.porcredmunicipal END) as porc_red_municipal,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredestadual ELSE eis.porcredestadual END) as porc_red_estadual,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN ei.tributacaoimportacao ELSE eis.tributacaoimportacao END) as tributacao_importacao,");
		sb.append("   (CASE WHEN (nvl((CASE WHEN s.aliasorigen_id IS NULL THEN po.regionmetropolitana_id ELSE pos.regionmetropolitana_id END),-1) = nvl((CASE WHEN s.aliasorigen_id IS NULL THEN pd.regionmetropolitana_id ELSE pds.regionmetropolitana_id END),-2)) THEN 1 ELSE 0 END) as isenta,");
		sb.append("   (nvl(b.preciopagado,0) - nvl(b.importetaxaembarque,0) - nvl(b.importepedagio,0) - nvl(b.importeseguro,0) - nvl(b.importeoutros,0)) as valor_tarifa,");
		sb.append("   b.preciopagado as valor_total,");
		sb.append("   (CASE WHEN nvl(case when s.aliasorigen_id is null then po.regionmetropolitana_id else pos.regionmetropolitana_id end, -1) = nvl(case when s.aliasorigen_id is null then pd.regionmetropolitana_id else pds.regionmetropolitana_id end, -2) THEN 1 ELSE 0 END) as reg_metropolitana");
		sb.append(" from boleto b");
		sb.append(" join empresa e on e.empresa_id = b.empresacorrida_id");
		sb.append(" join parada po on po.parada_id = b.origen_id");
		sb.append(" join ciudad co on co.ciudad_id = po.ciudad_id");
		sb.append(" join estado eo on eo.estado_id = co.estado_id");
		sb.append(" join parada pd on pd.parada_id = b.destino_id");
		sb.append(" join ciudad cd on cd.ciudad_id = pd.ciudad_id");
		sb.append(" join estado ed on ed.estado_id = cd.estado_id");
		sb.append(" left join alias_servico s on s.origen_id = b.origen_id and s.destino_id = b.destino_id and (s.corrida_id = b.corrida_id or s.corrida_id is null) and s.ruta_id = b.ruta_id");
		sb.append(" left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" left join estado eos on eos.estado_id = cos.estado_id");
		sb.append(" left join parada pds on pds.parada_id = s.aliasdestino_id");
		sb.append(" left join ciudad cds on cds.ciudad_id = pds.ciudad_id");
		sb.append(" left join estado eds on eds.estado_id = cds.estado_id");
		sb.append(" join empresa_imposto ei on ei.activo = 1 and ei.empresa_id = b.empresacorrida_id and ei.estado_id = eo.estado_id");
		sb.append(" left join empresa_imposto eis on eis.activo = 1 and eis.empresa_id = b.empresacorrida_id and eis.estado_id = eos.estado_id");
		sb.append(" where");
		sb.append("   b.activo = 1");
		sb.append("   and b.tipoventa_id = 3");
		sb.append("   and (b.indstatusboleto like 'V' or b.indstatusboleto like 'C')");
		sb.append("   and b.empresacorrida_id = ?");
		sb.append("   and (b.fechorventa >= to_date(?, 'dd/MM/YYYY hh24:mi:ss') and b.fechorventa <= to_date(?, 'dd/MM/YYYY hh24:mi:ss'))");
		sb.append("   and (CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) like ?");

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

			ResultSet rs = ps.executeQuery();

			ExportacaoRMDTipoDBP registro = null;

			Map<String, ExportacaoRMDTipoDBP> group = new HashMap<String, ExportacaoRMDTipoDBP>();

			while (rs.next()) {
				String key = rs.getString("estado_destino") + "|" + rs.getInt("cod_operacao") + "|" + rs.getString("estado_origem") + "|" + rs.getInt("municipio_origem");

				if (group.containsKey(key)) {
					registro = group.get(key);
				} else {
					registro = new ExportacaoRMDTipoDBP();
					registro.setUfDestino(rs.getString("estado_destino"));
					registro.setCfop(rs.getInt("cod_operacao")); // IM=5357; serviço IE= 6357
					registro.setUfOrigem(rs.getString("estado_origem"));
					registro.setMunicipioOrigem(rs.getInt("municipio_origem"));

					registro.setCodigoSituacaoTribColunaB(null);

					// 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
					if (rs.getInt("isenta") == 1) {
						registro.setCodigoSituacaoTribColunaB(40);
					}

					// 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
					if (registro.getCodigoSituacaoTribColunaB() == null) {
						registro.setCodigoSituacaoTribColunaB(rs.getInt("red_base_calc_icms") == 0 ? 0 : 20);
					}

					registro.setValorBaseCalculoICMS(BigDecimal.ZERO);
					registro.setValorTotal(BigDecimal.ZERO);
					registro.setValorICMS(BigDecimal.ZERO);
					registro.setValorICMSIsento(BigDecimal.ZERO);
					registro.setValorICMSOutros(BigDecimal.ZERO);
				}

				BigDecimal valorTotal = rs.getBigDecimal("valor_total");
				BigDecimal red_base_calc_icms = rs.getBigDecimal("red_base_calc_icms");
				BigDecimal porc_red_municipal = rs.getBigDecimal("porc_red_municipal");
				BigDecimal porc_red_estadual = rs.getBigDecimal("porc_red_estadual");
				BigDecimal tributacao_importacao = rs.getBigDecimal("tributacao_importacao");
				BigDecimal valorBaseCalculoICMS = BigDecimal.ZERO;

				BigDecimal valorIsenta = BigDecimal.ZERO;
				BigDecimal valorIsentaOutros = BigDecimal.ZERO;

				if (rs.getInt("reg_metropolitana") == 1) {
					valorIsenta = valorTotal;
					valorTotal = BigDecimal.ZERO;
				} else {
					if (red_base_calc_icms != null) {
						valorBaseCalculoICMS = valorTotal.subtract(valorTotal.multiply(red_base_calc_icms.divide(BigDecimal.valueOf(100d))));
					} else {
						// if (tributacao_importacao != null) {
						// if (rs.getString("estado_origem").equals(rs.getString("estado_destino"))) {
						// if (porc_red_municipal != null) {
						// BigDecimal porc = tributacao_importacao.subtract(tributacao_importacao.multiply(porc_red_municipal.divide(BigDecimal.valueOf(100d))));
						// valorBaseCalculoICMS = valorTotal.multiply(porc.divide(BigDecimal.valueOf(100d)));
						// }
						// } else {
						// if (porc_red_estadual != null) {
						// BigDecimal porc = tributacao_importacao.subtract(tributacao_importacao.multiply(porc_red_estadual.divide(BigDecimal.valueOf(100d))));
						// valorBaseCalculoICMS = valorTotal.multiply(porc.divide(BigDecimal.valueOf(100d)));
						// }
						// }
						// }

						valorBaseCalculoICMS = valorTotal;
					}
				}

				registro.setAliquotaICMS(tributacao_importacao);

				if (tributacao_importacao == null) {
					tributacao_importacao = BigDecimal.ZERO;
				} else {
					if (red_base_calc_icms != null) {
						BigDecimal porc_red = BigDecimal.ZERO;

						if (rs.getString("estado_origem").equals(rs.getString("estado_destino"))) {
							if (porc_red_municipal != null) {
								porc_red = porc_red_municipal;
							}
						} else {
							if (porc_red_estadual != null) {
								porc_red = porc_red_estadual;
							}
						}

						BigDecimal porc = tributacao_importacao.subtract(porc_red.divide(BigDecimal.valueOf(100d)));
						valorIsentaOutros = valorTotal.multiply(porc);
					}

					tributacao_importacao = MoneyHelper.dividir(tributacao_importacao, BigDecimal.valueOf(100d));
				}

				BigDecimal valorICMS = MoneyHelper.multiplicar(valorBaseCalculoICMS, tributacao_importacao);

				registro.setValorBaseCalculoICMS(registro.getValorBaseCalculoICMS().add(valorBaseCalculoICMS));
				registro.setValorTotal(registro.getValorTotal().add(valorTotal));
				registro.setValorICMS(registro.getValorICMS().add(valorICMS));
				registro.setValorICMSIsento(registro.getValorICMSIsento().add(valorIsenta));
				registro.setValorICMSOutros(registro.getValorICMSOutros().add(valorIsentaOutros));

				group.put(key, registro);
			}

			for (Map.Entry<String, ExportacaoRMDTipoDBP> entry : group.entrySet()) {
				retorno.add(entry.getValue());
			}

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

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

		return retorno;
	}

	@Override
	@Deprecated
	public List<ExportacaoRMDTipoSeqBPS> buscarRegistroRMDSeqTipoBPS(Connection connection, Date inicio, Date fim, Integer empresaId, String cveestado) {
		List<ExportacaoRMDTipoSeqBPS> listaBPS = new ArrayList<ExportacaoRMDTipoSeqBPS>();

		StringBuilder sb = new StringBuilder();
		sb.append(" select");
		sb.append("   ei.codestabelecimento as cod_estabelecimento,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN eo.estado_id ELSE eos.estado_id END) as cod_participante,");
		sb.append("   (CASE WHEN b.indstatusboleto like 'C' THEN 1 ELSE 0 END) as cancelado,");
		sb.append("   b.aidf_id,");
		sb.append("   a.acfiscal as num_aidf,");
		sb.append("   a.serie as serie,");
		sb.append("   a.subserie as subserie,");
		sb.append("   b.feccreacion as data_emissao,");
		sb.append("   b.numfoliopreimpreso as num_formulario,");
		sb.append("   b.preciopagado as valor_total,");
		sb.append("   b.rmd_id,");
		sb.append("   r.acfiscal as num_aidf_rmd,");
		sb.append("   r.serie as serie_rmd,");
		sb.append("   r.subserie as subserie_rmd,");
		sb.append("   b.foliormd as num_rmd,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) as estado_origem,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN ed.cveestado ELSE eds.cveestado END) as estado_destino,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN co.codibge ELSE cos.codibge END) as municipio_origem,");
		sb.append("   (CASE WHEN ((CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) = (CASE WHEN s.aliasorigen_id IS NULL THEN ed.cveestado ELSE eds.cveestado END)) THEN 5357 ELSE 6357 END) as cod_operacao,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredbaseicms ELSE eis.porcredbaseicms END) as red_base_calc_icms,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredmunicipal ELSE eis.porcredmunicipal END) as porc_red_municipal,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN ei.porcredestadual ELSE eis.porcredestadual END) as porc_red_estadual,");
		sb.append("   (CASE WHEN s.aliasorigen_id IS NULL THEN ei.tributacaoimportacao ELSE eis.tributacaoimportacao END) as tributacao_importacao,");
		sb.append("   (CASE WHEN (nvl((CASE WHEN s.aliasorigen_id IS NULL THEN po.regionmetropolitana_id ELSE pos.regionmetropolitana_id END),-1) = nvl((CASE WHEN s.aliasorigen_id IS NULL THEN pd.regionmetropolitana_id ELSE pds.regionmetropolitana_id END),-2)) THEN 1 ELSE 0 END) as isenta,");
		sb.append("   (nvl(b.preciopagado,0) - nvl(b.importetaxaembarque,0) - nvl(b.importepedagio,0) - nvl(b.importeseguro,0) - nvl(b.importeoutros,0)) as valor_tarifa,");
		sb.append("   b.preciopagado as valor_total,");
		sb.append("   (CASE WHEN nvl(case when s.aliasorigen_id is null then po.regionmetropolitana_id else pos.regionmetropolitana_id end, -1) = nvl(case when s.aliasorigen_id is null then pd.regionmetropolitana_id else pds.regionmetropolitana_id end, -2) THEN 1 ELSE 0 END) as reg_metropolitana");
		sb.append(" from boleto b");
		sb.append(" join empresa e on e.empresa_id = b.empresacorrida_id");
		sb.append(" join parada po on po.parada_id = b.origen_id");
		sb.append(" join ciudad co on co.ciudad_id = po.ciudad_id");
		sb.append(" join estado eo on eo.estado_id = co.estado_id");
		sb.append(" join parada pd on pd.parada_id = b.destino_id");
		sb.append(" join ciudad cd on cd.ciudad_id = pd.ciudad_id");
		sb.append(" join estado ed on ed.estado_id = cd.estado_id");
		sb.append(" left join alias_servico s on s.origen_id = b.origen_id and s.destino_id = b.destino_id and (s.corrida_id = b.corrida_id or s.corrida_id is null) and s.ruta_id = b.ruta_id");
		sb.append(" left join parada pos on pos.parada_id = s.aliasorigen_id");
		sb.append(" left join ciudad cos on cos.ciudad_id = pos.ciudad_id");
		sb.append(" left join estado eos on eos.estado_id = cos.estado_id");
		sb.append(" left join parada pds on pds.parada_id = s.aliasdestino_id");
		sb.append(" left join ciudad cds on cds.ciudad_id = pds.ciudad_id");
		sb.append(" left join estado eds on eds.estado_id = cds.estado_id");
		sb.append(" join empresa_imposto ei on ei.activo = 1 and ei.empresa_id = b.empresacorrida_id and ei.estado_id = eo.estado_id");
		sb.append(" left join empresa_imposto eis on eis.activo = 1 and eis.empresa_id = b.empresacorrida_id and eis.estado_id = eos.estado_id");
		sb.append(" join aidf a on a.aidf_id = b.aidf_id");
		sb.append(" join aidf r on r.aidf_id = b.rmd_id");
		sb.append(" where");
		sb.append("   b.activo = 1");
		sb.append("   and b.tipoventa_id = 3");
		sb.append("   and (b.indstatusboleto like 'V' or b.indstatusboleto like 'C')");
		sb.append("   and b.empresacorrida_id = ?");
		sb.append("   and (b.fechorventa >= to_date(?, 'dd/MM/YYYY hh24:mi:ss') and b.fechorventa <= to_date(?, 'dd/MM/YYYY hh24:mi:ss'))");
		sb.append("   and (CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) like ?");
		sb.append(" order by b.fechorventa, b.numfoliopreimpreso, (CASE WHEN ((CASE WHEN s.aliasorigen_id IS NULL THEN eo.cveestado ELSE eos.cveestado END) = (CASE WHEN s.aliasorigen_id IS NULL THEN ed.cveestado ELSE eds.cveestado END)) THEN 5357 ELSE 6357 END), (CASE WHEN s.aliasorigen_id IS NULL THEN ed.cveestado ELSE eds.cveestado END)");

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

			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

			ResultSet rs = ps.executeQuery();

			ExportacaoRMDTipoSeqBPS registroBPS = null;
			ExportacaoRMDTipoSeqDBP registroDBP = null;

			Long numeroInicial = 0l;
			Long numeroFinal = 0l;

			String dataEmissaoControle = "";
			Integer cfopControle = 0;

			Integer quantidadeTotal = 0;
			Integer quantidadeCancelado = 0;

			BigDecimal totalizador = BigDecimal.ZERO;

			while (rs.next()) {
				Integer codigoEstabelecimento = rs.getInt("cod_estabelecimento");
				String numeroAIDF = rs.getString("num_aidf");
				String serieAIDF = rs.getString("serie");
				String subSerieAIDF = rs.getString("subserie");
				String numeroAIDFRMD = rs.getString("num_aidf_rmd");
				String serieAIDFRMD = rs.getString("serie_rmd");
				String subSerieAIDFRMD = rs.getString("subserie_rmd");
				Integer numeroRMD = rs.getInt("num_rmd");
				String dataEmissao = sdf.format(rs.getDate("data_emissao"));
				Long numeroFormulario = rs.getLong("num_formulario");
				String ufDestino = rs.getString("estado_destino");
				Integer cfop = rs.getInt("cod_operacao"); // IM=5357; serviço IE= 6357
				String ufOrigem = rs.getString("estado_origem");
				Integer municipioOrigem = rs.getInt("municipio_origem");
				Boolean isenta = (rs.getInt("isenta") == 1);
				Boolean cancelado = (rs.getInt("cancelado") == 1);
				BigDecimal valorTotal = rs.getBigDecimal("valor_total");
				BigDecimal red_base_calc_icms = rs.getBigDecimal("red_base_calc_icms");
				BigDecimal porc_red_municipal = rs.getBigDecimal("porc_red_municipal");
				BigDecimal porc_red_estadual = rs.getBigDecimal("porc_red_estadual");
				BigDecimal tributacao_importacao = rs.getBigDecimal("tributacao_importacao");

				// BPR
				if ((numeroFinal + 1) != numeroFormulario || !dataEmissaoControle.equals(dataEmissao) || !cfopControle.equals(cfop)) {
					numeroInicial = numeroFormulario;
					dataEmissaoControle = dataEmissao;
					cfopControle = cfop;

					registroBPS = new ExportacaoRMDTipoSeqBPS();
					registroBPS.setEspecie("BPR");
					registroBPS.setNumeroInicial(numeroInicial);
					registroBPS.setCodigoEstabelecimento(codigoEstabelecimento);
					registroBPS.setNumeroAIDF(numeroAIDF);
					registroBPS.setSerieAIDF(serieAIDF);
					registroBPS.setSubSerieAIDF(subSerieAIDF);
					registroBPS.setNumeroAIDFRMD(numeroAIDFRMD);
					registroBPS.setSerieAIDFRMD(serieAIDFRMD);
					registroBPS.setSubSerieAIDFRMD(subSerieAIDFRMD);
					registroBPS.setNumeroRMD(numeroRMD);
					registroBPS.setDataEmissao(dataEmissao);
					registroBPS.setInfoPadraoBilhetePassagem(CODIGO_INDICADOR_CONTR_PREVIDENCIARIA);

					listaBPS.add(registroBPS);

					quantidadeTotal = 0;
					quantidadeCancelado = 0;

					totalizador = BigDecimal.ZERO;
				}

				quantidadeTotal++;

				if (cancelado) {
					quantidadeCancelado++;
				} else {
					totalizador = MoneyHelper.somar(totalizador, valorTotal);
				}

				numeroFinal = numeroFormulario;

				registroBPS.setNumeroFinal(numeroFinal);

				registroBPS.setQuantidadeTotal(quantidadeTotal);
				registroBPS.setQuantidadeCancelados(quantidadeCancelado);
				registroBPS.setValorTotal(totalizador);

				// DBP
				registroDBP = new ExportacaoRMDTipoSeqDBP(ufDestino);

				Integer indice = registroBPS.getListaDBP().indexOf(registroDBP);

				if (indice == -1) {
					registroBPS.getListaDBP().add(registroDBP);

					registroDBP.setCfop(cfop); // IM=5357; serviço IE= 6357
					registroDBP.setUfOrigem(ufOrigem);
					registroDBP.setMunicipioOrigem(municipioOrigem);

					registroDBP.setCodigoSituacaoTribColunaB(null);

					// 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
					if (isenta) {
						registroDBP.setCodigoSituacaoTribColunaB(40);
					}

					// 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
					if (registroDBP.getCodigoSituacaoTribColunaB() == null) {
						registroDBP.setCodigoSituacaoTribColunaB(red_base_calc_icms == null || red_base_calc_icms.compareTo(BigDecimal.ZERO) == 0 ? 0 : 20);
					}

					registroDBP.setValorBaseCalculoICMS(BigDecimal.ZERO);
					registroDBP.setValorTotal(BigDecimal.ZERO);
					registroDBP.setValorICMS(BigDecimal.ZERO);
					registroDBP.setValorICMSIsento(BigDecimal.ZERO);
					registroDBP.setValorICMSOutros(BigDecimal.ZERO);
				} else {
					registroDBP = registroBPS.getListaDBP().get(indice);
				}

				BigDecimal valorBaseCalculoICMS = BigDecimal.ZERO;

				BigDecimal valorIsenta = BigDecimal.ZERO;
				BigDecimal valorIsentaOutros = BigDecimal.ZERO;

				if (rs.getInt("reg_metropolitana") == 1) {
					valorIsenta = valorTotal;
					valorTotal = BigDecimal.ZERO;
				} else {
					if (red_base_calc_icms != null) {
						valorBaseCalculoICMS = valorTotal.subtract(valorTotal.multiply(red_base_calc_icms.divide(BigDecimal.valueOf(100d))));
					} else {
						valorBaseCalculoICMS = valorTotal;
					}
				}

				registroDBP.setAliquotaICMS(tributacao_importacao);

				if (tributacao_importacao == null) {
					tributacao_importacao = BigDecimal.ZERO;
				} else {
					if (red_base_calc_icms != null) {
						BigDecimal porc_red = BigDecimal.ZERO;

						if (rs.getString("estado_origem").equals(rs.getString("estado_destino"))) {
							if (porc_red_municipal != null) {
								porc_red = porc_red_municipal;
							}
						} else {
							if (porc_red_estadual != null) {
								porc_red = porc_red_estadual;
							}
						}

						BigDecimal porc = tributacao_importacao.subtract(porc_red.divide(BigDecimal.valueOf(100d)));
						valorIsentaOutros = valorTotal.multiply(porc);
					}

					tributacao_importacao = MoneyHelper.dividir(tributacao_importacao, BigDecimal.valueOf(100d));
				}

				BigDecimal valorICMS = MoneyHelper.multiplicar(valorBaseCalculoICMS, tributacao_importacao);

				registroDBP.setValorBaseCalculoICMS(registroDBP.getValorBaseCalculoICMS().add(valorBaseCalculoICMS));
				registroDBP.setValorTotal(registroDBP.getValorTotal().add(valorTotal));
				registroDBP.setValorICMS(registroDBP.getValorICMS().add(valorICMS));
				registroDBP.setValorICMSIsento(registroDBP.getValorICMSIsento().add(valorIsenta));
				registroDBP.setValorICMSOutros(registroDBP.getValorICMSOutros().add(valorIsentaOutros));
			}

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

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

		return listaBPS;
	}

	@Override
	public void cancelarRMDBoleto(Connection connection, Date inicio, Date fim, Integer empresaId, Estado estado, Aidf aidf,
			String folioInicial, String folioFinal, boolean isCancela, boolean isInativa, boolean isECF, boolean isBPR) {

		List<String> boletos = new ArrayList<String>();
		String boletoAgr = null;
		int cont = 0;

		List<String> foliosRmd = new ArrayList<String>();

		if (isCancela) {
			cancelaFolioConsumoRmd(connection, empresaId, estado.getEstadoId(), aidf.getAidfId(), folioInicial, folioFinal, inicio, fim);
		} else {
			inativarFolioConsumoRmd(connection, empresaId, estado.getEstadoId(), aidf.getAidfId(), folioInicial, folioFinal, inicio, fim);
		}

		for (DetalhadoRMD brp : buscarRegistroImpressaoBPR(connection, inicio, fim, empresaId, estado.getCveestado(), aidf.getAidfId(),
				folioInicial, folioFinal, isBPR, isECF, true)) {

			if (!foliosRmd.contains(brp.getFoliormd()))
				foliosRmd.add(brp.getFoliormd());

			if (cont == 999) {
				boletos.add(boletoAgr);
				boletoAgr = null;
				cont = 0;
			}

			if (boletoAgr == null)
				boletoAgr = brp.getCajaId().toString();
			else
				boletoAgr = boletoAgr + " ," + brp.getCajaId();

			cont++;
		}
		boletos.add(boletoAgr);

		if (isInativa) {
			for (String folio : foliosRmd) {
				insereConsulmoFolioRMD(connection, inicio, empresaId, estado.getEstadoId(), aidf, folio,
						isCancela, isInativa, false, isECF, isBPR, null, null, null, null, null, null);
			}
		}

		marcarRMDCaja(connection, boletos, null, null);
	}

	private void cancelaFolioConsumoRmd(Connection connection, Integer empresaId, Integer estadoId,
			Long rmdId, String folioInicial, String folioFinal, Date inicio, Date fim) {

		PreparedStatement pstmt = null;
		try {
			StringBuilder sb = new StringBuilder();
			sb.append(" update folio_consumo_rmd ");
			sb.append(" set activo = 1, fecmodif = sysdate, indcancelacion = 1 ");
			sb.append(" where activo = 1 ");
			sb.append(" and indimpresso = 1 ");
			sb.append(" and rmd_id = ? ");
			sb.append(" and empresa_id = ? ");
			sb.append(" and estado_id = ? ");
			sb.append(" and folio between ? and ?  ");
			sb.append(" and fechorfolio between to_date(?,'dd/MM/yyyy HH24:MI:SS') and to_date(?,'dd/MM/yyyy HH24:MI:SS') ");

			pstmt = connection.prepareStatement(sb.toString());
			pstmt.setInt(1, rmdId.intValue());
			pstmt.setInt(2, empresaId);
			pstmt.setInt(3, estadoId);
			pstmt.setString(4, folioInicial);
			pstmt.setString(5, folioFinal);
			pstmt.setString(6, DateUtil.getStringDate(inicio, DATE_FORMAT_DMY) + " 00:00:00");
			pstmt.setString(7, DateUtil.getStringDate(fim, DATE_FORMAT_DMY) + " 23:59:59");

			pstmt.executeUpdate();

		} catch (Exception e) {
			log.error("", e);
		} finally {
			try {
				if (pstmt != null && !pstmt.isClosed()) {
					pstmt.close();
				}
			} catch (Exception e) {
				log.error("", e);
			}
		}
	}

	private void inativarFolioConsumoRmd(Connection connection, Integer empresaId, Integer estadoId,
			Long rmdId, String folioInicial, String folioFinal, Date inicio, Date fim) {

		PreparedStatement pstmt = null;
		try {
			StringBuilder sb = new StringBuilder();
			sb.append(" update folio_consumo_rmd ");
			sb.append(" set activo = 0, fecmodif = sysdate ");
			sb.append(" where activo = 1 ");
			sb.append(" and indimpresso = 1 ");
			sb.append(" and rmd_id = ? ");
			sb.append(" and empresa_id = ? ");
			sb.append(" and estado_id = ? ");
			sb.append(" and folio between ? and ?  ");
			sb.append(" and fechorfolio between to_date(?,'dd/MM/yyyy HH24:MI:SS') and to_date(?,'dd/MM/yyyy HH24:MI:SS') ");

			pstmt = connection.prepareStatement(sb.toString());
			pstmt.setInt(1, rmdId.intValue());
			pstmt.setInt(2, empresaId);
			pstmt.setInt(3, estadoId);
			pstmt.setString(4, folioInicial);
			pstmt.setString(5, folioFinal);
			pstmt.setString(6, DateUtil.getStringDate(inicio, DATE_FORMAT_DMY) + " 00:00:00");
			pstmt.setString(7, DateUtil.getStringDate(fim, DATE_FORMAT_DMY) + " 23:59:59");

			pstmt.executeUpdate();

		} catch (Exception e) {
			log.error("", e);
		} finally {
			try {
				if (pstmt != null && !pstmt.isClosed()) {
					pstmt.close();
				}
			} catch (Exception e) {
				log.error("", e);
			}
		}
	}

	private void insereConsulmoFolioRMD(Connection connection, Date dataBilhete, Integer empresaId, Integer estadoId, Aidf aidf,
			String folio, boolean isCancela, boolean isInativa, boolean isImpresso, boolean isECF, boolean isBPR,
			BigDecimal valorContabil, BigDecimal baseCalculo, BigDecimal aliquota, BigDecimal isentos,
			BigDecimal outros, BigDecimal icms) {

		PreparedStatement pstmt = null;
		try {
			StringBuilder sb = new StringBuilder();
			sb.append("  insert into FOLIO_CONSUMO_RMD (FOLIOCONSUMORMD_ID, RMD_ID, FOLIO,  ");
			sb.append("  EMPRESA_ID, ESTADO_ID, INDCANCELACION, INDINACTIVO, INDIMPRESSO, FECHORFOLIO, ");
			sb.append("  VALORCONTABIL, BASECALCULO, ALIQUOTA, ISENTOS, OUTROS, ICMS, ");
			sb.append("  INDECF, INDBPR, ACTIVO, FECMODIF, USUARIO_ID) ");
			sb.append("  values (").append("FOLIO_CONSUMO_RMD_SEQ.NEXTVAL").append(",");
			sb.append(aidf.getAidfId()).append(",").append(folio).append(",");
			sb.append(empresaId).append(",").append(estadoId).append(",");

			if (isCancela)
				sb.append(1).append(",").append(0).append(",").append(0).append(",");
			else if (isInativa)
				sb.append(0).append(",").append(1).append(",").append(0).append(",");
			else if (isImpresso)
				sb.append(0).append(",").append(0).append(",").append(1).append(",");

			sb.append("?").append(",");
			sb.append("?").append(",");
			sb.append("?").append(",");
			sb.append("?").append(",");
			sb.append("?").append(",");
			sb.append("?").append(",");
			sb.append("?").append(",");

			if (isECF)
				sb.append(1).append(",").append(0).append(",");
			else
				sb.append(0).append(",").append(1).append(",");

			sb.append(1).append(",").append("SYSDATE").append(",").append(UsuarioLogado.getUsuarioLogado().getUsuarioId()).append(")");

			pstmt = connection.prepareStatement(sb.toString());
			pstmt.setTimestamp(1, new java.sql.Timestamp(DateUtil.inicioFecha(dataBilhete).getTime()));
			pstmt.setBigDecimal(2, MoneyHelper.arredondar(valorContabil));
			pstmt.setBigDecimal(3, MoneyHelper.arredondar(baseCalculo));
			pstmt.setBigDecimal(4, MoneyHelper.arredondar(aliquota));
			pstmt.setBigDecimal(5, MoneyHelper.arredondar(isentos));
			pstmt.setBigDecimal(6, MoneyHelper.arredondar(outros));
			pstmt.setBigDecimal(7, MoneyHelper.arredondar(icms));
			pstmt.executeUpdate();

		} catch (Exception e) {
			log.error("", e);
		} finally {
			try {
				if (pstmt != null && !pstmt.isClosed()) {
					pstmt.close();
				}
			} catch (Exception e) {
				log.error("", e);
			}
		}
	}

	@Override
	public void gravarRMDBoleto(Connection connection, List<ImpressaoRMD> rmds, Aidf aidf, String folio, Integer empresaId, Integer estadoId, boolean isECF, boolean isBPR) {

		int cont = 0;
		Integer rmdIterate = Integer.parseInt(folio);
		rmdIterate = rmdIterate - 1;

		String boletoAgr = null;
		List<String> boletos = new ArrayList<String>();
		int contBolto = 0;
		Date dataBilhete = null;

		BigDecimal valorContabil = BigDecimal.ZERO;
		BigDecimal baseCalculo = BigDecimal.ZERO;
		BigDecimal aliquota = BigDecimal.ZERO;
		BigDecimal isentos = BigDecimal.ZERO;
		BigDecimal outros = BigDecimal.ZERO;
		BigDecimal icms = BigDecimal.ZERO;

		for (ImpressaoRMD imp : rmds) {

			if (dataBilhete == null)
				dataBilhete = imp.getData();

			// Numero maximo de itens na folha do RMD
			if (cont == 23 || (!dataBilhete.equals(imp.getData()))) {

				// add primeiro ou ultimo na lista de insercao dos boletos
				boletos.add(boletoAgr);

				// incrementa na contagem dos folios na impressao do RMD
				rmdIterate++;
				cont = 0;

				insereConsulmoFolioRMD(connection, dataBilhete, empresaId, estadoId, aidf, rmdIterate.toString(), false, false, true, isECF, isBPR,
						valorContabil, baseCalculo, aliquota, isentos, outros, icms);

				marcarRMDCaja(connection, boletos, aidf.getAidfId(), rmdIterate);

				// limpa a lista de inseções do boleto
				boletos = new ArrayList<String>();
				boletoAgr = null;
				contBolto = 0;
				dataBilhete = imp.getData();

				valorContabil = BigDecimal.ZERO;
				baseCalculo = BigDecimal.ZERO;
				aliquota = BigDecimal.ZERO;
				isentos = BigDecimal.ZERO;
				outros = BigDecimal.ZERO;
				icms = BigDecimal.ZERO;
			}

			for (DetalhadoRMD det : imp.getDetalhada()) {

				if (contBolto == 999) {
					boletos.add(boletoAgr);
					boletoAgr = null;
					contBolto = 0;
				}

				if (boletoAgr == null)
					boletoAgr = det.getCajaId().toString();
				else
					boletoAgr = boletoAgr + " ," + det.getCajaId();

				contBolto++;
			}
			cont++;

			valorContabil = valorContabil.add(imp.getValorContabil());
			baseCalculo = baseCalculo.add(imp.getBaseCalculo());
			aliquota = imp.getAliquota();
			isentos = isentos.add(imp.getIsentos());
			outros = outros.add(imp.getOutros());
			icms = icms.add(imp.getIcms());
		}

		if (boletos.isEmpty()) {
			rmdIterate++;
			boletos.add(boletoAgr);
			insereConsulmoFolioRMD(connection, dataBilhete, empresaId, estadoId, aidf, rmdIterate.toString(), false, false, true, isECF, isBPR,
					valorContabil, baseCalculo, aliquota, isentos, outros, icms);
			marcarRMDCaja(connection, boletos, aidf.getAidfId(), rmdIterate);
		}
	}

	private void marcarRMDCaja(Connection connection, List<String> boletos, Long rmdId, Integer folio) {

		for (String bs : boletos) {
			StringBuilder sb = new StringBuilder();
			PreparedStatement pstmt = null;
			try {
				sb.append("  update caja set rmd_id = ").append(rmdId).append(", ");
				sb.append("  foliormd = ").append(folio).append(" ");
				sb.append("  where caja_id in ( ").append(bs).append(" ) ");
				pstmt = connection.prepareStatement(sb.toString());
				pstmt.executeUpdate();
			} catch (Exception e) {
				log.error("", e);
			} finally {
				try {
					if (pstmt != null && !pstmt.isClosed()) {
						pstmt.close();
					}
				} catch (Exception e) {
					log.error("", e);
				}
			}
		}
	}

	@Override
	public List<ImpressaoRMD> getRegistroImpressaoRMDTipoBPR(Connection connection, Date inicio, Date fim, Integer empresaId,
			String cveestado, String rmd, String folio) {

		List<ImpressaoRMD> list = new ArrayList<ImpressaoRMD>();

		// IMPRESSAO RMD MANUAL
		Date data = null;
		String numPuntoVenta = null;

		ImpressaoRMD impRmd = null;

		for (DetalhadoRMD brp : buscarRegistroImpressaoBPR(connection, inicio, fim, empresaId, cveestado, null, null, null, true, false, false)) {

			if (numPuntoVenta == null) {
				impRmd = new ImpressaoRMD(brp.getEmpresa(), brp.getEnderecoEmpresa(), brp.getCnpjEmpresa(), brp.getIeEmpresa(),
						brp.getFechorVenta(), rmd, "SERVIÇO DE TRANSPORTE", "DVB", null, null, folio);
				numPuntoVenta = brp.getNumPuntoVenta();
				data = brp.getFechorVenta();

			} else if (!(numPuntoVenta.equals(brp.getNumPuntoVenta()) && data.equals(brp.getFechorVenta()))) {
				impRmd.setNumero(brp.getCcf());
				list.add(impRmd);

				impRmd = new ImpressaoRMD(brp.getEmpresa(), brp.getEnderecoEmpresa(), brp.getCnpjEmpresa(), brp.getIeEmpresa(),
						brp.getFechorVenta(), rmd, "SERVIÇO DE TRANSPORTE", "DVB", null, null, folio);
				numPuntoVenta = brp.getNumPuntoVenta();
				data = brp.getFechorVenta();
			}

			impRmd.getDetalhada().add(brp);
		}

		if (impRmd != null)
			list.add(impRmd);

		agruparImpressaoRMD(list);

		return list;
	}

	@Override
	public List<ImpressaoRMD> getRegistroImpressaoRMDTipoECF(Connection connection, Date inicio, Date fim, Integer empresaId,
			String cveestado, String rmd, String folio) {

		List<ImpressaoRMD> list = new ArrayList<ImpressaoRMD>();

		// IMPRESSAO RMD ECF
		String serie = null;
		String datamov = null;
		ImpressaoRMD impRmd = null;

		for (DetalhadoRMD brp : buscarRegistroImpressaoBPR(connection, inicio, fim, empresaId, cveestado, null, null, null, false, true, false)) {
			Date dataMovimento = null;
			try {
				dataMovimento = DateUtil.getDateFromString(brp.getDatamov(), DATE_FORMAT_FISCAL);
			} catch (Exception e) {
			}

			if (serie == null) {

				impRmd = new ImpressaoRMD(brp.getEmpresa(), brp.getEnderecoEmpresa(), brp.getCnpjEmpresa(), brp.getIeEmpresa(),
						dataMovimento, rmd, "SERVIÇO DE TRANSPORTE", "ECF", brp.getEcf(), brp.getEstadoImpressora(), folio);
				serie = brp.getEcf();
				datamov = brp.getDatamov();

			} else if (!(serie.equals(brp.getEcf()) && datamov.equals(brp.getDatamov()))) {
				impRmd.setNumero(brp.getCcf());
				list.add(impRmd);

				impRmd = new ImpressaoRMD(brp.getEmpresa(), brp.getEnderecoEmpresa(), brp.getCnpjEmpresa(), brp.getIeEmpresa(),
						dataMovimento, rmd, "SERVIÇO DE TRANSPORTE", "ECF", brp.getEcf(), brp.getEstadoImpressora(), folio);
				serie = brp.getEcf();
				datamov = brp.getDatamov();
			}

			impRmd.getDetalhada().add(brp);
		}

		if (impRmd != null)
			list.add(impRmd);

		agruparImpressaoRMD(list);

		return list;
	}

	private void agruparImpressaoRMD(List<ImpressaoRMD> list) {

		for (ImpressaoRMD impRmd : list) {

			BigDecimal valorContabil = BigDecimal.ZERO;
			BigDecimal baseCalculo = BigDecimal.ZERO;
			BigDecimal aliquota = BigDecimal.ZERO;
			BigDecimal icms = BigDecimal.ZERO;
			BigDecimal isentos = BigDecimal.ZERO;
			BigDecimal outros = BigDecimal.ZERO;
			String cooFim = null;

			for (DetalhadoRMD brp : impRmd.getDetalhada()) {

				if (brp.getIsenta()) {
					isentos = isentos == null ? BigDecimal.ZERO : isentos.add(somarTotalBilhete(brp));
				} else {
					valorContabil = valorContabil == null ? BigDecimal.ZERO : valorContabil.add(brp.getTarifa() == null ? BigDecimal.ZERO : brp.getTarifa());

					BigDecimal redBaseCalcIcms = brp.getRedBaseCalcIcms() == null ? BigDecimal.ZERO : brp.getRedBaseCalcIcms().divide(UtiliteriasFiscal.CEM);
					BigDecimal redutor = valorContabil.multiply(redBaseCalcIcms);
					baseCalculo = valorContabil.subtract(redutor);

					aliquota = brp.getTributacaoImportacao() == null ? brp.getIcmsInterestadual() : brp.getTributacaoImportacao();
					icms = baseCalculo.multiply(aliquota.divide(BigDecimal.TEN.multiply(BigDecimal.TEN)));
					outros = valorContabil.subtract(baseCalculo);
				}
				cooFim = brp.getCoo() == null ? brp.getNumPuntoVenta() : brp.getCoo();
			}
			impRmd.setNumero(cooFim);
			impRmd.setValorContabil(valorContabil);
			impRmd.setBaseCalculo(baseCalculo);
			impRmd.setAliquota(aliquota);
			impRmd.setIcms(icms);
			impRmd.setIsentos(isentos);
			impRmd.setOutros(outros);
		}
	}

	private BigDecimal somarTotalBilhete(DetalhadoRMD brp) {

		BigDecimal total = BigDecimal.ZERO;
		total = total.add(brp.getTarifa() == null ? BigDecimal.ZERO : brp.getTarifa());
		total = total.add(brp.getTaxaEmbarque() == null ? BigDecimal.ZERO : brp.getTaxaEmbarque());
		total = total.add(brp.getPedagio() == null ? BigDecimal.ZERO : brp.getPedagio());
		total = total.add(brp.getSeguro() == null ? BigDecimal.ZERO : brp.getSeguro());
		total = total.add(brp.getOutros() == null ? BigDecimal.ZERO : brp.getOutros());
		return total;
	}

	public List<DetalhadoRMD> buscarRegistroImpressaoBPR(Connection connection, Date inicio, Date fim, Integer empresaId,
			String cveestado, Long rmdId, String folioInicial, String folioFinal, boolean isManual, boolean isECF, boolean isCancelamento) {

		List<DetalhadoRMD> list = new ArrayList<DetalhadoRMD>();
		try {
			boolean isDif = validaConstanteCustom(empresaId.toString(), "IMPORT_FISCAL_DIF");

			String sql = null;
			if (isECF && !isCancelamento) {
				sql = getSqlImpressaoRMDTipoECF();
			} else if (isManual && !isCancelamento) {
				sql = getSqlImpressaoRMDTipoBPR(isDif);
			} else if (isCancelamento) {
				sql = getSqlImpressaoRMDCancelados();
			}

			NamedParameterStatement ps = new NamedParameterStatement(connection, sql);
			ps.getStatement().setFetchSize(100);
			ps.setInt("EMPRESA_ID", 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()));

			if (isCancelamento) {
				ps.setLong("RMD_ID", rmdId);
				ps.setLong("FOLIO_INICIAL", NumberUtils.createLong(folioInicial));
				ps.setLong("FOLIO_FINAL", NumberUtils.createLong(folioFinal));
			} else {
				ps.setString("CVEESTADO", cveestado);
			}

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

				DetalhadoRMD brp = new DetalhadoRMD();
				brp.setCajaId(rs.getLong("cajaId"));
				if (!isCancelamento) {
					brp.setNumoperacion(rs.getString("numoperacion"));
					brp.setSerie(rs.getString("serieCompl"));
					brp.setFolio(rs.getInt("folio"));
					brp.setEstadoId(rs.getInt("estadoId"));
					brp.setFechorVenta(rs.getDate("fechorVenta"));
					brp.setEmpresa(rs.getString("empresa"));
					brp.setEnderecoEmpresa(rs.getString("enderecoEmpresa"));
					brp.setCnpjEmpresa(rs.getString("cnpjEmpresa"));
					brp.setIeEmpresa(rs.getString("ieEmpresa"));
					brp.setIcmsInterestadual(rs.getBigDecimal("icmsInterestadual"));
					brp.setIcmsIntermunicipal(rs.getBigDecimal("icmsIntermunicipal"));
					brp.setEstadoOrigem(rs.getString("estadoOrigem"));
					brp.setEstadoDestino(rs.getString("estadoDestino"));
					brp.setMunicipioOrigem(rs.getString("municipioOrigem"));
					brp.setInterEstadual(rs.getBoolean("isInterEstadual"));
					brp.setIcmsInterestadual(rs.getBigDecimal("icmsInterestadual"));
					brp.setRedBaseCalcIcms(rs.getBigDecimal("redBaseCalcIcms"));
					brp.setPorcRedMunicipal(rs.getBigDecimal("porcRedMunicipal"));
					brp.setPorcRedEstadual(rs.getBigDecimal("porcRedEstadual"));
					brp.setTributacaoImportacao(rs.getBigDecimal("tributacaoImportacao"));
					brp.setIsenta(rs.getBoolean("isenta"));
					brp.setTarifa(rs.getBigDecimal("tarifa"));
					brp.setTaxaEmbarque(rs.getBigDecimal("taxaEmbarque"));
					brp.setPedagio(rs.getBigDecimal("pedagio"));
					brp.setSeguro(rs.getBigDecimal("seguro"));
					brp.setOutros(rs.getBigDecimal("outros"));
					brp.setNombPuntoVenta(rs.getString("nombPuntoVenta"));
					brp.setNumPuntoVenta(rs.getString("numPuntoVenta"));

					if (isECF && !isCancelamento) {
						brp.setEcf(rs.getString("ecf"));
						brp.setDatamov(rs.getString("datamov"));
						brp.setCoo(rs.getString("cooredz"));
						brp.setCcf(rs.getString("ccf"));
						brp.setTotalFiscal(rs.getString("totalFiscal"));
						brp.setEstadoImpressora(rs.getString("estadoImpressora"));
					}
				} else {
					brp.setRmdId(rs.getInt("rmd_id"));
					brp.setFoliormd(rs.getString("foliormd"));
				}

				list.add(brp);
			}

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

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

		return list;
	}

	public boolean validaConstanteCustom(String valor, String nomeConstante) {
		ConstanteService constanteService = (ConstanteService) AppContext.getApplicationContext().getBean("constanteService");
		Constante contante = constanteService.buscarPorNomeConstante(nomeConstante);
		String value = contante == null ? null : contante.getValorconstante();

		if (StringUtils.isBlank(value))
			return false;

		List<String> valuesList = Arrays.asList(value.split(",", -1));
		return valuesList.contains(valor);
	}

	private String getSqlImpressaoRMDTipoBPR(boolean isDif) {

		StringBuilder sql = new StringBuilder();
		sql.append("select distinct ");
		sql.append("  b.caja_id as cajaId, ");
		sql.append("  b.numoperacion as numoperacion, ");
		sql.append("  b.numseriepreimpresa as serieCompl, ");
		sql.append("  b.numfoliopreimpreso as folio, ");
		sql.append("  a.acfiscal as numAidf, ");
		sql.append("  a.serie as serieAidf, ");
		sql.append("  a.subserie as subSerieAidf, ");
		sql.append("  trunc(b.feccreacion) as fechorVenta, ");
		sql.append("  e.nombempresa as empresa, ");
		sql.append("  coalesce(ie.cnpj, e.cnpj) as cnpjEmpresa, ");
		sql.append("  case when ie.logradouro is null ");
		sql.append("           then (e.logradouro || ', ' || e.numero || ' - ' || e.bairro || ', ' || ce.nombciudad ");
		sql.append("           || ' - ' || ee.cveestado || ', ' || e.cep ) ");
		sql.append("           else (ie.logradouro || ', ' || ie.numero || ' - ' || ie.bairro || ', ' || cie.nombciudad ");
		sql.append("           || ' - ' || eie.cveestado || ', ' || ie.cep ) end as enderecoEmpresa, ");
		sql.append("  pv.nombpuntoventa as nombPuntoVenta, ");
		sql.append("  pv.numpuntoventa as numPuntoVenta, ");
		sql.append("  ie.numinscricaoestadual as ieEmpresa, ");
		sql.append("  coalesce(ae.estado_id, e_ag.estado_id, eos.estado_id, eo.estado_id) as estadoId, ");
		sql.append("  coalesce(ei.icms, eos.icms) as icmsInterestadual, ");
		sql.append("  ei.icmsim as icmsIntermunicipal, ");
		sql.append("  coalesce(ae.cveestado, e_ag.cveestado, eos.cveestado, eo.cveestado) as estadoOrigem, ");
		sql.append("  ed.cveestado as estadoDestino, ");
		sql.append("  co.codibge as municipioOrigem, ");
		sql.append("  case when((coalesce(ae.cveestado, eos.cveestado)) = ed.cveestado) ");
		sql.append("             then 0 else 1 end as isInterEstadual, ");
		sql.append("  ei.porcredbaseicms as redBaseCalcIcms, ");
		sql.append("  ei.porcredmunicipal as porcRedMunicipal, ");
		sql.append("  ei.porcredestadual as porcRedEstadual, ");
		sql.append("  ei.tributacaoimportacao as tributacaoImportacao, ");
		sql.append("  case when (coalesce(pos.regionmetropolitana_id, po.regionmetropolitana_id, -1) = ");
		sql.append("               coalesce(pds.regionmetropolitana_id, pd.regionmetropolitana_id, -2)) ");
		sql.append("        then 1 else 0 end as isenta, ");
		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 caja b ");
		sql.append("  join marca m on b.marca_id = m.marca_id ");
		sql.append("  join empresa e on e.empresa_id = m.empresa_id ");
		sql.append("  left join aidf a on a.aidf_id = b.aidf_id ");
		sql.append("  left join punto_venta pv on pv.puntoventa_id = b.puntoventa_id ");
		sql.append("  left join parada de_ag on de_ag.parada_id = pv.parada_id ");
		sql.append("  left join ciudad cd_ag on cd_ag.ciudad_id = de_ag.ciudad_id ");
		sql.append("  left join estado e_ag on e_ag.estado_id = cd_ag.estado_id ");
		sql.append("  left join ciudad ce on ce.ciudad_id = e.ciudad_id ");
		sql.append("  left join estado ee on ee.estado_id = ce.estado_id ");
		sql.append("  join parada po on po.parada_id = b.origen_id ");
		sql.append("  join ciudad co on co.ciudad_id = po.ciudad_id ");
		sql.append("  join estado eo on eo.estado_id = co.estado_id ");
		sql.append("  join parada pd on pd.parada_id = b.destino_id ");
		sql.append("  join ciudad cd on cd.ciudad_id = pd.ciudad_id ");
		sql.append("  join estado ed on ed.estado_id = cd.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("  left join estado ae on ae.estado_id = a.estado_id ");
		sql.append("  left join inscricao_estadual ie on e.empresa_id = ie.empresa_id ");
		sql.append("                 and ie.estado_id = coalesce(ae.estado_id, e_ag.estado_id, eos.estado_id, eo.estado_id) and ie.activo = 1 ");
		sql.append("  left join ciudad cie on cie.ciudad_id = ie.ciudad_id ");
		sql.append("  left join estado eie on eie.estado_id = cie.estado_id ");
		sql.append("  left join empresa_imposto ei on ei.empresa_id = b.empresacorrida_id ");
		sql.append("                 and ei.estado_id = coalesce(ae.estado_id, e_ag.estado_id, eos.estado_id, eo.estado_id) and ei.activo = 1 ");
		sql.append("where ");

		if (isDif) {
			sql.append(" ((b.tipoventa_id not in (5,12,18,81,82,49,41) and b.indstatusboleto = 'V' and b.indreimpresion = 0) ");
			sql.append("        or (b.tipoventa_id in (5,12,18,81,82,49,41) and b.indstatusboleto = 'E' and b.numfoliosistema = b.numfoliopreimpreso)) ");
			sql.append("  and a.aidf_id is not null ");
		} else {
			sql.append(" ((b.tipoventa_id = 3 and b.indstatusboleto = 'V' and b.indreimpresion = 0) ");
			sql.append("        or (b.tipoventa_id in (12,18) and b.indstatusboleto = 'E' and b.numfoliosistema = b.numfoliopreimpreso)) ");
		}

		sql.append("   and (b.motivocancelacion_id is null or b.motivocancelacion_id <> 35) ");
		sql.append("   and b.indcancelacion = 0 ");
		sql.append("   and b.empresacorrida_id = :EMPRESA_ID ");
		sql.append("   and b.feccreacion between :DATE_INICIO and :DATE_FIM ");
		sql.append("   and coalesce(ae.cveestado, e_ag.cveestado, eos.cveestado, eo.cveestado) = :CVEESTADO ");
		sql.append("   and b.rmd_id is null ");
		sql.append("   and b.num_bpe is null ");
		sql.append("order by estadoId, fechorVenta, nombPuntoVenta, numPuntoVenta ");

		return sql.toString();
	}

	private String getSqlImpressaoRMDTipoECF() {

		StringBuilder sql = new StringBuilder();
		sql.append("select distinct ");
		sql.append("  c.caja_id as cajaId, ");
		sql.append("  c.numoperacion as numoperacion, ");
		sql.append("  c.numseriepreimpresa as serieCompl, ");
		sql.append("  c.numfoliopreimpreso as folio, ");
		sql.append("  '' as numAidf, ");
		sql.append("  '' as serieAidf, ");
		sql.append("  '' as subSerieAidf, ");
		sql.append("  trunc(c.feccreacion) as fechorVenta, ");
		sql.append("  ep.nombempresa as empresa,  ");
		sql.append("  ie.cnpj as cnpjEmpresa, ");
		sql.append("  (ie.logradouro || ', ' || ie.numero || ' - ' || ie.bairro || ', ' || cie.nombciudad ");
		sql.append("           || ' - ' || eie.cveestado || ', ' || ie.cep )  as enderecoEmpresa, ");
		sql.append("  '' as nombPuntoVenta, ");
		sql.append("  '' as numPuntoVenta, ");
		sql.append("  ie.numinscricaoestadual as ieEmpresa, ");
		sql.append("  (case when s.aliasorigen_id is null then eo.estado_id else eos.estado_id end) as estadoId,");
		sql.append("  (case when s.aliasorigen_id is null then ei.icms else eis.icms end) as icmsInterestadual,");
		sql.append("  (case when s.aliasorigen_id is null then ei.icmsim else eis.icmsim end) as icmsIntermunicipal,");
		sql.append("  (case when s.aliasorigen_id is null then eo.cveestado else eos.cveestado end) as estadoOrigem,");
		sql.append("  (case when s.aliasdestino_id is null then ed.cveestado else eds.cveestado end) as estadoDestino,");
		sql.append("  (case when s.aliasorigen_id is null then co.codibge else cos.codibge end) as municipioOrigem,");
		sql.append("  case when ( (case when s.aliasorigen_id is null then eo.cveestado else eos.cveestado end) = ");
		sql.append("         (case when s.aliasdestino_id is null then ed.cveestado else eds.cveestado end) )  then 0 else 1 end as isInterEstadual, ");
		sql.append("  (case when s.aliasorigen_id is null then ei.porcredbaseicms else eis.porcredbaseicms end) as redBaseCalcIcms,");
		sql.append("  (case when s.aliasorigen_id is null then ei.porcredmunicipal else eis.porcredmunicipal end) as porcRedMunicipal,");
		sql.append("  (case when s.aliasorigen_id is null then ei.porcredestadual else eis.porcredestadual end) as porcRedEstadual,");
		sql.append("  (case when s.aliasorigen_id is null then ei.tributacaoimportacao else eis.tributacaoimportacao end) as tributacaoImportacao,");
		sql.append("  (case when (coalesce(case when s.aliasorigen_id is null then po.regionmetropolitana_id ");
		sql.append("         else pos.regionmetropolitana_id end, -1) = coalesce(case when s.aliasorigen_id is null ");
		sql.append("         then pd.regionmetropolitana_id else pds.regionmetropolitana_id end, -2)) then 1 else 0 end) as isenta, ");
		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("  coalesce(r2.numserie20, imp.numserie20) as ecf, ");
		sql.append("  to_char(c.feccreacion, 'YYYYMMDD') as datamov, ");
		sql.append("  case when r2.numserie20 is null then '000001' else r2.coo end as coo, ");
		sql.append("  '000000' as ccf, ");
		sql.append("  null as totalFiscal, ");
		sql.append("  case when r2.numserie20 is null then '000001' else r2.coo end as cooredz, ");
		sql.append("  epv.cveestado as estadoImpressora ");
		sql.append(" from caja c ");
		sql.append(" join ruta r on r.ruta_id = c.ruta_id ");
		sql.append(" join parada po on po.parada_id = c.origen_id ");
		sql.append(" join ciudad co on co.ciudad_id = po.ciudad_id ");
		sql.append(" join estado eo on eo.estado_id = co.estado_id ");
		sql.append(" join parada pd on pd.parada_id = c.destino_id ");
		sql.append(" join ciudad cd on cd.ciudad_id = pd.ciudad_id ");
		sql.append(" join estado ed on ed.estado_id = cd.estado_id ");
		sql.append(" join empresa_imposto ei on ei.empresa_id = c.empresacorrida_id and ei.estado_id = eo.estado_id ");
		sql.append(" join fiscal_impressora imp on imp.numserie = c.serieimpfiscal ");
		sql.append(" left join estado e on e.estado_id = imp.estadolocal_id ");
		sql.append(" left join alias_servico s on s.origen_id = c.origen_id and s.destino_id = c.destino_id and (s.corrida_id = c.corrida_id or s.corrida_id is null) and s.ruta_id = c.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(" left join empresa_imposto eis on eis.empresa_id = c.empresacorrida_id and eis.estado_id = eos.estado_id ");
		sql.append(" left join fiscal_r4 r4 on r4.caja_id = c.caja_id ");
		sql.append(" left join fiscal_r2 r2 on r2.numserie20 = imp.numserie20 and r2.datamov = to_char(c.feccreacion, 'YYYYMMDD') ");
		sql.append(" join inscricao_estadual ie on c.empresacorrida_id = ie.empresa_id and ie.estado_id = coalesce(eos.estado_id, eo.estado_id) and ie.activo = 1 ");
		sql.append(" join ciudad cie on cie.ciudad_id = ie.ciudad_id ");
		sql.append(" join estado eie on eie.estado_id = cie.estado_id ");
		sql.append(" join marca ma on c.marca_id = ma.marca_id ");
		sql.append(" join empresa ep on ep.empresa_id = ma.empresa_id ");
		sql.append(" join punto_venta pv on pv.puntoventa_id = c.puntoventa_id ");
		sql.append(" left join parada ppv on ppv.parada_id = pv.parada_id ");
		sql.append(" left join ciudad cpv on cpv.ciudad_id = ppv.ciudad_id ");
		sql.append(" left join estado epv on epv.estado_id = cpv.estado_id ");
		sql.append(" where c.activo = 1 and po.activo = 1 and co.activo = 1 and eo.activo = 1 and ei.activo = 1 ");
		sql.append(" and coalesce(case when s.aliasorigen_id is null then ei.activo else eis.activo end, 0) = 1 ");
		sql.append(" and c.serieimpfiscal is not null ");
		sql.append(" and ((c.indreimpresion = 0 and c.motivocancelacion_id is null 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 ((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)) > 0 ");
		sql.append(" and c.feccreacion >= :DATE_INICIO and c.feccreacion <= :DATE_FIM ");
		sql.append(" and c.empresacorrida_id = :EMPRESA_ID ");
		sql.append(" and ((case when s.aliasorigen_id is null then eo.cveestado else eos.cveestado end) = :CVEESTADO ) ");
		sql.append(" and c.rmd_id is null ");
		sql.append(" and c.num_bpe is null ");
		sql.append(" order by estadoId, datamov, ecf, coo ");

		return sql.toString();
	}

	private String getSqlImpressaoRMDCancelados() {

		StringBuilder sql = new StringBuilder();
		sql.append("select distinct ");
		sql.append(" c.caja_id as cajaId, ");
		sql.append(" c.rmd_id as rmd_id,  ");
		sql.append(" c.foliormd as foliormd  ");
		sql.append(" from caja c ");
		sql.append(" where c.empresacorrida_id = :EMPRESA_ID ");
		sql.append(" and c.feccreacion >= :DATE_INICIO and c.feccreacion <= :DATE_FIM ");
		sql.append(" and c.rmd_id  = :RMD_ID ");
		sql.append(" and c.foliormd between :FOLIO_INICIAL and :FOLIO_FINAL ");

		return sql.toString();
	}

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

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

		List<DetalhadoFiscal> list = montaRelatorioRDI(connection, inicio, fim, empresaId, ufs);
		List<FiscalRdi> rdis = calcularRelatorioRDI(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(agr.getQuantBilhetes().add(detail.getTarifa() == null ? BigDecimal.ZERO : BigDecimal.ONE));
		agr.setTarifa(agr.getTarifa().add(detail.getTarifa() == null ? BigDecimal.ZERO : detail.getTarifa()));
		agr.setSeguro(agr.getSeguro().add(detail.getSeguro() == null ? BigDecimal.ZERO : detail.getSeguro()));
		agr.setTxEmbarque(agr.getTxEmbarque().add(detail.getTxEmbarque() == null ? BigDecimal.ZERO : detail.getTxEmbarque()));
		agr.setPedagio(agr.getPedagio().add(detail.getPedagio() == null ? BigDecimal.ZERO : detail.getPedagio()));
		agr.setPassagem(agr.getPassagem().add(detail.getPassagem() == null ? BigDecimal.ZERO : detail.getPassagem()));
		agr.setIsentos(agr.getIsentos().add(detail.getIsentos() == null ? BigDecimal.ZERO : detail.getIsentos()));
		agr.setOutros(agr.getOutros().add(detail.getOutros() == null ? BigDecimal.ZERO : detail.getOutros()));
		agr.setRbc(detail.getRbc() == null ? BigDecimal.ZERO : detail.getRbc());
		agr.setBaseCalculo(agr.getBaseCalculo().add(detail.getBaseCalculo() == null ? BigDecimal.ZERO : detail.getBaseCalculo()));
		agr.setAliquota(detail.getAliquota() == null ? BigDecimal.ZERO : detail.getAliquota());
		agr.setIcms(agr.getIcms().add(detail.getIcms() == null ? BigDecimal.ZERO : detail.getIcms()));
		agr.setCp(detail.getCp() == null ? BigDecimal.ZERO : detail.getCp());
		agr.setCredPres(agr.getCredPres().add(detail.getCredPres() == null ? BigDecimal.ZERO : detail.getCredPres()));
		agr.setIcmsRec(agr.getIcmsRec().add(detail.getIcmsRec() == null ? BigDecimal.ZERO : detail.getIcmsRec()));
		return agr;
	}

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

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

		for (DetalhadoFiscal det : list) {

			BigDecimal passagem = valorPassagem(det, isReceitaTerceiros);
			BigDecimal isentos = valorIsenta(det, isReceitaTerceiros);
			BigDecimal outros = BigDecimal.ZERO;
			BigDecimal rbc = BigDecimal.ZERO;
			BigDecimal baseCalculo = BigDecimal.ZERO;
			BigDecimal aliquota = BigDecimal.ZERO;
			BigDecimal icms = BigDecimal.ZERO;
			BigDecimal cp = BigDecimal.ZERO;
			BigDecimal credPres = BigDecimal.ZERO;
			BigDecimal icmsRec = BigDecimal.ZERO;

			if (det.isInterEstadual()) {
				aliquota = det.getTributacaoImportacao() != null ? det.getTributacaoImportacao() : det.getIcmsInterestadual();
			} else {
				aliquota = det.getTributacaoImportacao() != null ? det.getTributacaoImportacao() : det.getIcmsIntermunicipal();
			}

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

			rbc = det.getRedBaseCalcIcms() == null ? BigDecimal.ZERO : det.getRedBaseCalcIcms().divide(UtiliteriasFiscal.CEM);

			BigDecimal tarifa = valorBaseCalculo(det, isReceitaTerceiros);
			BigDecimal redutor = tarifa.multiply(rbc);
			baseCalculo = tarifa.subtract(redutor);

			icms = baseCalculo.multiply(aliquota.divide(BigDecimal.TEN.multiply(BigDecimal.TEN)));
			credPres = icms.multiply(cp.divide(BigDecimal.TEN.multiply(BigDecimal.TEN)));
			icmsRec = icms.subtract(credPres);

			outros = isentos.equals(BigDecimal.ZERO) ? BigDecimal.ZERO : passagem.subtract(isentos).subtract(baseCalculo);

			String tipoViagem = det.isInterEstadual() ? "IE" : "IM";
			BigDecimal taxaEmbarque = (isReceitaTerceiros && det.getTaxaEmbarque() == null) ? det.getTaxaEmbarque() : BigDecimal.ZERO;
			BigDecimal pedagio = (isReceitaTerceiros && det.getPedagio() == null) ? det.getPedagio() : BigDecimal.ZERO;
			BigDecimal seguro = (isReceitaTerceiros && det.getSeguro() == null) ? det.getSeguro() : BigDecimal.ZERO;

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

		return rdis;
	}

	private BigDecimal valorBaseCalculo(DetalhadoFiscal det, boolean isReceitaTerceiros) {
		BigDecimal total = BigDecimal.ZERO;
		total = total.add(det.getTarifa() == null ? BigDecimal.ZERO : det.getTarifa());

		if (isReceitaTerceiros && (det.isInterEstadual() && det.getIndTxembarqueEstadual() || !det.isInterEstadual() && det.getIndTxembarqueMunicipal()))
			total = total.add(det.getTaxaEmbarque() == null ? BigDecimal.ZERO : det.getTaxaEmbarque());

		if (isReceitaTerceiros && (det.isInterEstadual() && det.getIndPedagioEstdual() || !det.isInterEstadual() && det.getIndPedagioMunicipal()))
			total = total.add(det.getPedagio() == null ? BigDecimal.ZERO : det.getPedagio());

		if (isReceitaTerceiros && (det.isInterEstadual() && det.getIndSeguroEstadual() || !det.isInterEstadual() && det.getIndSeguroMunicipal()))
			total = total.add(det.getSeguro() == null ? BigDecimal.ZERO : det.getSeguro());

		return total;
	}

	private BigDecimal valorIsenta(DetalhadoFiscal det, boolean isReceitaTerceiros) {

		BigDecimal total = BigDecimal.ZERO;
		if (isReceitaTerceiros && (det.isInterEstadual() && !det.getIndTxembarqueEstadual() || !det.isInterEstadual() && !det.getIndTxembarqueMunicipal()))
			total = total.add(det.getTaxaEmbarque() == null ? BigDecimal.ZERO : det.getTaxaEmbarque());

		if (isReceitaTerceiros && (det.isInterEstadual() && !det.getIndPedagioEstdual() || !det.isInterEstadual() && !det.getIndPedagioMunicipal()))
			total = total.add(det.getPedagio() == null ? BigDecimal.ZERO : det.getPedagio());

		if (isReceitaTerceiros && (det.isInterEstadual() && !det.getIndSeguroEstadual() || !det.isInterEstadual() && !det.getIndSeguroMunicipal()))
			total = total.add(det.getSeguro() == null ? BigDecimal.ZERO : det.getSeguro());

		return total;
	}

	private BigDecimal valorPassagem(DetalhadoFiscal det, boolean isReceitaTerceiros) {
		BigDecimal total = BigDecimal.ZERO;
		total = total.add(det.getTarifa() == null ? BigDecimal.ZERO : det.getTarifa());
		if (isReceitaTerceiros) {
			total = total.add(det.getTaxaEmbarque() == null ? BigDecimal.ZERO : det.getTaxaEmbarque());
			total = total.add(det.getPedagio() == null ? BigDecimal.ZERO : det.getPedagio());
			total = total.add(det.getSeguro() == null ? BigDecimal.ZERO : det.getSeguro());
		}
		return total;
	}

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

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

			StringBuilder sql = new StringBuilder();
			sql.append(sqlRelatorioRDIVendidos(ufs));
			sql.append("    union all    ");
			sql.append(sqlRelatorioRDICancelados(ufs));

			NamedParameterStatement ps = new NamedParameterStatement(connection, sql.toString());
			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()) {

				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.setEstadoOrigem(rs.getString("estadoOrigem"));
				df.setEstadoDestino(rs.getString("estadoDestino"));
				df.setMunicipioOrigem(rs.getString("municipioOrigem"));
				df.setInterEstadual(rs.getBoolean("isInterEstadual"));
				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;
	}

	private String sqlRelatorioRDIVendidos(String ufs) {

		StringBuilder sql = new StringBuilder();

		sql.append("select distinct ");
		sql.append("  c.caja_id as cajaId, ");
		sql.append("  'REC' as tipoReceita, ");
		sql.append("  c.numoperacion as numoperacion, ");
		sql.append("  trunc(c.feccreacion) as fechorVenta, ");
		sql.append("  (case when s.aliasorigen_id is null then eo.estado_id else eos.estado_id end) as estadoId,");
		sql.append("  (case when s.aliasorigen_id is null then ei.icms else eis.icms end) as icmsInterestadual,");
		sql.append("  (case when s.aliasorigen_id is null then ei.icmsim else eis.icmsim end) as icmsIntermunicipal,");
		sql.append("  (case when s.aliasorigen_id is null then eo.cveestado else eos.cveestado end) as estadoOrigem,");
		sql.append("  (case when s.aliasdestino_id is null then ed.cveestado else eds.cveestado end) as estadoDestino,");
		sql.append("  (case when s.aliasorigen_id is null then co.codibge else cos.codibge end) as municipioOrigem,");
		sql.append("  case when ( (case when s.aliasorigen_id is null then eo.cveestado else eos.cveestado end) = ");
		sql.append("         (case when s.aliasdestino_id is null then ed.cveestado else eds.cveestado end) )  then 0 else 1 end as isInterEstadual, ");
		sql.append("  (case when s.aliasorigen_id is null then ei.porcredbaseicms else eis.porcredbaseicms end) as redBaseCalcIcms,");
		sql.append("  (case when s.aliasorigen_id is null then ei.porcredmunicipal else eis.porcredmunicipal end) as porcRedMunicipal,");
		sql.append("  (case when s.aliasorigen_id is null then ei.porcredestadual else eis.porcredestadual end) as porcRedEstadual,");
		sql.append("  (case when s.aliasorigen_id is null then ei.indtarifamunicipal else eis.indtarifamunicipal end) as indtarifamunicipal,");
		sql.append("  (case when s.aliasorigen_id is null then ei.indseguromunicipal else eis.indseguromunicipal end) as indseguromunicipal,");
		sql.append("  (case when s.aliasorigen_id is null then ei.indtxembarquemunicipal else eis.indtxembarquemunicipal end) as indtxembarquemunicipal,");
		sql.append("  (case when s.aliasorigen_id is null then ei.indpedagiomunicipal else eis.indpedagiomunicipal end) as indpedagiomunicipal,");
		sql.append("  (case when s.aliasorigen_id is null then ei.indtarifaestadual else eis.indtarifaestadual end) as indtarifaestadual,");
		sql.append("  (case when s.aliasorigen_id is null then ei.indseguroestadual else eis.indseguroestadual end) as indseguroestadual,");
		sql.append("  (case when s.aliasorigen_id is null then ei.indtxembarqueestadual else eis.indtxembarqueestadual end) as indtxembarqueestadual,");
		sql.append("  (case when s.aliasorigen_id is null then ei.indpedagioestdual else eis.indpedagioestdual end) as indpedagioestdual,");
		sql.append("  (case when s.aliasorigen_id is null then ei.tributacaoImportacao else eis.tributacaoImportacao end) as tributacaoImportacao,");
		sql.append("  (case when (coalesce(case when s.aliasorigen_id is null then po.regionmetropolitana_id ");
		sql.append("         else pos.regionmetropolitana_id end, -1) = coalesce(case when s.aliasorigen_id is null ");
		sql.append("         then pd.regionmetropolitana_id else pds.regionmetropolitana_id end, -2)) then 1 else 0 end) as isenta, ");
		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("  coalesce(r4.datamov, to_char(trunc(c.feccreacion), 'yyyymmdd')) as datamov ");
		sql.append("   ");
		sql.append(" from caja c ");
		sql.append(" join ruta r on r.ruta_id = c.ruta_id ");
		sql.append(" join parada po on po.parada_id = c.origen_id ");
		sql.append(" join ciudad co on co.ciudad_id = po.ciudad_id ");
		sql.append(" join estado eo on eo.estado_id = co.estado_id ");
		sql.append(" join parada pd on pd.parada_id = c.destino_id ");
		sql.append(" join ciudad cd on cd.ciudad_id = pd.ciudad_id ");
		sql.append(" join estado ed on ed.estado_id = cd.estado_id ");
		sql.append(" join empresa_imposto ei on ei.empresa_id = c.empresacorrida_id and ei.estado_id = eo.estado_id ");
		sql.append(" join fiscal_impressora imp on imp.numserie = c.serieimpfiscal ");
		sql.append(" left join estado e on e.estado_id = imp.estadolocal_id ");
		sql.append(" left join alias_servico s on s.origen_id = c.origen_id and s.destino_id = c.destino_id and (s.corrida_id = c.corrida_id or s.corrida_id is null) and s.ruta_id = c.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(" left join empresa_imposto eis on eis.empresa_id = c.empresacorrida_id and eis.estado_id = eos.estado_id ");
		sql.append(" left join fiscal_r4 r4 on r4.caja_id = c.caja_id ");
		sql.append(" left join fiscal_r2 r2 on r2.numserie20 = imp.numserie20 and r2.datamov = to_char(c.feccreacion, 'YYYYMMDD') ");
		sql.append(" join inscricao_estadual ie on c.empresacorrida_id = ie.empresa_id and ie.estado_id = coalesce(eos.estado_id, eo.estado_id) and ie.activo = 1 ");
		sql.append(" join ciudad cie on cie.ciudad_id = ie.ciudad_id ");
		sql.append(" join estado eie on eie.estado_id = cie.estado_id ");
		sql.append(" join marca ma on c.marca_id = ma.marca_id ");
		sql.append(" join empresa ep on ep.empresa_id = ma.empresa_id ");
		sql.append(" join punto_venta pv on pv.puntoventa_id = c.puntoventa_id ");
		sql.append(" left join parada ppv on ppv.parada_id = pv.parada_id ");
		sql.append(" left join ciudad cpv on cpv.ciudad_id = ppv.ciudad_id ");
		sql.append(" left join estado epv on epv.estado_id = cpv.estado_id ");
		sql.append("   ");
		sql.append(" where c.activo = 1 and po.activo = 1 and co.activo = 1 and eo.activo = 1 and ei.activo = 1 ");
		sql.append(" and coalesce(case when s.aliasorigen_id is null then ei.activo else eis.activo end, 0) = 1 ");
		sql.append(" and c.serieimpfiscal is not null ");
		sql.append(" and ((c.indreimpresion = 0 and c.motivocancelacion_id is null 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 c.empresacorrida_id = :EMPRESA_ID ");
		sql.append(" and c.num_bpe is null ");
		sql.append(" and ((case when s.aliasorigen_id is null then eo.cveestado else eos.cveestado end) in ( ").append(ufs).append(" )) ");
		sql.append("  ");
		sql.append("union all ");
		sql.append(" ");
		sql.append("select distinct ");
		sql.append("  c.caja_id as cajaId, ");
		sql.append("  'REC' as tipoReceita, ");
		sql.append("  c.numoperacion as numoperacion, ");
		sql.append("  trunc(c.feccreacion) as fechorVenta, ");
		sql.append("  coalesce(ae.estado_id, (case when s.aliasorigen_id is null then eo.estado_id else eos.estado_id end)) as estadoId,");
		sql.append("  coalesce(ei.icms, eos.icms) as icmsInterestadual, ");
		sql.append("  ei.icmsim as icmsIntermunicipal, ");
		sql.append("  coalesce(ae.cveestado,(case when s.aliasorigen_id is null then eo.cveestado else eos.cveestado end)) as estadoOrigem,");
		sql.append("  (case when s.aliasdestino_id is null then ed.cveestado else eds.cveestado end) as estadoDestino,");
		sql.append("  (case when s.aliasorigen_id is null then co.codibge else cos.codibge end) as municipioOrigem,");
		sql.append("  case when(coalesce(ae.cveestado,(case when s.aliasorigen_id is null then eo.cveestado else eos.cveestado end)) = ");
		sql.append("         (case when s.aliasdestino_id is null then ed.cveestado else eds.cveestado end) )  then 0 else 1 end as isInterEstadual, ");
		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("  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("  ei.tributacaoimportacao as tributacaoImportacao, ");
		sql.append("  (case when (coalesce(case when s.aliasorigen_id is null then po.regionmetropolitana_id ");
		sql.append("         else pos.regionmetropolitana_id end, -1) = coalesce(case when s.aliasorigen_id is null ");
		sql.append("         then pd.regionmetropolitana_id else pds.regionmetropolitana_id end, -2)) then 1 else 0 end) as isenta, ");
		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("from caja c ");
		sql.append("  join marca m on c.marca_id = m.marca_id ");
		sql.append("  join empresa e on e.empresa_id = m.empresa_id ");
		sql.append("  join aidf a on a.aidf_id = c.aidf_id ");
		sql.append("  join punto_venta pv on pv.puntoventa_id = c.puntoventa_id ");
		sql.append("  join ciudad ce on ce.ciudad_id = e.ciudad_id ");
		sql.append("  join estado ee on ee.estado_id = ce.estado_id ");
		sql.append("  join parada po on po.parada_id = c.origen_id ");
		sql.append("  join ciudad co on co.ciudad_id = po.ciudad_id ");
		sql.append("  join estado eo on eo.estado_id = co.estado_id ");
		sql.append("  join parada pd on pd.parada_id = c.destino_id ");
		sql.append("  join ciudad cd on cd.ciudad_id = pd.ciudad_id ");
		sql.append("  join estado ed on ed.estado_id = cd.estado_id ");
		sql.append("  left join alias_servico s on s.origen_id = c.origen_id ");
		sql.append("                 and s.destino_id = c.destino_id and (s.corrida_id = c.corrida_id or s.corrida_id is null) ");
		sql.append("                 and s.ruta_id = c.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("  left join estado ae on ae.estado_id = a.estado_id ");
		sql.append("  join inscricao_estadual ie on e.empresa_id = ie.empresa_id ");
		sql.append("                 and ie.estado_id = coalesce(ae.estado_id, eos.estado_id) and ie.activo = 1 ");
		sql.append("  join ciudad cie on cie.ciudad_id = ie.ciudad_id ");
		sql.append("  join estado eie on eie.estado_id = cie.estado_id ");
		sql.append("  join empresa_imposto ei on ei.empresa_id = c.empresacorrida_id ");
		sql.append("                 and ei.estado_id = coalesce(ae.estado_id, eos.estado_id) and ei.activo = 1 ");
		sql.append("where ((c.tipoventa_id = 3 and c.indstatusboleto = 'V' and c.indreimpresion = 0) ");
		sql.append("        or (c.tipoventa_id in (12,18) and c.indstatusboleto = 'E' and c.numfoliosistema = c.numfoliopreimpreso)) ");
		sql.append("   and (c.motivocancelacion_id is null or c.motivocancelacion_id <> 35) ");
		sql.append("   and c.indcancelacion = 0 ");
		sql.append("   and c.empresacorrida_id = :EMPRESA_ID ");
		sql.append("   and c.feccreacion between :DATE_INICIO and :DATE_FIM ");
		sql.append("   and c.num_bpe is null ");
		sql.append("   and coalesce(ae.cveestado, eos.cveestado) in ( ").append(ufs).append(" ) ");
		return sql.toString();
	}

	private String sqlRelatorioRDICancelados(String ufs) {

		StringBuilder sql = new StringBuilder();
		sql.append("select distinct ");
		sql.append("  b.boleto_id as cajaId, ");
		sql.append("  'DEV' as tipoReceita, ");
		sql.append("  b.numoperacion as numoperacion, ");
		sql.append("  trunc(b.feccreacion) as fechorVenta, ");
		sql.append("  coalesce(esaidf.estado_id, eos.estado_id, est.estado_id) as estadoId, ");
		sql.append("  ei.icms as icmsInterestadual, ");
		sql.append("  ei.icmsim as icmsIntermunicipal, ");
		sql.append("  coalesce(esaidf.cveestado, eos.cveestado, est.cveestado) as estadoOrigem, ");
		sql.append("  coalesce(eds.cveestado, est.cveestado) as estadoDestino, ");
		sql.append("  0 as municipioOrigem, ");
		sql.append("  case when (coalesce(cos.estado_id,co.estado_id) <> coalesce(cds.estado_id,cd.estado_id)) then 1 else 0 end as isInterEstadual, ");
		sql.append("  ei.porcredbaseicms as redBaseCalcIcms, ");
		sql.append("  ei.porcredmunicipal as porcRedMunicipal, ");
		sql.append("  ei.porcredestadual as porcRedEstadual, ");
		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("  ei.tributacaoimportacao as tributacaoImportacao, ");
		sql.append("  case when (coalesce(pos.regionmetropolitana_id, ori.regionmetropolitana_id, -1) = ");
		sql.append("              coalesce(pds.regionmetropolitana_id, des.regionmetropolitana_id, -2)) then 1 else 0 end as isenta, ");
		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(b.feccreacion), 'yyyymmdd') as datamov ");
		sql.append("   ");
		sql.append("from boleto b ");
		sql.append("inner join marca m on m.marca_id = b.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 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 punto_venta ptvo on ptvo.puntoventa_id = b.ptovtaventa_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("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("join inscricao_estadual ie on e.empresa_id = ie.empresa_id ");
		sql.append("               			   and ie.estado_id = coalesce(aidf.estado_id, 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(aidf.estado_id, eos.estado_id, est.estado_id) and ei.activo = 1 ");
		sql.append("where b.motivocancelacion_id in (31,32,10,37,99,36) ");
		sql.append("  and b.indstatusboleto = 'C' 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("  and b.categoria_id not in (select valorconstante from constante where nombconstante = 'GRATUIDADE_CRIANCA') ");
		sql.append("  and coalesce(esaidf.cveestado, eos.cveestado, est.cveestado) in ( ").append(ufs).append(" ) ");
		sql.append("  and b.num_bpe is null ");
		sql.append("order by estadoId, isInterEstadual ");

		return sql.toString();
	}
}
