package com.rjconsultores.ventaboletos.dao.hibernate;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.rjconsultores.ventaboletos.dao.SisdapDAO;
import com.rjconsultores.ventaboletos.entidad.Categoria;
import com.rjconsultores.ventaboletos.relatorios.MovimentoLinha;
import com.rjconsultores.ventaboletos.relatorios.MovimentoSecoes;
import com.rjconsultores.ventaboletos.relatorios.PrefixoAntt;

@Repository("sisdapDAO")
public class SisdapHibernateDAO implements SisdapDAO {

	private static String HYPHEN = "-";
	private static final Logger log = LogManager.getLogger(SisdapHibernateDAO.class);
	
	@Autowired
	private DataSource dataSourceRead;

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public List<String> getMovimentoLinhas(Date fecInicio, Date fecFinal, Integer empresaId) {

		List<MovimentoLinha> list = consultaMovimentoLinhas(fecInicio, fecFinal, empresaId);

		List<MovimentoLinha> result = new ArrayList<MovimentoLinha>();

		for (MovimentoLinha movimentoLinha : list) {
			boolean insert = agrupaMovimentoLinhas(result, movimentoLinha);
			if (insert)
				result.add(movimentoLinha);
		}

		List<String> periodos = new ArrayList<String>();
		for (MovimentoLinha movimentoLinha : result) {
			String periodo = movimentoLinha.getAno() + HYPHEN + movimentoLinha.getMes();
			if (!periodos.contains(periodo)) {
				periodos.add(periodo);
			}
		}

		List<PrefixoAntt> prefixos = buscaPrefixoEmpresa(empresaId);

		HashMap<String, List<PrefixoAntt>> periodosPrefixos = new HashMap<String, List<PrefixoAntt>>();
		for (String pd : periodos) {
			periodosPrefixos.put(pd, prefixos);
		}

		for (MovimentoLinha movimentoLinha : result) {
			String periodo = movimentoLinha.getAno() + HYPHEN + movimentoLinha.getMes();

			PrefixoAntt prefixoAntt = new PrefixoAntt();
			prefixoAntt.setAntt(movimentoLinha.getAntt());
			prefixoAntt.setPrefixo(movimentoLinha.getPrefixo());

			if (periodosPrefixos.get(periodo).contains(prefixoAntt)) {
				periodosPrefixos.get(periodo).remove(prefixoAntt);
			}
		}

		for (String key : periodosPrefixos.keySet()) {
			String[] periodo = key.split(HYPHEN);
			Integer ano = Integer.parseInt(periodo[0]);
			Integer mes = Integer.parseInt(periodo[1]);

			for (PrefixoAntt prefixoAntt : periodosPrefixos.get(key)) {
				MovimentoLinha linha = new MovimentoLinha();
				linha.setAno(ano);
				linha.setMes(mes);
				linha.setAntt(prefixoAntt.getAntt());
				linha.setPrefixo(prefixoAntt.getPrefixo());
				linha.setLugaresIda(NumberUtils.INTEGER_ZERO);
				linha.setLugaresVolta(NumberUtils.INTEGER_ZERO);
				linha.setViagensIda(NumberUtils.INTEGER_ZERO);
				linha.setViagensVolta(NumberUtils.INTEGER_ZERO);

				result.add(linha);
			}
		}

		Collections.sort(result, new Comparator() {
			public int compare(Object o1, Object o2) {
				MovimentoLinha c1 = (MovimentoLinha) o1;
				MovimentoLinha c2 = (MovimentoLinha) o2;

				int result = c1.getAno().compareTo(c2.getAno());
				if (result == 0) {
					result = c1.getMes().compareTo(c2.getMes());
				}
				if (result == 0) {
					result = c1.getAntt().compareToIgnoreCase(c2.getAntt());
				}
				if (result == 0) {
					return c1.getPrefixo().compareToIgnoreCase(c2.getPrefixo());
				}
				return result;
			}
		});

		List<String> movimentoLinhas = new ArrayList<String>();
		movimentoLinhas.add("empresa;prefixo;mes;ano;viagem_ida;viagem_volta;lugar_ida;lugar_volta");
		for (MovimentoLinha movimentoLinha : result) {
			movimentoLinhas.add(movimentoLinha.toString());
		}

		return movimentoLinhas;
	}

	private List<MovimentoLinha> consultaMovimentoLinhas(Date fecInicio, Date fecFinal, Integer empresaId) {

		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
		StringBuilder sb = new StringBuilder();
		sb.append("select e.codantt antt, r.prefixo prefixo, ");
		sb.append("       to_char(c.feccorrida, 'MM') mes, to_char(c.feccorrida, 'yyyy') ano, ");
		sb.append("       nvl(case r.indsentidoida when 1 then count(r.prefixo) end, 0) viagensida, ");
		sb.append("       nvl(case r.indsentidoida when 0 then count(r.prefixo) end, 0) viagensvolta, ");
		sb.append("       nvl(case r.indsentidoida when 1 then sum(da.cantasientos) end, 0) lugaresida, ");
		sb.append("       nvl(case r.indsentidoida when 0 then sum(da.cantasientos) end, 0) lugaresvolta ");
		sb.append("from ruta_empresa re ");
		sb.append("     left join empresa e on e.empresa_id = re.empresa_id ");
		sb.append("     left join ruta r on re.ruta_id = r.ruta_id ");
		sb.append("     left join corrida c on c.ruta_id = r.ruta_id ");
		sb.append("     left outer join rol_operativo ro on c.roloperativo_id = ro.roloperativo_id ");
		sb.append("     left outer join diagrama_autobus da on da.diagramaautobus_id = ro.diagramaautobus_id ");
		sb.append("where e.empresa_id = ? and re.activo = 1 and r.activo = 1 and e.activo = 1 ");
		sb.append("      and r.orgaoconcedente_id = 3  and e.codantt is not null ");
		sb.append("      and c.feccorrida between to_date(?, 'DD/MM/YYYY') and ");
		sb.append("                               to_date(?, 'DD/MM/YYYY') ");
		sb.append("group by e.codantt, r.prefixo, r.indsentidoida, ");
		sb.append("          to_char(c.feccorrida, 'MM'), to_char(c.feccorrida, 'yyyy') ");
		sb.append("order by mes,  ano,  e.codantt, r.prefixo, viagensida, viagensvolta ");

		QueryRunner queryRunner = new QueryRunner(dataSourceRead);
		ResultSetHandler<List<MovimentoLinha>> handler = new BeanListHandler<MovimentoLinha>(MovimentoLinha.class);											
		List<MovimentoLinha> returnedList = new ArrayList<MovimentoLinha>();
		
		try {
			returnedList = queryRunner.query(sb.toString(), handler, empresaId, sdf.format(fecInicio), sdf.format(fecFinal));
		} catch (SQLException e) {
			log.error("",e);
		}
		
		return returnedList;
	}

	private List<PrefixoAntt> buscaPrefixoEmpresa(Integer empresaId) {

		StringBuilder sb = new StringBuilder();
		sb.append(" select e.codantt antt, r.prefixo prefixo ");
		sb.append(" from ruta_empresa re ");
		sb.append("     left join marca m on m.empresa_id = re.empresa_id ");
		sb.append("     left join empresa e on m.empresa_id = e.empresa_id ");
		sb.append("     left join ruta r on re.ruta_id = r.ruta_id ");
		sb.append(" where re.empresa_id = ? and r.orgaoconcedente_id = 3 ");
		sb.append("       and re.activo = 1 and r.activo = 1 and e.activo = 1 ");
		sb.append(" group by e.codantt, r.prefixo ");
		sb.append(" order by e.codantt, r.prefixo ");
		
		
		QueryRunner queryRunner = new QueryRunner(dataSourceRead, true);
		ResultSetHandler<List<PrefixoAntt>> handler = new BeanListHandler<PrefixoAntt>(PrefixoAntt.class);											
		List<PrefixoAntt> returnedList = new ArrayList<PrefixoAntt>();
		
		try {
			returnedList = queryRunner.query(sb.toString(), handler, empresaId);
		} catch (SQLException e) {
			log.error("",e);
		}

		return returnedList;
	}

	private boolean agrupaMovimentoLinhas(List<MovimentoLinha> resul, MovimentoLinha movimentoLinha) {

		if (resul.isEmpty()) {
			return true;
		} else {
			for (MovimentoLinha ml : resul) {
				if (ml.getPrefixo().equals(movimentoLinha.getPrefixo()) && ml.getMes().equals(movimentoLinha.getMes())
						&& ml.getAno().equals(movimentoLinha.getAno())) {

					if (movimentoLinha.getViagensVolta() > 0) {
						ml.setLugaresVolta(movimentoLinha.getLugaresVolta());
						ml.setViagensVolta(movimentoLinha.getViagensVolta());
					}

					if (movimentoLinha.getViagensIda() > 0) {
						ml.setLugaresIda(movimentoLinha.getLugaresIda());
						ml.setViagensIda(movimentoLinha.getViagensIda());
					}
					return false;
				}
			}
		}

		return true;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public List<String> getMovimentoSecoes(Date fecInicio, Date fecFinal, Integer empresaId, List<Object>  pesquisaGratuidade, List<Object> pesquisaGratuidadeIdoso, List<Object> pesquisaDescontoIdoso, List<Object> pesquisaDescontoJovem, List<Object> pesquisaGratuidadeJovem) {		
		List<MovimentoSecoes> listResultConsulta = consultaMovimentoSecoes(fecInicio, fecFinal, empresaId, pesquisaGratuidade, pesquisaDescontoIdoso, pesquisaGratuidadeIdoso, pesquisaDescontoJovem, pesquisaGratuidadeJovem);
		List<MovimentoSecoes> listResultIdaVoltaInvertida = new ArrayList<MovimentoSecoes>();
		List<MovimentoSecoes> listVoltasSemIda = new ArrayList<MovimentoSecoes>();
			
		for (MovimentoSecoes ms : listResultConsulta) {
			
			Boolean achou = Boolean.FALSE;
			if(isIda(ms)) {
				for (MovimentoSecoes ms2 : listResultConsulta) {
					if(ms != null && ms2 != null && ms.getLocalOrigem() != null && ms2.getLocalOrigem() != null &&
							ms.getLocalOrigem().equals(ms2.getLocalDestino()) && ms2.getLocalOrigem().equals(ms.getLocalDestino()) && !isIda(ms2) && ms2.getPrefixo().equals(ms.getPrefixo())) {
						ms.setDescontoIdosoVolta(ms2.getDescontoIdosoVolta());
						ms.setGratuidadeIdosoVolta(ms2.getGratuidadeIdosoVolta());
						ms.setGratuidadePasseLivreVolta(ms2.getGratuidadePasseLivreVolta());
						ms.setPassageirosVolta(ms2.getPassageirosVolta());
						ms.setGratuidadeJovenVolta(ms2.getGratuidadeJovenVolta());
						ms.setDescontoJovenVolta(ms2.getGratuidadeJovenVolta());
						ms.setDescontoJovenVolta(ms2.getGratuidadeJovenVolta());
						listResultIdaVoltaInvertida.add(ms);
						achou = Boolean.TRUE;
						break;
					}
				}
			
				if(!achou) {
					listResultIdaVoltaInvertida.add(ms);
				}
			 } else {
				 listVoltasSemIda.add(ms);
			 }
		}
		
		for (MovimentoSecoes volta : listVoltasSemIda) {
			
			Boolean achou = Boolean.FALSE;
			
			for (MovimentoSecoes idaVolta : listResultIdaVoltaInvertida) {
				if(idaVolta != null && idaVolta.getLocalOrigem() != null && volta != null && volta.getLocalOrigem() != null && volta.getPrefixo() != null &&
						idaVolta.getLocalOrigem().equals(volta.getLocalDestino()) && volta.getLocalOrigem().equals(idaVolta.getLocalDestino()) && volta.getPrefixo().equals(idaVolta.getPrefixo())) {
					achou = Boolean.TRUE;
					break;
				}
			}
			
			if(!achou) {
				String origem = volta.getLocalOrigem();
				String destino = volta.getLocalDestino();
			
				volta.setLocalDestino(origem);
				volta.setLocalOrigem(destino);
				listResultIdaVoltaInvertida.add(volta);
			}
		}
		
		List<String> periodos = new ArrayList<String>();
		for (MovimentoSecoes ms : listResultIdaVoltaInvertida) {
			String periodo = ms.getAno() + HYPHEN + ms.getMes();
			if (!periodos.contains(periodo)) {
				periodos.add(periodo);
			}
		}

		List<PrefixoAntt> prefixos = buscaPrefixoEmpresaOrigenDestino(empresaId);

		HashMap<String, List<PrefixoAntt>> periodosPrefixos = new HashMap<String, List<PrefixoAntt>>();
		for (String pd : periodos) {
			periodosPrefixos.put(pd, prefixos);
		}

		for (MovimentoSecoes ms : listResultIdaVoltaInvertida) {
			String periodo = ms.getAno() + HYPHEN + ms.getMes();

			PrefixoAntt prefixoAntt = new PrefixoAntt();
			prefixoAntt.setAntt(ms.getAntt());
			prefixoAntt.setPrefixo(ms.getPrefixo());
			prefixoAntt.setLocalDestino(ms.getLocalDestino());
			prefixoAntt.setLocalOrigem(ms.getLocalOrigem());

			if (periodosPrefixos.get(periodo).contains(prefixoAntt)) {
				periodosPrefixos.get(periodo).remove(prefixoAntt);
			}
		}
		
		for (String key : periodosPrefixos.keySet()) {
			String[] periodo = key.split(HYPHEN);
			Integer ano = Integer.parseInt(periodo[0]);
			Integer mes = Integer.parseInt(periodo[1]);

			for (PrefixoAntt prefixoAntt : periodosPrefixos.get(key)) {
				MovimentoSecoes ms = new MovimentoSecoes();
				ms.setAno(ano);
				ms.setMes(mes);

				ms.setAntt(prefixoAntt.getAntt());
				ms.setPrefixo(prefixoAntt.getPrefixo());
				ms.setLocalDestino(prefixoAntt.getLocalDestino());
				ms.setLocalOrigem(prefixoAntt.getLocalOrigem());

				ms.setDescontoIdosoIda(NumberUtils.INTEGER_ZERO);
				ms.setDescontoIdosoVolta(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadeIdosoIda(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadeIdosoVolta(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadeJovenIda(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadeJovenVolta(NumberUtils.INTEGER_ZERO);
				ms.setDescontoJovenIda(NumberUtils.INTEGER_ZERO);
				ms.setDescontoJovenVolta(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadePasseLivreIda(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadePasseLivreVolta(NumberUtils.INTEGER_ZERO);
				ms.setPassageirosIda(NumberUtils.INTEGER_ZERO);
				ms.setPassageirosVolta(NumberUtils.INTEGER_ZERO);

				listResultIdaVoltaInvertida.add(ms);
			}
		}

		Collections.sort(listResultIdaVoltaInvertida, new Comparator() {
			public int compare(Object o1, Object o2) {
				MovimentoSecoes c1 = (MovimentoSecoes) o1;
				MovimentoSecoes c2 = (MovimentoSecoes) o2;

				int result = c1.getAno().compareTo(c2.getAno());
				if (result == 0) {
					result = c1.getMes().compareTo(c2.getMes());
				}
				if (result == 0) {
					result = c1.getAntt().compareToIgnoreCase(c2.getAntt());
				}
				if (result == 0) {
					return c1.getPrefixo().compareToIgnoreCase(c2.getPrefixo());
				}
				if (result == 0) {
					return c1.getLocalOrigem().compareToIgnoreCase(c2.getLocalOrigem());
				}
				if (result == 0) {
					return c1.getLocalDestino().compareToIgnoreCase(c2.getLocalDestino());
				}
				return result;
			}
		});

		List<String> movimentosSecoes = new ArrayList<String>();
		movimentosSecoes.add("empresa;prefixo;local_origem;local_destino;mes;ano;passageiro_ida;passageiro_volta;gratuidade_ida;gratuidade_volta;idoso_ida;idoso_volta;desconto_ida;desconto_volta;gratuidade_jovem_ida;gratuidade_jovem_volta;gratuidade_jovem_desconto_ida;gratuidade_jovem_desconto_volta");

		for (MovimentoSecoes ms : listResultIdaVoltaInvertida) {
			movimentosSecoes.add(ms.toStringSisdap());
		}

		return movimentosSecoes;
	}

	private boolean isIda(MovimentoSecoes ms) {				
		Integer somaVolta = (ms.getDescontoIdosoVolta() + ms.getGratuidadeIdosoVolta() + ms.getGratuidadePasseLivreVolta() + ms.getPassageirosVolta());
		Integer somaIda   = (ms.getDescontoIdosoIda()   + ms.getGratuidadeIdosoIda()   + ms.getGratuidadePasseLivreIda()   + ms.getPassageirosIda());
		return (somaVolta.intValue() == 0) && (somaIda.intValue() > 0);
	}

	private List<MovimentoSecoes> consultaMovimentoSecoes(Date fecInicio, Date fecFinal, Integer empresaId, List<Object> pesquisaGratuidade, List<Object> pesquisaDescontoIdoso, List<Object> pesquisaGratuidadeIdoso, List<Object> pesquisaDescontoJovem, List<Object> pesquisaGratuidadeJovem) {

		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
		
		String gratuidade = "";
		for (Object categoria : pesquisaGratuidade) {
			gratuidade += ((Categoria) categoria).getCategoriaId() + ",";
		}
		gratuidade = gratuidade.substring(0, gratuidade.length()-1);
		
		String gratuidadeIdoso = "";
		for (Object categoria : pesquisaGratuidadeIdoso) {
			gratuidadeIdoso += ((Categoria) categoria).getCategoriaId() + ",";
		}
		gratuidadeIdoso = gratuidadeIdoso.substring(0, gratuidadeIdoso.length()-1);
		
		String descontoIdoso = "";
		for (Object categoria : pesquisaDescontoIdoso) {
			descontoIdoso += ((Categoria) categoria).getCategoriaId() + ",";
		}
		descontoIdoso = descontoIdoso.substring(0, descontoIdoso.length()-1);
		
		String gratuidadeJovem = "";
		for (Object categoria : pesquisaGratuidadeJovem) {
			gratuidadeJovem += ((Categoria) categoria).getCategoriaId() + ",";
		}
		gratuidadeJovem = gratuidadeJovem.substring(0, gratuidadeJovem.length()-1);
		
		String descontoJovem = "";
		for (Object categoria : pesquisaDescontoJovem) {
			descontoJovem += ((Categoria) categoria).getCategoriaId() + ",";
		}
		descontoJovem = descontoJovem.substring(0, descontoJovem.length()-1);
		
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT subAlias.antt, ");
		sb.append("       subAlias.prefixo, ");
		sb.append("       subAlias.mes, ");
		sb.append("       subAlias.ano, ");
		sb.append("       po.codantt localOrigem, ");
		sb.append("       pd.codantt localDestino, ");
		sb.append("       sum(subAlias.passageirosida) as passageirosida, ");
		sb.append("       sum(subAlias.passageirosvolta) as passageirosvolta, ");
		sb.append("       sum(subAlias.gratuidadepasselivreida) as gratuidadepasselivreida, ");
		sb.append("       sum(subAlias.gratuidadepasselivrevolta) as gratuidadepasselivrevolta, ");
		sb.append("       sum(subAlias.gratuidadeidosoida) as gratuidadeidosoida, ");
		sb.append("       sum(subAlias.gratuidadeidosovolta) as gratuidadeidosovolta, ");
		sb.append("       sum(subAlias.descontoidosoida) as descontoidosoida, ");
		sb.append("       sum(subAlias.descontoidosovolta) as descontoidosovolta, ");
		
		sb.append("       sum(subAlias.gratuidadejovenida) as gratuidadejovenida, ");
		sb.append("       sum(subAlias.gratuidadejovenvolta) as gratuidadejovenvolta, ");
		sb.append("       sum(subAlias.descontojovenida) as descontojovenida, ");
		sb.append("       sum(subAlias.descontojovenvolta) as descontojovenvolta ");
		
		sb.append("FROM   (SELECT subResp.antt                                   antt, ");
		sb.append("               subResp.prefixo                                prefixo, ");
		sb.append("               subResp.mes                                    mes, ");
		sb.append("               subResp.ano                                    ano, ");
		sb.append("               coalesce(ase.aliasorigen_id, subResp.localorigem)   aliasorigen, ");
		sb.append("               coalesce(ase.aliasdestino_id, subResp.localdestino) aliasdestino, ");
		sb.append("               subResp.passageirosida                    passageirosida, ");
		sb.append("               subResp.passageirosvolta                  passageirosvolta, ");
		sb.append("               subResp.gratuidadepasselivreida 			 gratuidadepasselivreida, ");
		sb.append("               subResp.gratuidadepasselivrevolta 		 gratuidadepasselivrevolta, ");
		sb.append("               subResp.gratuidadeidosoida 				 gratuidadeidosoida, ");
		sb.append("               subResp.gratuidadeidosovolta				 gratuidadeidosovolta, ");
		sb.append("               subResp.descontoidosoida                  descontoidosoida, ");
		sb.append("               subResp.descontoidosovolta                descontoidosovolta, ");
		
		sb.append("               subResp.gratuidadejovenida 				 gratuidadejovenida, ");
		sb.append("               subResp.gratuidadejovenvolta				 gratuidadejovenvolta, ");
		sb.append("               subResp.descontojovenida                  descontojovenida, ");
		sb.append("               subResp.descontojovenvolta                descontojovenvolta ");
		
		sb.append("        FROM   (SELECT distinct r.ruta_id 			ruta_id, ");
		sb.append("						  e.codantt           	 		antt, ");
		sb.append("                       r.prefixo                     prefixo, ");
		sb.append("                       To_char(c.feccorrida, 'MM')   mes, ");
		sb.append("                       To_char(c.feccorrida, 'yyyy') ano, ");
		sb.append("                       po.parada_id localorigem, ");
		sb.append("                       pd.parada_id localdestino, ");
		
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN (SELECT categoria_id FROM   categoria WHERE grupocategoria_id IS NULL) THEN Count(*) END, 0) passageirosida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN (SELECT categoria_id FROM   categoria WHERE grupocategoria_id IS NULL) THEN Count(*) END, 0) passageirosvolta, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN ( " + gratuidade + " ) THEN Count(*) END, 0) gratuidadepasselivreida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN ( " + gratuidade + " ) THEN Count(*) END, 0) gratuidadepasselivrevolta, ");
		
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN ( " + gratuidadeIdoso + " ) THEN Count(*) END, 0) gratuidadeidosoida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN ( " + gratuidadeIdoso + " ) THEN Count(*) END, 0) gratuidadeidosovolta, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN ( " + descontoIdoso + " ) THEN Count(*) END, 0) descontoidosoida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN ( " + descontoIdoso + " ) THEN Count(*) END, 0) descontoidosovolta, ");
		
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN ( " + gratuidadeJovem + " ) THEN Count(*) END, 0) gratuidadejovenida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN ( " + gratuidadeJovem + " ) THEN Count(*) END, 0) gratuidadejovenvolta, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN ( " + descontoJovem + " ) THEN Count(*) END, 0) descontojovenida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN ( " + descontoJovem + " ) THEN Count(*) END, 0) descontojovenvolta ");
		
		sb.append("                FROM   ruta_empresa re ");
		sb.append("                       left join empresa 	  e ON e.empresa_id = re.empresa_id ");
		sb.append("                       left join ruta 		  r ON re.ruta_id 	= r.ruta_id ");
		sb.append("                       left join corrida 	  c ON c.ruta_id 	= r.ruta_id ");
		sb.append("                       left outer join boleto  b ON c.corrida_id = b.corrida_id AND c.feccorrida = b.feccorrida ");
		sb.append("                       left outer join parada po ON po.parada_id = b.origen_id ");
		sb.append("                       left outer join parada pd ON pd.parada_id = b.destino_id ");
		
		sb.append("                WHERE  e.empresa_id = ?  ");
		sb.append("                       AND re.activo = 1 ");
		sb.append("                       AND r.activo = 1 ");
		sb.append("                       AND e.activo = 1 ");
		sb.append("                       AND r.orgaoconcedente_id = 3 ");
		sb.append("                       AND b.numasiento IS NOT NULL ");
		sb.append("                       AND b.motivocancelacion_id IS NULL ");
		sb.append("                       AND b.indstatusoperacion = 'F' ");
		sb.append("                       AND b.activo = 1 ");
		sb.append("                       AND e.codantt IS NOT NULL ");
		sb.append("                       AND c.feccorrida BETWEEN To_date(?, 'dd/MM/yyyy') AND To_date (?, 'dd/MM/yyyy') ");
		sb.append("						  AND b.categoria_id <> (select valorconstante from constante where NOMBCONSTANTE = 'GRATUIDADE_CRIANCA')");
		sb.append("                GROUP  BY e.codantt, ");
		sb.append("                          r.prefixo, ");
		sb.append("                          To_char(c.feccorrida, 'MM'), ");
		sb.append("                          To_char(c.feccorrida, 'yyyy'), ");
		sb.append("                          po.parada_id, ");
		sb.append("                          pd.parada_id, ");
		sb.append("                          r.indsentidoida, ");
		sb.append("                          b.categoria_id, ");
		sb.append(" 						 r.ruta_id ");
		sb.append( "				ORDER BY e.codantt, ");
		sb.append( "					     r.prefixo) subResp ");
				
		sb.append("               left join alias_servico ase ON ( subResp.localorigem = ase.origen_id AND subResp.localdestino = ase.destino_id  and ase.ruta_id = subResp.ruta_id and ase.activo = 1) ");
		
		sb.append( " ORDER BY subResp.antt,");
		sb.append( " subResp.prefixo");
		sb.append( " ) subAlias");
		
		sb.append("       inner join parada po ON ( subAlias.aliasorigen = po.parada_id ) ");
		sb.append("       inner join parada pd ON ( subAlias.aliasdestino = pd.parada_id ) ");		
		sb.append("GROUP  BY mes, ");
		sb.append("          ano, ");
		sb.append("          antt, ");
		sb.append("          prefixo, ");
		sb.append("          po.codantt, ");
		sb.append("          pd.codantt ");
		
		sb.append("ORDER  BY mes, ");
		sb.append("          ano, ");
		sb.append("          antt, ");
		sb.append("          prefixo, ");
		sb.append("          localOrigem, ");
		sb.append("          localDestino ");
		
		QueryRunner queryRunner = new QueryRunner(dataSourceRead, true);
		ResultSetHandler<List<MovimentoSecoes>> handler = new BeanListHandler<MovimentoSecoes>(MovimentoSecoes.class);											
		List<MovimentoSecoes> returnedList = new ArrayList<MovimentoSecoes>();
		
		try {
			returnedList = queryRunner.query(sb.toString(), handler, empresaId, sdf.format(fecInicio), sdf.format(fecFinal));
			
		} catch (SQLException e) {
			log.error("",e);
		}	
		
		return returnedList;
	}
	
	private List<MovimentoSecoes> consultaMovimentoSecoes(Date fecInicio, Date fecFinal, Integer empresaId, List<Object> pesquisaGratuidade, List<Object> pesquisaDescontoIdoso, List<Object> pesquisaGratuidadeIdoso, List<Object> pesquisaDescontoJovem, List<Object> pesquisaGratuidadeJovem, List<Object> pesquisaGratuidadeEstudante, List<Object> pesquisaGratuidadeProfessor) {

		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
		
		String gratuidade = "";
		for (Object categoria : pesquisaGratuidade) {
			gratuidade += ((Categoria) categoria).getCategoriaId() + ",";
		}
		gratuidade = gratuidade.substring(0, gratuidade.length()-1);
		
		String gratuidadeIdoso = "";
		for (Object categoria : pesquisaGratuidadeIdoso) {
			gratuidadeIdoso += ((Categoria) categoria).getCategoriaId() + ",";
		}
		gratuidadeIdoso = gratuidadeIdoso.substring(0, gratuidadeIdoso.length()-1);
		
		String descontoIdoso = "";
		for (Object categoria : pesquisaDescontoIdoso) {
			descontoIdoso += ((Categoria) categoria).getCategoriaId() + ",";
		}
		descontoIdoso = descontoIdoso.substring(0, descontoIdoso.length()-1);
		
		String gratuidadeJovem = "";
		for (Object categoria : pesquisaGratuidadeJovem) {
			gratuidadeJovem += ((Categoria) categoria).getCategoriaId() + ",";
		}
		gratuidadeJovem = gratuidadeJovem.substring(0, gratuidadeJovem.length()-1);
		
		String descontoJovem = "";
		for (Object categoria : pesquisaDescontoJovem) {
			descontoJovem += ((Categoria) categoria).getCategoriaId() + ",";
		}
		descontoJovem = descontoJovem.substring(0, descontoJovem.length()-1);
		
		String gratuidadeProfessor = "";
		for (Object categoria : pesquisaGratuidadeProfessor) {
			gratuidadeProfessor += ((Categoria) categoria).getCategoriaId() + ",";
		}
		gratuidadeProfessor = gratuidadeProfessor.substring(0, gratuidadeProfessor.length()-1);
		
		String gratuidadeEstudante = "";
		for (Object categoria : pesquisaGratuidadeEstudante) {
			gratuidadeEstudante += ((Categoria) categoria).getCategoriaId() + ",";
		}
		gratuidadeEstudante = gratuidadeEstudante.substring(0, gratuidade.length()-1);
		
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT subAlias.antt, ");
		sb.append("       subAlias.prefixo, ");
		sb.append("       subAlias.mes, ");
		sb.append("       subAlias.ano, ");
		sb.append("       po.codantt localOrigem, ");
		sb.append("       pd.codantt localDestino, ");
		sb.append("       sum(subAlias.passageirosida) as passageirosida, ");
		sb.append("       sum(subAlias.passageirosvolta) as passageirosvolta, ");
		sb.append("       sum(subAlias.gratuidadepasselivreida) as gratuidadepasselivreida, ");
		sb.append("       sum(subAlias.gratuidadepasselivrevolta) as gratuidadepasselivrevolta, ");
		sb.append("       sum(subAlias.gratuidadeidosoida) as gratuidadeidosoida, ");
		sb.append("       sum(subAlias.gratuidadeidosovolta) as gratuidadeidosovolta, ");
		sb.append("       sum(subAlias.descontoidosoida) as descontoidosoida, ");
		sb.append("       sum(subAlias.descontoidosovolta) as descontoidosovolta, ");
		
		sb.append("       sum(subAlias.gratuidadejovenida) as gratuidadejovenida, ");
		sb.append("       sum(subAlias.gratuidadejovenvolta) as gratuidadejovenvolta, ");
		sb.append("       sum(subAlias.descontojovenida) as descontojovenida, ");
		sb.append("       sum(subAlias.descontojovenvolta) as descontojovenvolta, ");
		
		sb.append("       sum(subAlias.gratuidadeestudanteida)   as gratuidadeestudanteida, ");
		sb.append("       sum(subAlias.gratuidadeestudantevolta) as gratuidadeestudantevolta, ");
		sb.append("       sum(subAlias.gratuidadeprofessorida)   as gratuidadeprofessorida, ");
		sb.append("       sum(subAlias.gratuidadeprofessorvolta) as gratuidadeprofessorvolta ");
		
		
		
		sb.append("FROM   (SELECT subResp.antt                                   antt, ");
		sb.append("               subResp.prefixo                                prefixo, ");
		sb.append("               subResp.mes                                    mes, ");
		sb.append("               subResp.ano                                    ano, ");
		sb.append("               coalesce(ase.aliasorigen_id, subResp.localorigem)   aliasorigen, ");
		sb.append("               coalesce(ase.aliasdestino_id, subResp.localdestino) aliasdestino, ");
		sb.append("               subResp.passageirosida                    passageirosida, ");
		sb.append("               subResp.passageirosvolta                  passageirosvolta, ");
		sb.append("               subResp.gratuidadepasselivreida 			 gratuidadepasselivreida, ");
		sb.append("               subResp.gratuidadepasselivrevolta 		 gratuidadepasselivrevolta, ");
		sb.append("               subResp.gratuidadeidosoida 				 gratuidadeidosoida, ");
		sb.append("               subResp.gratuidadeidosovolta				 gratuidadeidosovolta, ");
		sb.append("               subResp.descontoidosoida                  descontoidosoida, ");
		sb.append("               subResp.descontoidosovolta                descontoidosovolta, ");
		
		sb.append("               subResp.gratuidadejovenida 				 gratuidadejovenida, ");
		sb.append("               subResp.gratuidadejovenvolta				 gratuidadejovenvolta, ");
		sb.append("               subResp.descontojovenida                  descontojovenida, ");
		sb.append("               subResp.descontojovenvolta                descontojovenvolta, ");
		
		sb.append("               subResp.gratuidadeestudanteida 				 gratuidadeestudanteida, ");
		sb.append("               subResp.gratuidadeestudantevolta				 gratuidadeestudantevolta, ");
		sb.append("               subResp.gratuidadeprofessorida 				 gratuidadeprofessorida, ");
		sb.append("               subResp.gratuidadeprofessorvolta				 gratuidadeprofessorvolta ");
		
		sb.append("        FROM   (SELECT distinct r.ruta_id 			ruta_id, ");
		sb.append("						  e.codantt           	 		antt, ");
		sb.append("                       r.prefixo                     prefixo, ");
		sb.append("                       To_char(c.feccorrida, 'MM')   mes, ");
		sb.append("                       To_char(c.feccorrida, 'yyyy') ano, ");
		sb.append("                       po.parada_id localorigem, ");
		sb.append("                       pd.parada_id localdestino, ");
		
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN (SELECT categoria_id FROM   categoria WHERE grupocategoria_id IS NULL) THEN Count(*) END, 0) passageirosida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN (SELECT categoria_id FROM   categoria WHERE grupocategoria_id IS NULL) THEN Count(*) END, 0) passageirosvolta, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN ( " + gratuidade + " ) THEN Count(*) END, 0) gratuidadepasselivreida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN ( " + gratuidade + " ) THEN Count(*) END, 0) gratuidadepasselivrevolta, ");
		
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN ( " + gratuidadeIdoso + " ) THEN Count(*) END, 0) gratuidadeidosoida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN ( " + gratuidadeIdoso + " ) THEN Count(*) END, 0) gratuidadeidosovolta, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN ( " + descontoIdoso + " ) THEN Count(*) END, 0) descontoidosoida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN ( " + descontoIdoso + " ) THEN Count(*) END, 0) descontoidosovolta, ");
		
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN ( " + gratuidadeJovem + " ) THEN Count(*) END, 0) gratuidadejovenida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN ( " + gratuidadeJovem + " ) THEN Count(*) END, 0) gratuidadejovenvolta, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN ( " + descontoJovem + " ) THEN Count(*) END, 0) descontojovenida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN ( " + descontoJovem + " ) THEN Count(*) END, 0) descontojovenvolta, ");
		
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN ( " + gratuidadeEstudante + " ) THEN Count(*) END, 0) gratuidadeestudanteida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN ( " + gratuidadeEstudante + " ) THEN Count(*) END, 0) gratuidadeestudantevolta, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 1 AND b.categoria_id IN ( " + gratuidadeProfessor + " ) THEN Count(*) END, 0) gratuidadeprofessorida, ");
		sb.append("                       Nvl(CASE WHEN r.indsentidoida = 0 AND b.categoria_id IN ( " + gratuidadeProfessor + " ) THEN Count(*) END, 0) gratuidadeprofessorvolta ");
		
		
		sb.append("                FROM   ruta_empresa re ");
		sb.append("                       left join empresa 	  e ON e.empresa_id = re.empresa_id ");
		sb.append("                       left join ruta 		  r ON re.ruta_id 	= r.ruta_id ");
		sb.append("                       left join corrida 	  c ON c.ruta_id 	= r.ruta_id ");
		sb.append("                       left outer join boleto  b ON c.corrida_id = b.corrida_id AND c.feccorrida = b.feccorrida ");
		sb.append("                       left outer join parada po ON po.parada_id = b.origen_id ");
		sb.append("                       left outer join parada pd ON pd.parada_id = b.destino_id ");
		
		sb.append("                WHERE  e.empresa_id = ?  ");
		sb.append("                       AND re.activo = 1 ");
		sb.append("                       AND r.activo = 1 ");
		sb.append("                       AND e.activo = 1 ");
		sb.append("                       AND r.orgaoconcedente_id = 3 ");
		sb.append("                       AND b.numasiento IS NOT NULL ");
		sb.append("                       AND b.motivocancelacion_id IS NULL ");
		sb.append("                       AND b.indstatusoperacion = 'F' ");
		sb.append("                       AND b.activo = 1 ");
		sb.append("                       AND e.codantt IS NOT NULL ");
		sb.append("                       AND c.feccorrida BETWEEN To_date(?, 'dd/MM/yyyy') AND To_date (?, 'dd/MM/yyyy') ");
		sb.append("						  AND b.categoria_id <> (select valorconstante from constante where NOMBCONSTANTE = 'GRATUIDADE_CRIANCA')");
		sb.append("                GROUP  BY e.codantt, ");
		sb.append("                          r.prefixo, ");
		sb.append("                          To_char(c.feccorrida, 'MM'), ");
		sb.append("                          To_char(c.feccorrida, 'yyyy'), ");
		sb.append("                          po.parada_id, ");
		sb.append("                          pd.parada_id, ");
		sb.append("                          r.indsentidoida, ");
		sb.append("                          b.categoria_id, ");
		sb.append(" 						 r.ruta_id ");
		sb.append( "				ORDER BY e.codantt, ");
		sb.append( "					     r.prefixo) subResp ");
				
		sb.append("               left join alias_servico ase ON ( subResp.localorigem = ase.origen_id AND subResp.localdestino = ase.destino_id  and ase.ruta_id = subResp.ruta_id and ase.activo = 1) ");
		
		sb.append( " ORDER BY subResp.antt,");
		sb.append( " subResp.prefixo");
		sb.append( " ) subAlias");
		
		sb.append("       inner join parada po ON ( subAlias.aliasorigen = po.parada_id ) ");
		sb.append("       inner join parada pd ON ( subAlias.aliasdestino = pd.parada_id ) ");		
		sb.append("GROUP  BY mes, ");
		sb.append("          ano, ");
		sb.append("          antt, ");
		sb.append("          prefixo, ");
		sb.append("          po.codantt, ");
		sb.append("          pd.codantt ");
		
		sb.append("ORDER  BY mes, ");
		sb.append("          ano, ");
		sb.append("          antt, ");
		sb.append("          prefixo, ");
		sb.append("          localOrigem, ");
		sb.append("          localDestino ");
		QueryRunner queryRunner = new QueryRunner(dataSourceRead, true);
		ResultSetHandler<List<MovimentoSecoes>> handler = new BeanListHandler<MovimentoSecoes>(MovimentoSecoes.class);											
		List<MovimentoSecoes> returnedList = new ArrayList<MovimentoSecoes>();
		
		try {
			returnedList = queryRunner.query(sb.toString(), handler, empresaId, sdf.format(fecInicio), sdf.format(fecFinal));
			
		} catch (SQLException e) {
			log.error("",e);
		}
		
		return returnedList;
	}

	private List<PrefixoAntt> buscaPrefixoEmpresaOrigenDestino(Integer empresaId) {

		StringBuilder sb = new StringBuilder();

		sb.append(" SELECT DISTINCT ");
		sb.append("        subAlias.antt,  ");
		sb.append("        subAlias.prefixo,  ");
		sb.append("        CASE WHEN subAlias.indIda = 1 THEN po.codantt ELSE pd.codantt END localOrigem, ");
		sb.append("        CASE WHEN subAlias.indIda = 1 THEN pd.codantt ELSE po.codantt END localDestino ");
		sb.append(" FROM   (SELECT distinct subResp.antt  antt, ");
		sb.append("                subResp.prefixo        prefixo, ");
		sb.append("                ase.aliasorigen_id     aliasorigen,  ");
		sb.append("                ase.aliasdestino_id    aliasdestino, ");
		sb.append("                subResp.indIda         indIda ");

		sb.append("         FROM   (SELECT distinct r.ruta_id 			ruta_id,  ");
		sb.append("                        e.codantt           	 		antt,  ");
		sb.append("                        r.prefixo                prefixo,  ");
		sb.append("                        po.parada_id             localorigem,  ");
		sb.append("                        pd.parada_id             localdestino, ");
		sb.append("                        r.INDSENTIDOIDA          indIda ");
		sb.append("                 FROM   ruta_empresa re  ");
		sb.append("                        join empresa 	        e ON re.empresa_id = e.empresa_id  ");
		sb.append("                        join ruta 		          r ON re.ruta_id 	 = r.ruta_id  ");
		sb.append("                        join RUTA_COMBINACION rc on rc.RUTA_ID    = r.ruta_id ");
		sb.append("                        join tramo            tr on tr.TRAMO_ID   = rc.TRAMO_ID ");
		sb.append("                        join parada           po ON po.parada_id  = tr.origen_id  ");
		sb.append("                        join parada           pd ON pd.parada_id  = tr.destino_id  ");
				
		sb.append("                 WHERE  e.empresa_id  = ?   ");
		sb.append("                        AND re.activo = 1  ");
		sb.append("                        AND r.activo = 1  ");
		sb.append("                        AND r.orgaoconcedente_id = 3  ");
		sb.append("                        AND e.codantt IS NOT NULL  ");
		sb.append("                 GROUP  BY e.codantt,  ");
		sb.append("                           r.prefixo,  ");
		sb.append("                           po.parada_id,  ");
		sb.append("                           pd.parada_id,  ");
		sb.append("                           r.ruta_id, ");
		sb.append("                           r.INDSENTIDOIDA ");
		sb.append("                 ORDER BY e.codantt,  ");
		sb.append("                          r.prefixo) subResp  ");
						
		sb.append("                join alias_servico ase ON ( subResp.localorigem = ase.origen_id AND subResp.localdestino = ase.destino_id  and ase.ruta_id = subResp.ruta_id)  ");
				
		sb.append("  ORDER BY subResp.antt, ");
		sb.append("  subResp.prefixo ) subAlias ");
		 
		sb.append("        join parada po ON ( subAlias.aliasorigen = po.parada_id )  ");
		sb.append("        join parada pd ON ( subAlias.aliasdestino = pd.parada_id )  ");

		sb.append(" WHERE po.codantt <> pd.codantt ");
		  
		sb.append(" GROUP  BY antt,  ");
		sb.append("           prefixo,  ");
		sb.append("           po.codantt,  ");
		sb.append("           pd.codantt , ");
		sb.append("           indIda ");
		sb.append(" ORDER  BY antt,  ");
		sb.append("           prefixo,  ");
		sb.append("           localOrigem,   ");
		sb.append("           localDestino ");

		QueryRunner queryRunner = new QueryRunner(dataSourceRead, true);
		ResultSetHandler<List<PrefixoAntt>> handler = new BeanListHandler<PrefixoAntt>(PrefixoAntt.class);		

		List<PrefixoAntt> returnedList = new ArrayList<PrefixoAntt>();
		
		try {
			returnedList = queryRunner.query(sb.toString(), handler, empresaId);
		} catch (SQLException e) {
			log.error("",e);
		}		
		return returnedList;
	}

	@Override
	public List<String> getMovimentoSecoes(Date fecInicio, Date fecFinal, Integer empresaId,
			List<Object> pesquisaGratuidade, List<Object> pesquisaDescontoIdoso, List<Object> pesquisaGratuidadeIdoso,
			List<Object> pesquisaDescontoJovem, List<Object> pesquisaGratuidadeJovem,
			List<Object> pesquisaGratuidadeEstudante, List<Object> pesquisaGratuidadeProfessor) {

		List<MovimentoSecoes> listResultConsulta = consultaMovimentoSecoes(fecInicio, fecFinal, empresaId, pesquisaGratuidade, pesquisaDescontoIdoso, pesquisaGratuidadeIdoso, pesquisaDescontoJovem, pesquisaGratuidadeJovem, 
				pesquisaGratuidadeEstudante, pesquisaGratuidadeProfessor);
		List<MovimentoSecoes> listResultIdaVoltaInvertida = new ArrayList<MovimentoSecoes>();
		List<MovimentoSecoes> listVoltasSemIda = new ArrayList<MovimentoSecoes>();
			
		for (MovimentoSecoes ms : listResultConsulta) {
			
			Boolean achou = Boolean.FALSE;
			if(isIda(ms)) {
				for (MovimentoSecoes ms2 : listResultConsulta) {
					if(ms != null && ms2 != null && ms.getLocalOrigem() != null && ms2.getLocalOrigem() != null &&
							ms.getLocalOrigem().equals(ms2.getLocalDestino()) && ms2.getLocalOrigem().equals(ms.getLocalDestino()) && !isIda(ms2) && ms2.getPrefixo().equals(ms.getPrefixo())) {
						ms.setDescontoIdosoVolta(ms2.getDescontoIdosoVolta());
						ms.setGratuidadeIdosoVolta(ms2.getGratuidadeIdosoVolta());
						ms.setGratuidadePasseLivreVolta(ms2.getGratuidadePasseLivreVolta());
						ms.setPassageirosVolta(ms2.getPassageirosVolta());
						ms.setGratuidadeJovenVolta(ms2.getGratuidadeJovenVolta());
						ms.setDescontoJovenVolta(ms2.getGratuidadeJovenVolta());
						ms.setDescontoJovenVolta(ms2.getGratuidadeJovenVolta());
						ms.setGratuidadeEstudanteIda(ms2.getGratuidadeEstudanteIda());
						ms.setGratuidadeEstudanteVolta(ms2.getGratuidadeEstudanteVolta());
						ms.setGratuidadeProfessorIda(ms2.getGratuidadeProfessorIda());
						ms.setGratuidadeProfessorVolta(ms2.getGratuidadeProfessorVolta());						
						listResultIdaVoltaInvertida.add(ms);
						achou = Boolean.TRUE;
						break;
					}
				}
			
				if(!achou) {
					listResultIdaVoltaInvertida.add(ms);
				}
			 } else {
				 listVoltasSemIda.add(ms);
			 }
		}
		
		for (MovimentoSecoes volta : listVoltasSemIda) {
			
			Boolean achou = Boolean.FALSE;
			
			for (MovimentoSecoes idaVolta : listResultIdaVoltaInvertida) {
				if(idaVolta != null && idaVolta.getLocalOrigem() != null && volta != null && volta.getLocalOrigem() != null && volta.getPrefixo() != null &&
						idaVolta.getLocalOrigem().equals(volta.getLocalDestino()) && volta.getLocalOrigem().equals(idaVolta.getLocalDestino()) && volta.getPrefixo().equals(idaVolta.getPrefixo())) {
					achou = Boolean.TRUE;
					break;
				}
			}
			
			if(!achou) {
				String origem = volta.getLocalOrigem();
				String destino = volta.getLocalDestino();
			
				volta.setLocalDestino(origem);
				volta.setLocalOrigem(destino);
				listResultIdaVoltaInvertida.add(volta);
			}
		}
		
		List<String> periodos = new ArrayList<String>();
		for (MovimentoSecoes ms : listResultIdaVoltaInvertida) {
			String periodo = ms.getAno() + HYPHEN + ms.getMes();
			if (!periodos.contains(periodo)) {
				periodos.add(periodo);
			}
		}

		List<PrefixoAntt> prefixos = buscaPrefixoEmpresaOrigenDestino(empresaId);

		HashMap<String, List<PrefixoAntt>> periodosPrefixos = new HashMap<String, List<PrefixoAntt>>();
		for (String pd : periodos) {
			periodosPrefixos.put(pd, prefixos);
		}

		for (MovimentoSecoes ms : listResultIdaVoltaInvertida) {
			String periodo = ms.getAno() + HYPHEN + ms.getMes();

			PrefixoAntt prefixoAntt = new PrefixoAntt();
			prefixoAntt.setAntt(ms.getAntt());
			prefixoAntt.setPrefixo(ms.getPrefixo());
			prefixoAntt.setLocalDestino(ms.getLocalDestino());
			prefixoAntt.setLocalOrigem(ms.getLocalOrigem());

			if (periodosPrefixos.get(periodo).contains(prefixoAntt)) {
				periodosPrefixos.get(periodo).remove(prefixoAntt);
			}
		}
		
		for (String key : periodosPrefixos.keySet()) {
			String[] periodo = key.split(HYPHEN);
			Integer ano = Integer.parseInt(periodo[0]);
			Integer mes = Integer.parseInt(periodo[1]);

			for (PrefixoAntt prefixoAntt : periodosPrefixos.get(key)) {
				MovimentoSecoes ms = new MovimentoSecoes();
				ms.setAno(ano);
				ms.setMes(mes);

				ms.setAntt(prefixoAntt.getAntt());
				ms.setPrefixo(prefixoAntt.getPrefixo());
				ms.setLocalDestino(prefixoAntt.getLocalDestino());
				ms.setLocalOrigem(prefixoAntt.getLocalOrigem());

				ms.setDescontoIdosoIda(NumberUtils.INTEGER_ZERO);
				ms.setDescontoIdosoVolta(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadeIdosoIda(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadeIdosoVolta(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadeJovenIda(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadeJovenVolta(NumberUtils.INTEGER_ZERO);
				ms.setDescontoJovenIda(NumberUtils.INTEGER_ZERO);
				ms.setDescontoJovenVolta(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadePasseLivreIda(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadePasseLivreVolta(NumberUtils.INTEGER_ZERO);
				ms.setPassageirosIda(NumberUtils.INTEGER_ZERO);
				ms.setPassageirosVolta(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadeEstudanteIda(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadeEstudanteVolta(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadeProfessorIda(NumberUtils.INTEGER_ZERO);
				ms.setGratuidadeProfessorVolta(NumberUtils.INTEGER_ZERO);
				

				listResultIdaVoltaInvertida.add(ms);
			}
		}

		Collections.sort(listResultIdaVoltaInvertida, new Comparator() {
			public int compare(Object o1, Object o2) {
				MovimentoSecoes c1 = (MovimentoSecoes) o1;
				MovimentoSecoes c2 = (MovimentoSecoes) o2;

				int result = c1.getAno().compareTo(c2.getAno());
				if (result == 0) {
					result = c1.getMes().compareTo(c2.getMes());
				}
				if (result == 0) {
					result = c1.getAntt().compareToIgnoreCase(c2.getAntt());
				}
				if (result == 0) {
					return c1.getPrefixo().compareToIgnoreCase(c2.getPrefixo());
				}
				if (result == 0) {
					return c1.getLocalOrigem().compareToIgnoreCase(c2.getLocalOrigem());
				}
				if (result == 0) {
					return c1.getLocalDestino().compareToIgnoreCase(c2.getLocalDestino());
				}
				return result;
			}
		});

		List<String> movimentosSecoes = new ArrayList<String>();
		movimentosSecoes.add("empresa;prefixo;local_origem;local_destino;mes;ano;passageiro_ida;passageiro_volta;gratuidade_ida;gratuidade_volta;idoso_ida;idoso_volta;desconto_ida;desconto_volta;gratuidade_jovem_ida;gratuidade_jovem_volta;gratuidade_jovem_desconto_ida;gratuidade_jovem_desconto_volta;gratuidade_estudante_ida;gratuidade_estudante_volta;gratuidade_professoe_ida;gratuidade_professor_volta");
		

		for (MovimentoSecoes ms : listResultIdaVoltaInvertida) {
			movimentosSecoes.add(ms.toString());
		}

		return movimentosSecoes;
	}
	
}