package com.rjconsultores.ventaboletos.relatorios.impl;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.rjconsultores.ventaboletos.constantes.Constantes;
import com.rjconsultores.ventaboletos.enums.RelatorioMovimentacaoBilheteStatusEnum;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.DataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.RelatorioMovimentacaoBilheteBean;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

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

public class RelatorioMovimentacaoBilhete extends Relatorio {
	
	private List<RelatorioMovimentacaoBilheteBean> lsDadosRelatorio;
	
	public RelatorioMovimentacaoBilhete(Map<String, Object> parametros, Connection conexao)  throws Exception {
		super(parametros, conexao);
		
		this.setCustomDataSource(new DataSource(this) {
			@Override
			public void initDados() throws Exception {

				Connection conexao = this.relatorio.getConexao();

				Map<String, Object> parametros = this.relatorio.getParametros();

				String fecInicioViagem = null;
				if (parametros.containsKey("fecInicioViagem")) {
					fecInicioViagem = parametros.get("fecInicioViagem").toString() + " 00:00";
				}

				String fecFinalViagem = null;
				if (parametros.containsKey("fecFinalViagem")) {
					fecFinalViagem = parametros.get("fecFinalViagem").toString() + " 23:59";
				}

				String fecInicioVenda = null;
				if (parametros.containsKey("fecInicioVenda")) {
					fecInicioVenda = parametros.get("fecInicioVenda").toString() + " 00:00";
				}

				String fecFinalVenda = null;
				if (parametros.containsKey("fecFinalVenda")) {
					fecFinalVenda = parametros.get("fecFinalVenda").toString() + " 23:59";
				}

				Integer empresa_id = (Integer) parametros.get("empresa_id");
				Integer agencia_id = (Integer) parametros.get("agencia_id");
				Integer ruta_id = (Integer) parametros.get("ruta_id");
				Integer origem_id = (Integer) parametros.get("origem_id");
				Integer destino_id = (Integer) parametros.get("destino_id");
				Integer orgaoConcedente_id = (Integer) parametros.get("orgao_concedente_id");
				RelatorioMovimentacaoBilheteStatusEnum status = (RelatorioMovimentacaoBilheteStatusEnum) parametros.get("status");
				String categoria_id = (String) parametros.get("categoria_id");
				Integer mcAlteracaoPoltrona = (Integer) (parametros.get("mcAlteracaoPoltrona") != null ? parametros.get("mcAlteracaoPoltrona") : null);

				String sql = getSql(fecInicioViagem, fecFinalViagem, fecInicioVenda, fecFinalVenda, empresa_id, agencia_id, ruta_id, origem_id, destino_id, orgaoConcedente_id, status, categoria_id, mcAlteracaoPoltrona);
				
				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);

				if (fecInicioViagem != null) {
					stmt.setString("fecInicioViagem", fecInicioViagem);
				}

				if (fecFinalViagem != null) {
					stmt.setString("fecFinalViagem", fecFinalViagem);
				}

				if (fecInicioVenda != null) {
					stmt.setString("fecInicioVenda", fecInicioVenda);
				}

				if (fecFinalVenda != null) {
					stmt.setString("fecFinalVenda", fecFinalVenda);
				}

				if (empresa_id != null) {
					stmt.setInt("empresa_id", empresa_id);
				}

				if (agencia_id != null) {
					stmt.setInt("puntoventa_id", agencia_id);
				}

				if (ruta_id != null) {
					stmt.setInt("ruta_id", ruta_id);
				}

				if (origem_id != null) {
					stmt.setInt("origem_id", origem_id);
				}

				if (destino_id != null) {
					stmt.setInt("destino_id", destino_id);
				}

				if (orgaoConcedente_id != null && !orgaoConcedente_id.equals(-1)) {
					stmt.setInt("orgao_concedente_id", orgaoConcedente_id);
				}

				if (mcAlteracaoPoltrona != null) {
					stmt.setInt("mcAlteracaoPoltrona", mcAlteracaoPoltrona);
				}

				stmt.setInt("bpeEventoAlteracaoPoltrona", Integer.valueOf(Constantes.BPE_ALTERACAO_POLTRONA));
				
				ResultSet rset = stmt.executeQuery();
		
				lsDadosRelatorio = new ArrayList<RelatorioMovimentacaoBilheteBean>();
				
				SimpleDateFormat hora = new SimpleDateFormat("HH:mm");
				SimpleDateFormat data = new SimpleDateFormat("dd/MM/yyyy");

				while (rset.next()) {
					String indstatusboleto = rset.getString("INDSTATUSBOLETO");
					if (indstatusboleto == null) {
						indstatusboleto = "";
					}

					RelatorioMovimentacaoBilheteBean bean = new RelatorioMovimentacaoBilheteBean();
					bean.setTarifa(rset.getBigDecimal("preciopagado"));
					bean.setCcf(rset.getString("ccf"));
					bean.setCorridaId(rset.getString("corrida_id"));
					bean.setCveusuario(rset.getString("cveusuario"));
					bean.setDescnumdoc(rset.getString("descnumdoc"));
					bean.setDesctipoventa(rset.getString("desctipoventa"));
					bean.setDestino(rset.getString("destino"));
					bean.setFeccreacion(rset.getDate("feccreacion"));
					bean.setFecdatviaje(rset.getTimestamp("fechorviaje") != null ? data.format(rset.getTimestamp("fechorviaje")) : "");
					bean.setFechorviaje(rset.getTimestamp("fechorviaje") != null ? hora.format(rset.getTimestamp("fechorviaje")) : "");
					bean.setKm(rset.getInt("numkmviaje"));
					bean.setLinha(rset.getString("descruta"));
					bean.setNombpasajero(rset.getString("nombpasajero"));
					bean.setNombpuntoventa(rset.getString("nombpuntoventa"));
					bean.setOrigen(rset.getString("origen"));
					bean.setPorccategoria(rset.getBigDecimal("porccategoria"));
					bean.setPreciooriginal(rset.getBigDecimal("preciooriginal"));
					bean.setPreciopagado(rset.getBigDecimal("preciopagado"));
					bean.setNombempresa(rset.getString("nombempresa"));
					bean.setCvecategoria(rset.getString("cvecategoria"));
					bean.setNumasiento(rset.getString("numasiento"));
					bean.setDescorigen(rset.getString("descorigen"));
					bean.setDescdestino(rset.getString("descdestino"));
					bean.setNumfoliosistema(rset.getString("numfoliosistema"));
					bean.setTipoDoc(rset.getString("desctipodoc"));
					bean.setTipo(rset.getString("desccategoria"));
					bean.setSeguro(rset.getBigDecimal("importeseguro"));
					bean.setPedagio(rset.getBigDecimal("importepedagio"));
					bean.setUtr(rset.getBigDecimal("importetaxaembarque"));
					bean.setRg(rset.getString("DESCNUMDOC"));
					bean.setStatus(indstatusboleto);
					bean.setCodOrigem(rset.getString("codOrigem"));
					bean.setCodDestino(rset.getString("codDestino"));
					bean.setDescorgao(rset.getString("descorgao"));
					bean.setTpp(rset.getBigDecimal("importetpp"));
					bean.setDireccionnumero(rset.getString("direccionnumero"));
					bean.setDataEmissao(rset.getDate("fechorventa"));
					bean.setNumRuta(rset.getString("numruta"));
					bean.setPrefixo(rset.getString("prefixo"));
					bean.setSerie(rset.getString("serie"));
					bean.setSubserie(rset.getString("subserie"));
					bean.setNumbpe(rset.getString("num_bpe"));
					bean.setChavebpe(rset.getString("chbpe"));
					bean.setProtocolobpe(rset.getString("nprot"));
					bean.setHoraMD(rset.getTimestamp("feccreacion") != null ? hora.format(rset.getTimestamp("feccreacion")) : "");
					bean.setHoraEmissao(rset.getTimestamp("fechorventa") != null ? hora.format(rset.getTimestamp("fechorventa")) : "");
					bean.setNumPuntoVenta(rset.getString("numpuntoventa"));
					
					if (isPossuiElemento(RelatorioMovimentacaoBilheteStatusEnum.TROCA.getStatusRelatorioAnterior(), indstatusboleto)
							|| isPossuiElemento(RelatorioMovimentacaoBilheteStatusEnum.TRANSFERENCIA.getStatusRelatorioAnterior(), indstatusboleto)
							|| isPossuiElemento(RelatorioMovimentacaoBilheteStatusEnum.REATIVACAO.getStatusRelatorioAnterior(), indstatusboleto)
							|| isPossuiElemento(RelatorioMovimentacaoBilheteStatusEnum.TROCA_TITULARIDADE.getStatusRelatorioAnterior(), indstatusboleto)
							|| isPossuiElemento(RelatorioMovimentacaoBilheteStatusEnum.TROCA_POLTRONA.getStatusRelatorioAnterior(), indstatusboleto)) {
						bean.setChavebpe(rset.getString("chbpe_ori"));
						bean.setProtocolobpe(rset.getString("nprot_ori"));
					}
					
					if (isPossuiElemento(RelatorioMovimentacaoBilheteStatusEnum.TRANSFERENCIA.getStatusRelatorioAnterior(), indstatusboleto)) {
						bean.setSerienovo(rset.getString("serienovo_ant"));
						bean.setSubserienovo(rset.getString("subserienovo_ant"));
						bean.setCcfnovo(rset.getString("ccfnovo_ant"));
						bean.setBpenovo(rset.getString("bpenovo_ant"));
						bean.setNumfoliosistemanovo(rset.getString("numfoliosistema_ant"));
					} else if (isPossuiElemento(RelatorioMovimentacaoBilheteStatusEnum.TROCA.getStatusRelatorioAnterior(), indstatusboleto)
								|| isPossuiElemento(RelatorioMovimentacaoBilheteStatusEnum.REATIVACAO.getStatusRelatorioAnterior(), indstatusboleto)) {
						bean.setSerienovo(rset.getString("serienovo_prox"));
						bean.setSubserienovo(rset.getString("subserienovo_prox"));
						bean.setCcfnovo(rset.getString("ccfnovo_prox"));
						bean.setBpenovo(rset.getString("bpenovo_prox"));
						bean.setNumfoliosistemanovo(rset.getString("numfoliosistema_prox"));
					} else if (isPossuiElemento(RelatorioMovimentacaoBilheteStatusEnum.TROCA_TITULARIDADE.getStatusRelatorioAnterior(), indstatusboleto)
								|| isPossuiElemento(RelatorioMovimentacaoBilheteStatusEnum.TROCA_POLTRONA.getStatusRelatorioAnterior(), indstatusboleto)) {
						bean.setSerienovo(rset.getString("serienovo"));
						bean.setSubserienovo(rset.getString("subserienovo"));
						bean.setCcfnovo(rset.getString("ccfnovo"));
						bean.setBpenovo(rset.getString("bpenovo"));
						bean.setNumfoliosistemanovo(rset.getString("numfoliosistemanovo"));
					}

					lsDadosRelatorio.add(bean);

					addCheckin(rset, lsDadosRelatorio, bean);

					addTitularidadeTrocada(rset, lsDadosRelatorio, bean);

					filtrarStatus(status, lsDadosRelatorio);
				}

				if (lsDadosRelatorio.size() > 0) {
					setLsDadosRelatorio(lsDadosRelatorio);
				}
			}
		});
	}
	
	@Override
	protected void processaParametros() throws Exception {
	}

	private void addCheckin(ResultSet rset, List<RelatorioMovimentacaoBilheteBean> lsDadosRelatorio, RelatorioMovimentacaoBilheteBean bean) throws SQLException, CloneNotSupportedException {
		if (rset.getInt("checkin") == 1) {
			RelatorioMovimentacaoBilheteBean beanNovo = bean.getClone();
			beanNovo.setStatus(RelatorioMovimentacaoBilheteStatusEnum.CHECK_IN.getStatusRelatorio());
			lsDadosRelatorio.add(beanNovo);
		}
	}

	private void addTitularidadeTrocada(ResultSet rset, List<RelatorioMovimentacaoBilheteBean> lsDadosRelatorio, RelatorioMovimentacaoBilheteBean bean) throws SQLException, CloneNotSupportedException {
		if (rset.getInt("titularidade_trocada") == 1) {
			RelatorioMovimentacaoBilheteBean beanNovo = bean.getClone();
			beanNovo.setStatus(RelatorioMovimentacaoBilheteStatusEnum.TROCA_TITULARIDADE.getStatusRelatorio());
			lsDadosRelatorio.add(beanNovo);
		}
	}

	private void filtrarStatus(RelatorioMovimentacaoBilheteStatusEnum status, List<RelatorioMovimentacaoBilheteBean> lsDadosRelatorio) {
		if (status != null) {
			Iterator<RelatorioMovimentacaoBilheteBean> iterator = lsDadosRelatorio.iterator();

			while (iterator.hasNext()) {
				RelatorioMovimentacaoBilheteBean bean = iterator.next();

				if (bean.getStatus().equalsIgnoreCase(status.getStatusRelatorio())) {
					continue;
				} else if (isPossuiElemento(status.getStatusRelatorioAnterior(), bean.getStatus())) {
					continue;
				}

				iterator.remove();
			}
		}
	}

	private void setLsDadosRelatorio(List<RelatorioMovimentacaoBilheteBean> lsDadosRelatorio) {
		this.setCollectionDataSource(new JRBeanCollectionDataSource(lsDadosRelatorio));
		this.lsDadosRelatorio = lsDadosRelatorio;
	}
	
	private String getSql(String fecInicioViagem, String fecFinalViagem, String fecInicioVenda, String fecFinalVenda, Integer empresa_id, Integer agencia_id, Integer ruta_id, Integer origem_id, Integer destino_id, Integer orgaoConcedente_id, RelatorioMovimentacaoBilheteStatusEnum status, String categoria_id, Integer mcAlteracaoPoltrona) {
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT * ");
		sb.append("FROM ");
		sb.append("  (SELECT distinct b.boletooriginal_id, b.boleto_id,");
		sb.append("          b.ccf,");
		sb.append("          og.descorgao,");
		sb.append("          b.feccreacion,");
		sb.append("          ori.cveparada origen,");
		sb.append("          des.cveparada destino,");
		sb.append("          ori.descparada descorigen,");
		sb.append("          des.descparada descdestino,");
		sb.append("          b.numkmviaje,");
		sb.append("          r.descruta,");
		sb.append("          b.corrida_id,");
		sb.append("          b.fechorviaje,");
		sb.append("          b.numasiento,");
		sb.append("          b.numfoliosistema,");
		sb.append("          case when b.tipoventa_id in(5,12,18,41,49)  then 'PTA' else tv.desctipoventa end as desctipoventa, ");
		sb.append("          b.nombpasajero,");
		sb.append("          b.descnumdoc,");
		sb.append("          tar.preciooriginal,");
		sb.append("          tar.precio,");
		sb.append("          case when b.PRECIOBASE > 0 then TRUNC(((100 - (b.PRECIOPAGADO * 100) / b.PRECIOBASE)),2) else 0 end as porccategoria, ");
		sb.append("          u.cveusuario,");
		sb.append("          ag.nombpuntoventa,");
		sb.append("          ag.direccionnumero,");
		sb.append("          e.nombempresa,");
		sb.append("          ca.cvecategoria,");
		sb.append("          b.desctipodoc,");
		sb.append("          ca.desccategoria,");
		sb.append("          b.importepedagio,");
		sb.append("          b.importeseguro,");
		sb.append("          b.importetaxaembarque, ");
		sb.append(" 						case ");
		sb.append(" 					    when b.motivocancelacion_id = 11 ");
		sb.append(" 					         and b.indcancelacion = 0 then 'RESERVA' ");
		sb.append(" 					    when b.motivocancelacion_id = 9 then 'CONFIRMA RESERVA' ");
		sb.append(" 					    when b.motivocancelacion_id = 11 ");
		sb.append(" 					         and b.indcancelacion = 1 then 'LIBERA RESERVA' ");
		sb.append(" 					    when b.motivocancelacion_id = 12 then 'LIBERA.RESERVA AUTO' ");
		sb.append("                         when b.indreimpresion = 1 and b.motivoreimpresion_id = 99 then 'REIMPRESSO' ");
		sb.append(" 					    else b.indstatusboleto ");
		sb.append(" 					end as indstatusboleto, ");
		sb.append("          ori.cveparada codorigem,");
		sb.append("          des.cveparada coddestino,");
		sb.append("          b.fechorventa fechorventa,");
		sb.append("          r.numruta,");
		sb.append("          r.prefixo,");
		sb.append("          aidf.serie serie, ");
		sb.append("       	 aidf.subserie subserie, ");
		sb.append("       	 b.num_bpe num_bpe, ");
		sb.append("       	 bpe.chbpe chbpe, ");
		sb.append("       	 bpe.nprot nprot, ");
		sb.append("       	 'N/A' as serienovo , ");
		sb.append("       	 'N/A' as subserienovo , ");
		sb.append("       	 'N/A' as ccfnovo , ");
		sb.append("       	 'N/A' as bpenovo, ");
		sb.append("       	 'N/A' as numfoliosistemanovo, ");
		sb.append("       	 b.importetpp, ");
		sb.append("       	 0 as checkin, ");
		sb.append("       	 0 as titularidade_trocada, ");
		sb.append("       	 ag.numpuntoventa, ");
		sb.append("       	 b.preciopagado, ");
		sb.append("       	 null chbpe_ori, ");
		sb.append("       	 null nprot_ori, ");
		sb.append("       	 'N/A' as serienovo_ant, ");
		sb.append("       	 'N/A' as subserienovo_ant, ");
		sb.append("       	 'N/A' as ccfnovo_ant , ");
		sb.append("       	 'N/A' as bpenovo_ant, ");
		sb.append("       	 'N/A' as numfoliosistema_ant, ");
		sb.append("       	 'N/A' as serienovo_prox , ");
		sb.append("       	 'N/A' as subserienovo_prox , ");
		sb.append("       	 'N/A' as ccfnovo_prox , ");
		sb.append("       	 'N/A' as bpenovo_prox, ");
		sb.append("       	 'N/A' as numfoliosistema_prox ");
		sb.append("   FROM boleto b");
		sb.append("   JOIN categoria ca ON b.categoria_id = ca.categoria_id");
		sb.append("   JOIN parada ori ON ori.parada_id = b.origen_id");
		sb.append("   JOIN parada des ON des.parada_id = b.destino_id");
		sb.append("   JOIN ruta r ON r.ruta_id = b.ruta_id");
		sb.append("   JOIN tipo_venta tv ON tv.tipoventa_id = b.tipoventa_id");
		sb.append("   JOIN punto_venta ag ON ag.puntoventa_id = b.puntoventa_id");
		sb.append("   JOIN usuario u ON u.usuario_id = b.usuario_id");
		sb.append("   JOIN vigencia_tarifa vt ON b.fechorventa BETWEEN vt.feciniciovigencia AND vt.fecfinvigencia and vt.activo = 1");
		sb.append("   JOIN tarifa tar ON (tar.ruta_id = b.ruta_id");
		sb.append("                       AND tar.marca_id = b.marca_id");
		sb.append("                       AND tar.claseservicio_id = b.claseservicio_id");
		sb.append("                       AND tar.vigenciatarifa_id = vt.vigenciatarifa_id");
		sb.append("                       AND tar.origen_id = b.origen_id");
		sb.append("                       AND tar.destino_id = b.destino_id and tar.activo = 1)");
		sb.append("   JOIN marca m on m.marca_id = b.marca_id");
		sb.append("   JOIN empresa e on e.empresa_id = m.empresa_id");
		sb.append("   JOIN orgao_concedente og ON og.orgaoconcedente_id = tar.orgaoconcedente_id");
		sb.append("   LEFT join aidf aidf on aidf.aidf_id = b.aidf_id ");
		sb.append("   left join bpe bpe on bpe.boleto_id = b.boleto_id ");
		sb.append("   WHERE 1=1  and b.tipoventa_id = 15");
		sb.append("   AND b.indstatusboleto = 'S' ");
		
		if (fecInicioViagem != null && fecFinalViagem != null) {
			sb.append("AND b.feccorrida BETWEEN TO_DATE(:fecInicioViagem,'dd/mm/yyyy hh24:mi') AND TO_DATE(:fecFinalViagem,'dd/mm/yyyy hh24:mi') ");
		}

		if (fecInicioVenda != null && fecFinalVenda != null) {
			sb.append("AND b.fechorventa BETWEEN TO_DATE(:fecInicioVenda,'dd/mm/yyyy hh24:mi') AND TO_DATE(:fecFinalVenda,'dd/mm/yyyy hh24:mi') ");
		}		
		
		if (empresa_id != null) {
			sb.append("AND e.empresa_id = :empresa_id ");
		}

		if (agencia_id != null) {
			sb.append("AND b.puntoventa_id = :puntoventa_id ");
		}

		if (ruta_id != null) {
			sb.append("AND b.ruta_id = :ruta_id ");
		}

		if (origem_id != null) {
			sb.append("AND ori.parada_id = :origem_id ");
		}

		if (destino_id != null) {
			sb.append("AND des.parada_id = :destino_id ");
		}

		if (categoria_id != null && !categoria_id.isEmpty()) {
			sb.append("AND ca.categoria_id in (" + categoria_id + ") ");
		}

		if (orgaoConcedente_id != null && !orgaoConcedente_id.equals(-1)) {
			sb.append("AND r.orgaoconcedente_id = :orgao_concedente_id ");
		}

		sb.append("   ");
		sb.append("   UNION ALL ");
		sb.append("   ");
		sb.append("   SELECT distinct c.transacaooriginal_id, c.transacao_id,");
		sb.append("                    c.ccf,");
		sb.append("                    og.descorgao,");
		sb.append("                    c.feccreacion,");
		sb.append("                    ori.cveparada origen,");
		sb.append("                    des.cveparada destino,");
		sb.append("                    ori.descparada descorigen,");
		sb.append("                    des.descparada descdestino,");
		sb.append("                    c.numkmviaje,");
		sb.append("                    r.descruta,");
		sb.append("                    c.corrida_id,");
		sb.append("                    c.fechorviaje,");
		sb.append("                    c.numasiento,");
		sb.append("                    c.numfoliosistema,");
		sb.append("                    case when c.numfoliopreimpreso is null then 'PTA' when c.tipoventa_id = '81' then 'VENDA DE TRANSFERENCIA'  when c.tipoventa_id = '82' then 'CONFIRM.VEND.ABERTO'  when c.tipoventa_id = '8' then 'TROCA' else tv.desctipoventa end as desctipoventa, ");
		sb.append("                    c.nombpasajero,");
		sb.append("                    c.descnumdoc,");
		sb.append("                    tar.preciooriginal,");
		sb.append("                    tar.precio,");
		sb.append("         		  case when c.PRECIOBASE > 0 then TRUNC(((100 - (c.PRECIOPAGADO * 100) / c.PRECIOBASE)),2) else 0 end as  porccategoria, ");
		sb.append("                    u.cveusuario,");
		sb.append("                    ag.nombpuntoventa,");
		sb.append("                    ag.direccionnumero,");
		sb.append("                    e.nombempresa,");
		sb.append("                    ca.cvecategoria,");
		sb.append("                    c.desctipodoc,");
		sb.append("                    ca.desccategoria,");
		sb.append("                    c.importepedagio,");
		sb.append("                    c.importeseguro,");
		sb.append("                    c.importetaxaembarque,");
		sb.append("                    case when c.indstatusboleto = 'V' then 'VENDIDO' ");
		sb.append("                    		when c.indstatusboleto = 'C' and c.motivocancelacion_id = 31 then 'CANCELADO' ");
		sb.append(" 				        when c.indstatusboleto = 'C' and c.motivocancelacion_id = 32 then 'DEVOLVIDO' ");
		sb.append(" 				        when c.indstatusboleto = 'C' and c.motivocancelacion_id = 37 then 'CANCEC. EMERG' ");
		sb.append(" 				        when c.indstatusboleto = 'E' and c.indreimpresion = 1 then  'ENTREGUE' ");

		// TROCA e TROCA PASSAGEM
		sb.append("                         when (c.indstatusboleto = 'T' and c.tipoventa_id = 8) ");
		sb.append("                               or (c.indstatusboleto = 'T' and c.tipoventa_id not in (81,41,82) and ct.cambiotitularidad_id is null and (bpe.tipoevento is null or bpe.tipoevento <> :bpeEventoAlteracaoPoltrona)) ");
		sb.append(" 							  or (c.indstatusboleto = 'T' and c.motivocancelacion_id is null and c.tipoventa_id = 8 and (bpe.tipoevento is null or bpe.tipoevento <> :bpeEventoAlteracaoPoltrona))  ");
		sb.append(" 							  then 'TROCA' ");
		sb.append("                         when c.indstatusboleto = 'C'  and c.motivocancelacion_id = 10 then 'TROCA PASSAGEM' ");

		// POLTRONA ALTERADA e TROCA POLTRONA
		sb.append("                         when c.indstatusboleto = 'T' and c.motivocancelacion_id is null and bpe.tipoevento = :bpeEventoAlteracaoPoltrona then 'POLTRONA ALTERADA' ");
		if (mcAlteracaoPoltrona != null) {
			// sb.append(" when c.indstatusboleto = 'C' and c.indreimpresion = 1 and c.motivocancelacion_id = :mcAlteracaoPoltrona then 'TROCA POLTRONA' ");
			sb.append("                     when c.indstatusboleto = 'C' and (select count(*) from caja c1 join bpe bpe1 on bpe1.boleto_id = c1.transacao_id where c1.transacaoanterior_id=c.transacao_id and c1.indstatusboleto = 'T' and c1.motivocancelacion_id is null and bpe1.tipoevento = :bpeEventoAlteracaoPoltrona)>0 then 'TROCA POLTRONA' ");
		}

		// TRANSFERIDO e TRANSFERÊNCIA
		sb.append("                         when c.indstatusboleto = 'T'  and c.tipoventa_id = 81 then 'TRANSFERIDO' ");
		sb.append("                         when c.indstatusboleto = 'C' and c.motivocancelacion_id = 23 and (select count(*) from caja c1 where c1.transacaoanterior_id=c.transacao_id and c1.tipoventa_id=81 and c1.indstatusboleto = 'T')>0 then 'TRANSFERÊNCIA' ");

		sb.append("                         when c.indstatusboleto = 'T'  and c.tipoventa_id = 82 then 'CONFIRM.ABERTO' " );
		sb.append("                         when c.indstatusboleto = 'C' and c.motivocancelacion_id = 27 then 'NO-SHOW' ");
		
		// TITULARIDADE TROCADA e TROCA TITULARIDADE
		// sb.append(" when c.indstatusboleto = 'V' and (select count(*) from caja c1 join cambio_titularidad ct1 on ct1.boleto_id = c1.transacao_id where c1.activo=1 and c1.transacaooriginal_id=c.transacao_id)>0 then 'TITULARIDADE TROCADA' ");
		sb.append("                         when ct.cambiotitularidad_id is not null then 'TROCA TITULARIDADE' ");

		// CHECKIN REATIVADO e REATIVADO
		sb.append("                         when c.indstatusboleto = 'T' and c.tipoventa_id = 41  then 'CHECKIN REATIVADO' ");
		sb.append("                         when c.indstatusboleto = 'C' and c.motivocancelacion_id = 23 and (select count(*) from caja c1 where c1.transacaoanterior_id=c.transacao_id and c1.tipoventa_id=41 and c1.indstatusboleto = 'T')>0 then 'REATIVADO' ");

		sb.append("                         when c.indreimpresion = 1 and c.motivoreimpresion_id = 99 then 'REIMPRESSO' ");
		sb.append("                         else c.indstatusboleto ");
		sb.append("                    end as indstatusboleto,");
		sb.append("                    ori.cveparada codorigem,");
		sb.append("                    des.cveparada coddestino,");
		sb.append("                    c.fechorventa fechorventa,");
		sb.append("          		   r.numruta,");
		sb.append("          		   r.prefixo,");
		sb.append("       			   aidf.serie serie, ");
		sb.append("       			   aidf.subserie subserie, ");
		sb.append("       	 		   c.num_bpe num_bpe, ");
		sb.append("       	 		   bpe.chbpe chbpe, ");
		sb.append("       	 		   bpe.nprot nprot, ");
		sb.append("       	 		   c_ori.ccf as ccfnovo, ");
		sb.append("       			   aidf_ori.serie serienovo, ");
		sb.append("       			   aidf_ori.subserie subserienovo, ");
		sb.append("       	 		   c_ori.num_bpe bpenovo, ");
		sb.append("       	 		   c_ori.numfoliosistema numfoliosistemanovo, ");
		sb.append("       	 		   c.importetpp, ");
		sb.append("                    case when c.indstatusboleto = 'V' and (select count(*) from boleto_checkin bc1 where bc1.activo=1 and bc1.boletooriginal_id=c.transacao_id)=0 and c.fechorviaje > c.fechorventa then 1 else 0 end as checkin, ");
		sb.append("                    case when c.indstatusboleto = 'V' and (select count(*) from caja c1 join cambio_titularidad ct1 on ct1.boleto_id = c1.transacao_id where c1.activo=1 and c1.transacaooriginal_id=c.transacao_id)>0 then 1 else 0 end as titularidade_trocada, ");
		sb.append("       	 		   ag.numpuntoventa, ");
		sb.append("       	 		   c.preciopagado, ");
		sb.append("       	 		   bpe_ori.chbpe chbpe_ori, ");
		sb.append("       	 		   bpe_ori.nprot nprot_ori, ");
		sb.append("       	 		   c_ant.ccf as ccfnovo_ant, ");
		sb.append("       			   aidf_ant.serie serienovo_ant, ");
		sb.append("       			   aidf_ant.subserie subserienovo_ant, ");
		sb.append("       	 		   c_ant.num_bpe bpenovo_ant, ");
		sb.append("       	 		   c_ant.numfoliosistema numfoliosistema_ant, ");
		sb.append("       	 		   c_prox.ccf as ccfnovo_prox, ");
		sb.append("       			   aidf_prox.serie serienovo_prox, ");
		sb.append("       			   aidf_prox.subserie subserienovo_prox, ");
		sb.append("       	 		   c_prox.num_bpe bpenovo_prox, ");
		sb.append("       	 		   c_prox.numfoliosistema numfoliosistema_prox ");
		sb.append("   FROM caja c");
		sb.append("   JOIN categoria ca ON c.categoria_id = ca.categoria_id");
		sb.append("   JOIN parada ori ON ori.parada_id = c.origen_id");
		sb.append("   JOIN parada des ON des.parada_id = c.destino_id");
		sb.append("   JOIN ruta r ON r.ruta_id = c.ruta_id");
		sb.append("   JOIN tipo_venta tv ON tv.tipoventa_id = c.tipoventa_id");
		sb.append("   JOIN punto_venta ag ON ag.puntoventa_id = c.puntoventa_id");
		sb.append("   JOIN usuario u ON u.usuario_id = c.usuario_id");
		sb.append("   JOIN vigencia_tarifa vt ON c.fechorventa BETWEEN vt.feciniciovigencia AND vt.fecfinvigencia");
		sb.append("   JOIN tarifa tar ON (tar.ruta_id = c.ruta_id");
		sb.append("                       AND tar.marca_id = c.marca_id");
		sb.append("                       AND tar.claseservicio_id = c.claseservicio_id");
		sb.append("                       AND tar.vigenciatarifa_id = vt.vigenciatarifa_id");
		sb.append("                       AND tar.origen_id = c.origen_id");
		sb.append("                       AND tar.destino_id = c.destino_id and tar.activo = 1)");
		sb.append("   JOIN marca m on m.marca_id = c.marca_id");
		sb.append("   JOIN empresa e on e.empresa_id = m.empresa_id");
		sb.append("   JOIN orgao_concedente og ON og.orgaoconcedente_id = tar.orgaoconcedente_id");
		sb.append("   LEFT JOIN bpe bpe on bpe.boleto_id = c.transacao_id ");
		sb.append("   LEFT JOIN cambio_titularidad ct on ct.boleto_id = c.transacao_id ");
		sb.append("   LEFT JOIN AIDF AIDF ON AIDF.AIDF_ID = c.AIDF_ID ");
		sb.append("   left join bpe bpe on bpe.boleto_id = c.transacao_id ");
		
		sb.append("   left join caja c_ori on c_ori.transacao_id = c.transacaooriginal_id ");
		sb.append("   left join caja c_ant on c_ant.transacao_id = c.transacaoanterior_id ");
		sb.append("   left join caja c_prox on c_prox.transacaoanterior_id = c.transacao_id ");
		
		sb.append("   left join aidf aidf_ori ON aidf_ori.AIDF_ID = c_ori.AIDF_ID ");
		sb.append("   left join aidf aidf_ant ON aidf_ant.AIDF_ID = c_ant.AIDF_ID ");
		sb.append("   left join aidf aidf_prox ON aidf_prox.AIDF_ID = c_prox.AIDF_ID ");
		
		sb.append("   left join bpe bpe_ori on bpe_ori.boleto_id = c_ori.transacao_id ");
		sb.append("   WHERE 1=1  ");
		sb.append("   and c.motivoreimpresion_id is null ");
		sb.append("   and (c.motivocancelacion_id IN (");
		sb.append(carregarMotivosCancelacion(mcAlteracaoPoltrona));
		sb.append(") OR c.motivocancelacion_id IS NULL) ");
		sb.append(" AND (c.indreimpresion = 0 ");
		sb.append(" 	 OR (c.indstatusboleto IN ('E','T') AND c.indreimpresion = 1) ");
		sb.append(" 	 OR (c.indstatusboleto = 'C' AND c.motivocancelacion_id = 27) ");
		sb.append(" 	 OR (c.indstatusboleto = 'C' AND c.motivocancelacion_id = 23) ");

		if (mcAlteracaoPoltrona != null) {
			sb.append(" OR (c.indstatusboleto = 'C' AND c.indreimpresion = 1 AND c.motivocancelacion_id = :mcAlteracaoPoltrona) ");
		}

		sb.append(" ) ");
		
		if (fecInicioViagem != null && fecFinalViagem != null) {
			sb.append("AND c.feccorrida BETWEEN TO_DATE(:fecInicioViagem,'dd/mm/yyyy hh24:mi') AND TO_DATE(:fecFinalViagem,'dd/mm/yyyy hh24:mi') ");
		}

		if (fecInicioVenda != null && fecFinalVenda != null) {
			sb.append("AND c.fechorventa BETWEEN TO_DATE(:fecInicioVenda,'dd/mm/yyyy hh24:mi') AND TO_DATE(:fecFinalVenda,'dd/mm/yyyy hh24:mi') ");
		}

		if (empresa_id != null) {
			sb.append("AND e.empresa_id = :empresa_id ");
		}

		if (agencia_id != null && !agencia_id.equals(-1)) {
			sb.append("AND c.puntoventa_id = :puntoventa_id ");
		}

		if (ruta_id != null && !ruta_id.equals(-1)) {
			sb.append("AND c.ruta_id = :ruta_id ");
		}

		if (origem_id != null && !origem_id.equals(-1)) {
			sb.append("AND ori.parada_id = :origem_id ");
		}

		if (destino_id != null && !destino_id.equals(-1)) {
			sb.append("AND des.parada_id = :destino_id ");
		}

		if (categoria_id != null && !categoria_id.isEmpty()) {
			sb.append("AND ca.categoria_id in (" + categoria_id + ") ");
		}

		if (orgaoConcedente_id != null && !orgaoConcedente_id.equals(-1)) {
			sb.append("AND r.orgaoconcedente_id = :orgao_concedente_id ");
		}

		sb.append(") ");
		sb.append("ORDER BY 5, 15");
		
		return sb.toString();
	}
	
	private String carregarMotivosCancelacion(Integer mcAlteracaoPoltrona) {
		List<Integer> motivosCancelacion = new ArrayList<Integer>();
		motivosCancelacion.add(31);
		motivosCancelacion.add(32);
		motivosCancelacion.add(37);
		motivosCancelacion.add(10);
		motivosCancelacion.add(27);
		motivosCancelacion.add(23);
		
		if(mcAlteracaoPoltrona != null) {
			motivosCancelacion.add(mcAlteracaoPoltrona);
		}
		
		return motivosCancelacion.toString().replaceAll("[\\[\\]]", "");
	}

	private boolean isPossuiElemento(List<String> lista, String elemento) {
		return lista != null && elemento != null && lista.contains(elemento);
	}
}