/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.rjconsultores.ventaboletos.dao.hibernate;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.lang.math.NumberUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;
import org.hibernate.type.BooleanType;
import org.hibernate.type.IntegerType;
import org.hibernate.type.StringType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.rjconsultores.ventaboletos.dao.CorridaDAO;
import com.rjconsultores.ventaboletos.dao.CorridaTramoDAO;
import com.rjconsultores.ventaboletos.dao.sqlbuilder.SQLBuilder;
import com.rjconsultores.ventaboletos.entidad.ClaseServicio;
import com.rjconsultores.ventaboletos.entidad.ConexionRutaLocalidadeRemovida;
import com.rjconsultores.ventaboletos.entidad.Corrida;
import com.rjconsultores.ventaboletos.entidad.Corrida.Id;
import com.rjconsultores.ventaboletos.entidad.CorridaTramo;
import com.rjconsultores.ventaboletos.entidad.DiagramaAutobus;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.Estado;
import com.rjconsultores.ventaboletos.entidad.Marca;
import com.rjconsultores.ventaboletos.entidad.Parada;
import com.rjconsultores.ventaboletos.entidad.Ruta;
import com.rjconsultores.ventaboletos.exception.BusinessException;
import com.rjconsultores.ventaboletos.utilerias.ActivoUtil;
import com.rjconsultores.ventaboletos.utilerias.ApplicationProperties;
import com.rjconsultores.ventaboletos.utilerias.CustomEnum;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.vo.corrida.CorridaVO;
import com.rjconsultores.ventaboletos.vo.secuencia.SecuenciaVO;

/**
 * 
 * @author rodrigo
 */
@SuppressWarnings("unchecked")
@Repository("corridaDAO")
public class CorridaHibernateDAO extends GenericHibernateDAO<Corrida, Corrida.Id> implements CorridaDAO {

	@Autowired
	private SQLBuilder sqlBuilder;
	private static final Integer ULTIMA_HORA_DIA = Integer.valueOf(23);
	private static final Integer ULTIMO_MINUTO_SEGUNDO = Integer.valueOf(59);
	private static final Integer ULTIMO_MILLISEGUNDO = Integer.valueOf(99);
	@Autowired
	private CorridaTramoDAO corridaTramoDao;
	
	private static final Logger log = LogManager.getLogger(CorridaHibernateDAO.class);

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

	@Override
	public Boolean existe(final Id id) {

		Criteria c = makeCriteria();
		c.setProjection(Projections.rowCount());
		c.add(Restrictions.eq("id", id));

		Long cant = HibernateFix.count(c.list());

		return (cant > 0);
	}
	
	@Override
	public Boolean existeActivo(final Id id) {

		Criteria c = makeCriteria();
		
		c.setProjection(Projections.rowCount());
		c.add(Restrictions.eq("id", id));
		c.add(Restrictions.eq(ACTIVO, ActivoUtil.ATIVO));

		Long cant = HibernateFix.count(c.list());

		return (cant > 0);
	}

	@Override
	public Corrida suscribir(final Corrida entity) {

		if (ApplicationProperties.getInstance().isCustomHabilitado(CustomEnum.GERAR_CAMPO_EQUIVALENCIA_CORRIDA.getDescricao())) {
			String sql = "SELECT CORRIDA_EQUIVALENCIA_SEQ.NEXTVAL FROM DUAL";
			Object o = this.getSession().createSQLQuery(sql).uniqueResult();
			entity.setEquivalenciaId(o.toString());
		}

		Corrida corrida = super.suscribir(entity);
		this.getSession().flush();
		return corrida;
	}

	@Override
	public List<Corrida> buscarPorAutobusCorridasFuturas(final DiagramaAutobus diagramaAutobus) {
		String hql = " select co from Corrida co, Autobus ab "
				+ " where ab.autobusId = co.autobus.autobusId "
				+ " and ab.diagramaAutobus.diagramaautobusId = " + diagramaAutobus.getDiagramaautobusId()
				+ " and co.id.feccorrida > current_timestamp()";

		Query sq = getSession().createQuery(hql);

		List<Corrida> lsCorridas = sq.list();

		return lsCorridas;
	}

	@Override
	public List<Corrida> buscarPorRolOperativoCorridasFuturas(final DiagramaAutobus diagramaAutobus) {
		String hql = " select co from Corrida co, RolOperativo rol "
				+ " where rol.roloperativoId = co.rolOperativo.roloperativoId "
				+ " and rol.diagramaAutobus.diagramaautobusId = " + diagramaAutobus.getDiagramaautobusId()
				+ " and co.id.feccorrida > current_timestamp()";

		Query sq = getSession().createQuery(hql);
		List<Corrida> lsCorridas = sq.list();

		return lsCorridas;
	}

	@Override
	public List<Corrida> buscarPorFecCorrida(final Date value) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq(ACTIVO, ActivoUtil.ATIVO));

		c.add(Restrictions.eq("id.feccorrida", value));

		return c.list();
	}

	@Override
	public Long count(final Ruta ruta) {
		Criteria c = this.makeCriteria();
		c.add(Restrictions.eq("ruta", ruta));
		c.add(Restrictions.eq(ACTIVO, ActivoUtil.ATIVO));
		c.setProjection(Projections.rowCount());

		return HibernateFix.count(c.list());

	}

	@Override
	public List<Corrida> verificarCorridaId(Integer corridaId) {

		StringBuilder hql = new StringBuilder();
		hql.append("select distinct ");
		hql.append("    new com.rjconsultores.ventaboletos.entidad.Corrida(");
		hql.append("	c.id.corridaId, ");
		hql.append("	c.origem, ");
		hql.append("	c.destino) ");
		hql.append("from ");
		hql.append("	Corrida c ");
		hql.append("where ");
		hql.append("	1 = 1 ");
		hql.append("	and c.activo = 1 ");
		hql.append(" and cast(c.id.corridaId as string) like :corridaId ");
		hql.append(" group by ");
		hql.append("	c.id.corridaId, ");
		hql.append("	c.origem, ");
		hql.append("	c.destino) ");

		Query sq = getSession().createQuery(hql.toString());

		if (corridaId != null) {
			sq.setParameter("corridaId", corridaId.toString() + '%');
		} else {
			sq.setParameter("corridaId", '%');
		}

		return sq.list();
	}

	@Override
	public List<Corrida> buscarPorId(final Integer idCorrida) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq(ACTIVO, ActivoUtil.ATIVO));
		c.add(Restrictions.eq("id.corridaId", idCorrida));

		return c.list();
	}

	@Override
	public List<Corrida> buscarFiltro(final Parada ori, final Parada des, final Date hora, final ClaseServicio cs) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq(ACTIVO, ActivoUtil.ATIVO));
		c.add(Restrictions.eq("origem", ori));
		c.add(Restrictions.eq("destino", des));
		c.add(Restrictions.between("fechorsalida", getDiaGeracaoHoraIni(hora), getDiaGeracaoHoraFim(hora)));
		c.add(Restrictions.eq("claseServicio", cs));

		return c.list();
	}

	@Override
	public boolean count(final Parada ori, final Parada des, final Date hora,
			final ClaseServicio cs, final boolean pisoExtra) {

		Criteria c = makeCriteria();
		c.setProjection(Projections.rowCount());
		c.add(Restrictions.eq(ACTIVO, ActivoUtil.ATIVO));
		c.add(Restrictions.eq("origem", ori));
		c.add(Restrictions.eq("destino", des));
		c.add(Restrictions.between("fechorsalida", getDiaGeracaoHoraIni(hora), getDiaGeracaoHoraFim(hora)));
		c.add(Restrictions.eq("claseServicio", cs));

		// Se for piso extra numPiso = 2
		if (pisoExtra) {
			// Corrida Piso Extra
			c.add(Restrictions.eq("numPiso", 2));
		} else {
			// num piso == null ou diferente de 2
			c.add(Restrictions.or(Restrictions.not(Restrictions.eq("numPiso", 2)), Restrictions.isNull("numPiso")));
		}

		Long cant = HibernateFix.count(c.list());

		return (cant > 0);
	}

	private Date getDiaGeracaoHoraIni(final Date hora) {
		Date dataCorreta = new Date();

		// para pegar a hora e adicionar ao dia da geracao:
		GregorianCalendar gAux = new GregorianCalendar();
		gAux.setTime(hora);
		GregorianCalendar gcalendar = new GregorianCalendar();
		gcalendar.setTime(hora);
		gcalendar.set(Calendar.HOUR_OF_DAY, gAux.get(Calendar.HOUR_OF_DAY));
		gcalendar.set(Calendar.MINUTE, gAux.get(Calendar.MINUTE));
		gcalendar.set(Calendar.SECOND, NumberUtils.INTEGER_ZERO);
		gcalendar.set(Calendar.MILLISECOND, NumberUtils.INTEGER_ZERO);

		dataCorreta = gcalendar.getTime();

		return dataCorreta;
	}

	private Date getDiaGeracaoHoraFim(final Date hora) {
		Date dataCorreta = new Date();

		// para pegar a hora e adicionar ao dia da geracao:
		GregorianCalendar gAux = new GregorianCalendar();
		gAux.setTime(hora);
		GregorianCalendar gcalendar = new GregorianCalendar();
		gcalendar.setTime(hora);
		gcalendar.set(Calendar.HOUR_OF_DAY, gAux.get(Calendar.HOUR_OF_DAY));
		gcalendar.set(Calendar.MINUTE, gAux.get(Calendar.MINUTE));
		gcalendar.set(Calendar.SECOND, NumberUtils.INTEGER_ZERO);
		gcalendar.set(Calendar.MILLISECOND, ULTIMA_HORA_DIA);

		dataCorreta = gcalendar.getTime();

		return dataCorreta;
	}

	@Override
	public List<Corrida> buscarDistinct(final Parada ori, final Parada des, final Date horaSalidaInicio,
			final Date horaSalidaFin, final ClaseServicio cs, final Integer corridaId) {
		StringBuilder hql = new StringBuilder("");
		hql.append("select distinct ");
		hql.append("    new com.rjconsultores.ventaboletos.entidad.Corrida(");
		hql.append("	c.marca, ");
		hql.append("	c.id.corridaId, ");
		hql.append("	c.origem, ");
		hql.append("	c.destino, ");
		hql.append("	c.claseServicio, ");
		hql.append("	c.corridaCtrl.horario) ");
		hql.append("from ");
		hql.append("	Corrida c ");
		hql.append("where ");
		hql.append("	1 = 1 ");
		if (ori != null) {
			hql.append("	and c.origem = :origen ");
		}
		if (des != null) {
			hql.append("	and c.destino = :destino");
		}
		if (cs != null) {
			hql.append("	and c.claseServicio = :claseServicio ");
		}
		if (corridaId != null) {
			hql.append("	and c.id.corridaId = :corridaId ");
		}
		if (horaSalidaInicio != null) {

			hql.append("	and c.corridaCtrl.horario >= :horaSalidaInicio");
		}
		if (horaSalidaFin != null) {

			hql.append("	and c.corridaCtrl.horario <= :horaSalidaFin");
		}

		hql.append("  order by c.id.corridaId,c.corridaCtrl.horario");

		Query query = getSession().createQuery(hql.toString());

		if (ori != null) {
			query.setParameter("origen", ori);
		}
		if (des != null) {
			query.setParameter("destino", des);
		}
		if (cs != null) {
			query.setParameter("claseServicio", cs);
		}
		if (corridaId != null) {
			query.setParameter("corridaId", corridaId);
		}

		if (horaSalidaInicio != null) {

			query.setParameter("horaSalidaInicio", horaSalidaInicio);
		}
		if (horaSalidaFin != null) {
			query.setParameter("horaSalidaFin", horaSalidaFin);

		}

		return query.list();
	}

	@Override
	public boolean existe(final Ruta ruta, final Date fecCorrida, final Date horaCorrida,
			final ClaseServicio claseServicio, final Marca marca, final boolean pisoExtra) {
		Calendar soloFecha = Calendar.getInstance();
		soloFecha.setTime(fecCorrida);
		soloFecha.set(Calendar.HOUR, NumberUtils.INTEGER_ZERO);
		soloFecha.set(Calendar.MINUTE, NumberUtils.INTEGER_ZERO);
		soloFecha.set(Calendar.SECOND, NumberUtils.INTEGER_ZERO);
		soloFecha.set(Calendar.MILLISECOND, NumberUtils.INTEGER_ZERO);

		Criteria c = makeCriteria();
		c.setProjection(Projections.rowCount());
		c.add(Restrictions.eq("ruta", ruta));
		c.add(Restrictions.eq("id.feccorrida", soloFecha.getTime()));
		c.add(Restrictions.eq("claseServicio", claseServicio));
		c.add(Restrictions.eq("marca", marca));

		// Se for piso extra numPiso = 2
		if (pisoExtra) {
			// Corrida Piso Extra
			c.add(Restrictions.eq("numPiso", 2));
		} else {
			// num piso == null ou diferente de 2
			c.add(Restrictions.or(Restrictions.not(Restrictions.eq("numPiso", 2)), Restrictions.isNull("numPiso")));
		}

		Criteria cCorridaCtrl = c.createCriteria("corridaCtrl");
		cCorridaCtrl.add(Restrictions.eq("horario", horaCorrida));

		Long cant = HibernateFix.count(c.list());

		return (cant > 0);
	}

	@Override
	public Long cantCorridaGeneradasHoy() {
		Calendar cTmp1 = Calendar.getInstance();
		Calendar cTmp2 = Calendar.getInstance();

		cTmp1.set(Calendar.HOUR_OF_DAY, NumberUtils.INTEGER_ZERO);
		cTmp1.set(Calendar.MINUTE, NumberUtils.INTEGER_ZERO);
		cTmp1.set(Calendar.MILLISECOND, NumberUtils.INTEGER_ZERO);
		cTmp1.set(Calendar.SECOND, NumberUtils.INTEGER_ZERO);

		cTmp2.set(Calendar.HOUR_OF_DAY, ULTIMA_HORA_DIA);
		cTmp2.set(Calendar.MINUTE, ULTIMO_MINUTO_SEGUNDO);
		cTmp2.set(Calendar.SECOND, ULTIMO_MINUTO_SEGUNDO);
		cTmp2.set(Calendar.MILLISECOND, ULTIMO_MILLISEGUNDO);

		String sql = "select count(c.fecmodif) from Corrida c where c.fecmodif between :inicio and :fim";

		Query query = getSession().createQuery(sql);
		query.setParameter("inicio", cTmp1.getTime());
		query.setParameter("fim", cTmp2.getTime());
		Long count = HibernateFix.count(query.uniqueResult());

		return count;
	}

	@Override
	public List<Corrida> buscarGroupCorrridaId(final Integer corridaId, final Integer origem, final Integer destino,
			final Integer ruta, final Integer numRuta, final Date dateInicio, final Date dateFin) {

		StringBuilder sql = new StringBuilder();
		sql.append(" SELECT c.corrida_id ");
		sql.append(" FROM   corrida c ");
		if (numRuta != null) {
			sql.append(" INNER JOIN Ruta r ON r.ruta_id=c.ruta_id ");
		}
		sql.append(" WHERE  c.feccorrida BETWEEN :dateInicio AND :dateFin ");
		sql.append(" AND c.corrida_id LIKE :corridaId ");

		if (origem != null) {
			sql.append(" AND c.ORIGEN_ID=:origem");
		}
		if (destino != null) {
			sql.append(" AND c.DESTINO_ID=:destino");
		}
		if (ruta != null) {
			sql.append(" AND c.RUTA_ID=:ruta");
		}
		if (numRuta != null) {
			sql.append(" AND r.NUMRUTA=:numRuta");
		}

		sql.append(" GROUP  BY c.corrida_id ");

		Query sq = getSession().createSQLQuery(sql.toString());

		if (corridaId != null) {
			sq.setParameter("corridaId", corridaId.toString() + '%');
		} else {
			sq.setParameter("corridaId", '%');
		}
		
		if (origem != null) {
			sq.setParameter("origem", origem);
		}
		if (destino != null) {
			sq.setParameter("destino", destino);
		}
		if (ruta != null) {
			sq.setParameter("ruta", ruta);
		}
		if (numRuta != null) {
			sq.setParameter("numRuta", numRuta.toString());
		}

		sq.setParameter("dateInicio", dateInicio);
		sq.setParameter("dateFin", dateFin);

		List<Object> lsObject = sq.list();

		List<Corrida> lsCorridas = new ArrayList<Corrida>();

		if (lsObject != null && !lsObject.isEmpty()) {

			for (Object object : lsObject) {

				BigDecimal id = (BigDecimal) object;

				StringBuffer hql = new StringBuffer();
				hql.append(" FROM Corrida   ");
				hql.append("      WHERE id.corridaId = " + id);
				hql.append(origem != null ? " AND origem.paradaId = :origem " : "");
				hql.append(destino != null ? " AND destino.paradaId = :destino " : "");
				hql.append(ruta != null ? " AND ruta.rutaId = :ruta " : "");
				hql.append(numRuta != null ? " AND ruta.numRuta = :numruta " : "");
				
				Query squery = getSession().createQuery(hql.toString());

				if (origem != null)
					squery.setParameter("origem", origem);

				if (destino != null)
					squery.setParameter("destino", destino);

				if (ruta != null)
					squery.setParameter("ruta", ruta);

				if (numRuta != null)
					squery.setParameter("numruta", numRuta.toString());
				
				squery.setMaxResults(NumberUtils.INTEGER_ONE);
				
				List<Corrida> lsCorridasAux = squery.list();

				if (lsCorridasAux != null && !lsCorridasAux.isEmpty()) {
					lsCorridas.add(lsCorridasAux.iterator().next());
				}
			}
		}

		return lsCorridas;
	}

	@Override
	public List<Corrida> buscarGroupCorrridaId(final Integer corridaId, final Date dateInicio, final Date dateFin) {

		StringBuilder sql = new StringBuilder();
		sql.append(" SELECT c.corrida_id ");
		sql.append(" FROM   corrida c ");
		sql.append(" WHERE  c.feccorrida BETWEEN :dateInicio AND :dateFin ");
		sql.append("       AND c.corrida_id LIKE :corridaId ");
		sql.append(" GROUP  BY c.corrida_id ");

		Query sq = getSession().createSQLQuery(sql.toString());

		if (corridaId != null) {
			sq.setParameter("corridaId", corridaId.toString() + '%');
		} else {
			sq.setParameter("corridaId", '%');
		}

		sq.setParameter("dateInicio", dateInicio);
		sq.setParameter("dateFin", dateFin);

		List<Object> lsObject = sq.list();

		List<Corrida> lsCorridas = new ArrayList<Corrida>();

		if (lsObject != null && !lsObject.isEmpty()) {

			for (Object object : lsObject) {

				BigDecimal id = (BigDecimal) object;

				StringBuilder hql = new StringBuilder();
				hql.append(" FROM Corrida   ");
				hql.append("      WHERE id.corridaId =  " + id);
				hql.append("      and id.feccorrida BETWEEN :dateInicio AND :dateFin");

				Query squery = getSession().createQuery(hql.toString());
				squery.setParameter("dateInicio", dateInicio);
				squery.setParameter("dateFin", dateFin);
				squery.setMaxResults(NumberUtils.INTEGER_ONE);

				List<Corrida> lsCorridasAux = squery.list();

				if (lsCorridasAux != null && !lsCorridasAux.isEmpty()) {
					lsCorridas.add(lsCorridasAux.iterator().next());
				}
			}
		}

		return lsCorridas;
	}

	@Override
	public void actualizaFecHusoFecVerano(final Corrida corrida) {

		Integer corridaId = corrida.getId().getCorridaId();
		Date feccorrida = corrida.getId().getFeccorrida();

		Query queryCorrida = getSession().createQuery(
				sqlBuilder.getSQLActualizarCorridaFecHusoFecVerano());
		queryCorrida.setInteger("corridaId", corridaId);
		queryCorrida.setInteger("corridaId", corridaId);
		queryCorrida.setDate("feccorrida", feccorrida);
		queryCorrida.executeUpdate();

		Query queryCorridaTramo = getSession().createQuery(
				sqlBuilder.getSQLActualizarCorridaTramoFecHusoFecVerano());
		queryCorridaTramo.setInteger("corridaId", corridaId);
		queryCorridaTramo.setDate("feccorrida", feccorrida);
		queryCorridaTramo.executeUpdate();
	}

	@SuppressWarnings("deprecation")
	@Override
	public void actualizaFecHusoFecVerano(final List<Corrida> corridas) {

		for (Corrida corrida : corridas) {

			Date husoHorVeranoLlegadaAnterior = null;
			Date fechorSalidaOriginalUpdate = null;
			Date fechorsalidaUpdate = null;
			Date fechorllegadaUpdate = null;
			Integer corridatramoId = 0;
			Date fechorSalidaOriginal = null;
			Date fechorsalida = null;
			Date fechorllegada = null;
			Integer tiempoHorHusoOrigem = Integer.valueOf(0);
			Integer tiempoHorVeranoOrigem = Integer.valueOf(0);
			Integer tiempoHorHusoDestino = Integer.valueOf(0);
			Integer tiempoHorVeranoDestino = Integer.valueOf(0);
			Date tiempoestancia = null;

			List<Object[]> tramos = buscarTramosCorrida(corrida);

			for (Object[] objeto : tramos) {
				corridatramoId = Integer.valueOf(objeto[0].toString());
				fechorSalidaOriginal = (Date) objeto[2];
				fechorsalida = (Date) objeto[3];
				fechorllegada = (Date) objeto[4];
				tiempoHorHusoOrigem = Integer.valueOf(objeto[5].toString());
				tiempoHorVeranoOrigem = Integer.valueOf(objeto[6].toString());
				tiempoHorHusoDestino = Integer.valueOf(objeto[7].toString());
				tiempoHorVeranoDestino = Integer.valueOf(objeto[8].toString());
				tiempoestancia = (Date) objeto[9];

				if (husoHorVeranoLlegadaAnterior == null) {
					fechorSalidaOriginalUpdate = fechorSalidaOriginal;
					fechorsalidaUpdate = fechorsalida;
				} else {
					fechorSalidaOriginalUpdate = husoHorVeranoLlegadaAnterior;
					fechorsalidaUpdate = husoHorVeranoLlegadaAnterior;
				}

				husoHorVeranoLlegadaAnterior = calcularHusoHorVeranoLlegada(
						fechorsalida,
						fechorllegada,
						fechorsalidaUpdate,
						tiempoHorHusoOrigem + tiempoHorVeranoOrigem,
						tiempoHorHusoDestino + tiempoHorVeranoDestino);

				if (tiempoestancia != null) {
					Calendar aux = Calendar.getInstance();
					aux.setTime(DateUtil.normalizar(husoHorVeranoLlegadaAnterior));
					aux.add(Calendar.MINUTE, tiempoestancia.getMinutes());
					aux.add(Calendar.HOUR_OF_DAY, tiempoestancia.getHours());

					husoHorVeranoLlegadaAnterior = aux.getTime();

					Calendar auxFechorsalidaUpdate = Calendar.getInstance();
					auxFechorsalidaUpdate.setTime(DateUtil.normalizar(fechorsalidaUpdate));
					auxFechorsalidaUpdate.add(Calendar.MINUTE, tiempoestancia.getMinutes());
					auxFechorsalidaUpdate.add(Calendar.HOUR_OF_DAY, tiempoestancia.getHours());

					fechorsalidaUpdate = auxFechorsalidaUpdate.getTime();
				}

				if (husoHorVeranoLlegadaAnterior != null) {
					fechorllegadaUpdate = husoHorVeranoLlegadaAnterior;
				} else {
					fechorllegadaUpdate = fechorllegada;
				}

				Query queryCorridaTramo = getSession().createQuery(sqlBuilder.getSQLActualizarCorridaTramoFecHusoFecVerano());
				queryCorridaTramo.setTimestamp("fechorSalidaOriginalH", fechorSalidaOriginalUpdate);
				queryCorridaTramo.setTimestamp("fechorsalidaH", fechorsalidaUpdate);
				queryCorridaTramo.setTimestamp("fechorllegadaH", fechorllegadaUpdate);
				queryCorridaTramo.setInteger("corridatramoId", corridatramoId);
				queryCorridaTramo.executeUpdate();
			}
		}
	}

	private Date calcularHusoHorVeranoLlegada(Date fechorsalida, Date fechorllegada, Date fechorsalidaH, int tiempoOrigen, int tiempoDestino) {
		Calendar horLlegada = null;

		// Si los tiempos son distintos, hube cambio de huso horario/horario de verano

		long elapsedMinutes = DateUtil.getElapsedMinutos(fechorsalida, fechorllegada);

		horLlegada = Calendar.getInstance();
		horLlegada.setTime(fechorsalidaH);
		horLlegada.add(Calendar.MINUTE, (int) elapsedMinutes);

		if (tiempoOrigen != tiempoDestino) {
			horLlegada.add(Calendar.HOUR, difHuso(tiempoOrigen, tiempoDestino));

		}

		return (horLlegada == null) ? null : horLlegada.getTime();
	}

	private int difHuso(int a, int b) {
		return b - a;
	}

	@Override
	public List<Corrida> buscarPorEstado(final Estado estado, final Date dataInicial, Integer corridaId) {
		StringBuilder hql = new StringBuilder();

		hql.append(" select ");
		hql.append(" distinct new com.rjconsultores.ventaboletos.entidad.Corrida").append("(");
		hql.append("       ct.corrida.id.corridaId, ");
		hql.append("       ct.corrida.id.feccorrida").append(")");
		hql.append(" from   CorridaTramo ct ");
		hql.append("       left join ct.origem.ciudad.estado eo ");
		hql.append("       left join ct.destino.ciudad.estado ed ");
		hql.append(" where  ct.corrida.activo = :isActivo ");
		hql.append("        and ct.corrida.id.feccorrida >= :feccorrida ");
		hql.append("        and  ( eo.estadoId = :estadoId ");
		hql.append("        or ed.estadoId = :estadoId )");
		if (corridaId != null) {
			hql.append("    and ct.corrida.id.corridaId = :corridaId )");
		}
		hql.append(" group  by ");
		hql.append("       ct.corrida.id.corridaId, ");
		hql.append("       ct.corrida.id.feccorrida ");

		Query query = getSession().createQuery(hql.toString());
		query.setInteger("isActivo", ActivoUtil.ATIVO);
		query.setDate("feccorrida", dataInicial);
		query.setInteger("estadoId", estado.getEstadoId());

		if (corridaId != null) {
			query.setInteger("corridaId", corridaId);
		}

		return query.list();
	}

	@Override
	public List<Corrida> buscarPorEstado(final Estado estado, final Date dataInicial) {
		return buscarPorEstado(estado, dataInicial, null);
	}

	private List<Object[]> buscarTramosCorrida(final Corrida corrida) {
		StringBuilder hql = new StringBuilder();

		hql.append(" select ");
		hql.append("       ct.corridatramoId, ");
		hql.append("       ct.numsecuencia,");
		hql.append("       ct.fechorSalidaOriginal,");
		hql.append("       ct.fechorsalida,");
		hql.append("       ct.fechorllegada,");
		hql.append("       nvl(estadoO.tiempoHorHuso, 0) as tiempoHorHusoOrigem,");
		hql.append("       nvl( case when ");
		hql.append("               ct.fechorSalidaOriginal between  ");
		hql.append("               estadoO.fecInicioHorVerano  ");
		hql.append("               and estadoO.fecFinoHorVerano ");
		hql.append("               then (estadoO.tiempoHorVerano)");
		hql.append("               else 0 end, 0) as tiempoHorVeranoOrigem,");
		hql.append("       nvl(estadoD.tiempoHorHuso, 0) as tiempoHorHusoDestino,");
		hql.append("       nvl( case when ");
		hql.append("               ct.fechorSalidaOriginal between  ");
		hql.append("               estadoD.fecInicioHorVerano  ");
		hql.append("               and estadoD.fecFinoHorVerano ");
		hql.append("               then (estadoD.tiempoHorVerano)");
		hql.append("               else 0 end, 0) as tiempoHorVeranoDestino,");
		hql.append("	   ct.tiempoEstancia ");
		hql.append(" from   CorridaTramo ct ");
		hql.append("        inner join ct.origem origem ");
		hql.append("        inner join origem.ciudad ciudadO ");
		hql.append("        inner join ciudadO.estado estadoO ");
		hql.append("        inner join ct.destino destino ");
		hql.append("        inner join destino.ciudad ciudadD ");
		hql.append("        inner join ciudadD.estado estadoD ");

		hql.append(" where  ct.corrida.activo = :isActivo ");
		hql.append("        and ct.activo = :isActivo ");
		hql.append("        and ct.corrida.id.corridaId = :corridaId ");
		hql.append("        and ct.corrida.id.feccorrida = :feccorrida ");
		hql.append(" order by ");
		hql.append("       ct.numsecuencia ");

		Query query = getSession().createQuery(hql.toString());
		query.setInteger("isActivo", ActivoUtil.ATIVO);
		query.setDate("feccorrida", corrida.getId().getFeccorrida());
		query.setInteger("corridaId", corrida.getId().getCorridaId());

		return query.list();
	}

	@Override
	public Corrida buscaCorrridaFutura(Ruta ruta, Date fecInicio) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq("ruta", ruta));
		c.add(Restrictions.gt("fechorsalida", fecInicio));
		c.addOrder(Order.asc("fechorsalida"));
		List<Corrida> lsCorrida = c.list();
		if (!lsCorrida.isEmpty()) {
			return lsCorrida.get(0);
		}
		return null;
	}

	@Override
	public Boolean editarCorridaPorOutraCorrida(List<Corrida> corridas, Corrida corridaPadrao) {
		List<CorridaTramo> tramosPadrao = corridaTramoDao.buscarCorridaTramoPorCorrida(corridaPadrao);

		for (Corrida corrida : corridas) {
			List<CorridaTramo> tramos = corridaTramoDao.buscarCorridaTramoPorCorrida(corrida);

			try{
				for (CorridaTramo tramo : tramos) {

					for (CorridaTramo tramoPadrao : tramosPadrao) {
						if (tramoPadrao.getNumsecuencia().equals(tramo.getNumsecuencia())) {
							tramo.setFechorsalida(mudarData(tramoPadrao.getFechorsalida(), tramo.getFechorsalida()));
							tramo.setFechorsalidaH(mudarData(tramoPadrao.getFechorsalidaH(), tramo.getFechorsalidaH()));
							tramo.setFechorSalidaOriginal(mudarData(tramoPadrao.getFechorSalidaOriginal(), tramo.getFechorSalidaOriginal()));
							tramo.setFechorllegada(mudarData(tramoPadrao.getFechorllegada(), tramo.getFechorllegada()));
							tramo.setFechorllegadaH(mudarData(tramoPadrao.getFechorllegadaH(), tramo.getFechorllegadaH()));
							corridaTramoDao.actualizacion(tramo);
							break;
						}
					}
				}				
			}catch(Exception e){
				log.error(e.getMessage());
			}
			
		}
		return true;
	}

	private Date mudarData(Date dataPadrao, Date dataMudanca) {
		try{
			Calendar calPadrao = Calendar.getInstance();
			calPadrao.setTime(dataPadrao);
			Calendar calMudanca = Calendar.getInstance();
			calMudanca.setTime(dataMudanca);

			calMudanca.set(calMudanca.get(Calendar.YEAR), calMudanca.get(Calendar.MONTH), calMudanca.get(Calendar.DAY_OF_MONTH),
					calPadrao.get(Calendar.HOUR_OF_DAY), calPadrao.get(Calendar.MINUTE), calPadrao.get(Calendar.SECOND));
			return calMudanca.getTime();
		}catch(Exception e){
			return null;
		}
	}

	@Override
	public Corrida buscarPorId(Id id) {
		
		StringBuilder hql = new StringBuilder();
		
		hql.append(" from   Corrida corrida ");
		hql.append(" where  corrida.id.feccorrida = :feccorrida ");
		hql.append("    and corrida.id.corridaId = :corridaId )");
		
		Query query = getSession().createQuery(hql.toString());
		query.setDate("feccorrida", id.getFeccorrida());
		query.setInteger("corridaId", id.getCorridaId());

		query.setMaxResults(1);
		return (Corrida)query.uniqueResult();
	}
	
	@Override
	public Corrida buscarCorridaAtivaPorId(Id id) {
		
		StringBuilder hql = new StringBuilder();
		
		hql.append(" from   Corrida corrida ");
		hql.append(" where  corrida.id.feccorrida = :feccorrida ");
		hql.append("    and corrida.id.corridaId = :corridaId ");
		hql.append("    and corrida.activo = 1 ");
		hql.append("    and corrida.indstatuscorrida = 'H' ");
		
		Query query = getSession().createQuery(hql.toString());
		query.setDate("feccorrida", id.getFeccorrida());
		query.setInteger("corridaId", id.getCorridaId());

		query.setMaxResults(1);
		return (Corrida)query.uniqueResult();
	}
	
	private List<Corrida> buscaCorridaFutura(){
		List<Corrida> corridaList = new ArrayList<Corrida>();
		
		return corridaList;
	}

	@Override
	public List<Corrida> buscarCorridaRelAproveitamento(Parada origem, Parada destino,
			Date feccorrida, Integer corridaId) {

		StringBuilder sql = new StringBuilder();
		sql.append(" 	select  ");
		sql.append("          c.corrida_id as corrida_id, ");
		sql.append("          c.feccorrida as feccorrida, ");
		sql.append("          c.fechorsalida as fechorsalida, ");
		sql.append("          origen.parada_id as origen_id, ");
		sql.append("          origen.descparada as origen, ");
		sql.append("          destino.parada_id as destino_id, ");
		sql.append("          destino.descparada as destino, ");
		sql.append("          r.ruta_id as ruta_id,  ");
		sql.append("          r.descruta as descruta,  ");
		sql.append("          cs.claseservicio_id as claseservicio_id, ");
		sql.append("          cs.descclase as descclase ");
		sql.append(" 	from corrida c ");
		sql.append(" 	     inner join parada origen on c.origen_id = origen.parada_id ");
		sql.append(" 	     inner join parada destino on c.destino_id = destino.parada_id ");
		sql.append(" 	     inner join ruta r on c.ruta_id = r.ruta_id ");
		sql.append(" 	     inner join clase_servicio cs on c.claseservicio_id = cs.claseservicio_id ");
		sql.append(" 	where c.activo <> 0 ");
		if (corridaId != null) {
			sql.append(" and c.corrida_id = :corridaId ");
		}
		sql.append(feccorrida == null ? "" : " and c.feccorrida = :feccorrida ");
		if (origem != null) {
			sql.append(origem == null ? "" : " and c.origen_id = :origen_id ");
		}
		if (destino != null) {
			sql.append(destino == null ? "" : " and c.destino_id = :destino_id ");
		}

		Query query = getSession().createSQLQuery(sql.toString());
		if (corridaId != null) {
			query.setParameter("corridaId", corridaId);
		}
		query.setParameter("feccorrida", feccorrida);
		if (origem != null) {
			query.setParameter("origen_id", origem.getParadaId());
		}
		if (destino != null) {
			query.setParameter("destino_id", destino.getParadaId());
		}

		List<Object> lsObject = query.list();

		List<Corrida> lsCorridas = new ArrayList<Corrida>();

		if (lsObject != null && !lsObject.isEmpty()) {

			for (Object object : lsObject) {
				if (object != null) {
					Object objectArray[] = (Object[]) object;
					Id id = new Id();
					id.setCorridaId(((BigDecimal) objectArray[0]).intValue());
					id.setFeccorrida((Timestamp) objectArray[1]);

					Parada o = new Parada();
					o.setParadaId(((BigDecimal) objectArray[3]).intValue());
					o.setDescparada((String) objectArray[4]);

					Parada d = new Parada();
					d.setParadaId(((BigDecimal) objectArray[5]).intValue());
					d.setDescparada((String) objectArray[6]);

					Ruta ruta = new Ruta();
					ruta.setRutaId(((BigDecimal) objectArray[7]).intValue());
					ruta.setDescruta((String) objectArray[8]);

					ClaseServicio claseServicio = new ClaseServicio();
					claseServicio.setClaseservicioId(((BigDecimal) objectArray[9]).intValue());
					claseServicio.setDescclase((String) objectArray[10]);

					Corrida corrida = new Corrida();
					corrida.setId(id);
					corrida.setFechorsalida((Timestamp) objectArray[2]);
					corrida.setOrigem(o);
					corrida.setDestino(d);
					corrida.setRuta(ruta);
					corrida.setClaseServicio(claseServicio);

					lsCorridas.add(corrida);
				}
			}
		}
		return lsCorridas;
	}

	@Override
	public Boolean existeCorrida(Long id) {
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT CORRIDA_ID FROM CORRIDA corrida ");
		sql.append("WHERE CORRIDA_ID = " + id + " AND ACTIVO = 1");

		Query query = getSession().createSQLQuery(sql.toString());

		return query.list().size() > 0;
	}

	@Override
	@Transactional(rollbackFor = { BusinessException.class })
	public Integer atualizaCorridasIntegracaoTotvs(Marca marca, Date dataIncial, Date dataFinal, Integer corridaId) throws BusinessException {

		// update caja set integradototvs = 0 where PUNTOVENTA_ID = 269 and FECHORVENTA >= '30/03/2018' and FECHORVENTA <= '01/04/2018';
		StringBuilder sb = new StringBuilder();
		sb.append("  update corrida set integradototvs = 0 ");
		sb.append("  where FECCORRIDA >= :fechorInicial ");
		sb.append(" and  FECCORRIDA <= :fechorFinal ");
		sb.append(" and CORRIDA_ID = :corridaId ");
		if (marca != null) {
			sb.append(" and  MARCA_ID = :marcaId  ");
		}
		SQLQuery query = getSession().createSQLQuery(sb.toString());
		if (marca != null) {
			query.setInteger("marcaId", marca.getMarcaId());
		}
		query.setInteger("corridaId", corridaId);
		query.setTimestamp("fechorInicial", dataIncial);
		query.setTimestamp("fechorFinal", dataFinal);
		Integer result = query.executeUpdate();
		return result;
	}

	@Override
	public List<CorridaVO> buscarListaPorIds(List<Id> corridaIds){
		
		StringBuilder hql = new StringBuilder();
		hql.append(" select co ")
			.append(" from Corrida co")
			.append(" where co.activo = 1 ")
			.append(" and co.id in ( :corridaIds )");

		Query query = getSession().createQuery(hql.toString());
		query.setParameterList("corridaIds", corridaIds);
		List<Corrida> lsCorridas = query.list();
		
		List<CorridaVO> listCorrida = new ArrayList<CorridaVO>();
		for (Corrida corrida : lsCorridas) {
			CorridaVO co = new CorridaVO(corrida);
			
			preencherTramoSequencia(co, corrida);
			
			listCorrida.add(co);
		}

		return listCorrida;
	}
	
	@Override
	public CorridaVO buscarVOPorId(Id corridaId){
		
		StringBuilder sb = new StringBuilder();
		sb.append(" select ");
		sb.append("   c.corrida_id as corridaId, ");
	    sb.append("   to_char(c.feccorrida, 'dd/MM/yyyy') as feccorrida, ");
	    sb.append("   c.corrida_id as numCorrida, ");
	    sb.append("   to_char(c.fechorsalida, 'dd/MM/yyyy HH24:mi:ss')||'.000' as fechorsalida, ");
	    sb.append("   c.origen_id as origenId, ");
	    sb.append("   c.destino_id as destinoId, ");
	    sb.append("   c.tiposervicio_id as tipoServicioId, ");
	    sb.append("   c.roloperativo_id as rolOperativoId, ");
	    sb.append("   c.claseservicio_id as claseServicioId, ");
	    sb.append("   c.empresacorrida_id as empresaId, ");
	    sb.append("   mar.marca_id as marcaId, ");
	    sb.append("   emp.indtabelaprecoembarcada as tarifaEmbarcada, ");
	    sb.append("   c.ruta_id as rutaId ");
	    sb.append(" from corrida c ");
	    sb.append(" JOIN empresa  emp ON emp.empresa_id = c.empresacorrida_id ");
		sb.append(" JOIN marca  mar ON mar.empresa_id = emp.empresa_id ");
		sb.append("   AND mar.activo = 1 ");
	    sb.append(" where c.activo = 1 ");
		sb.append("   and C.CORRIDA_ID = :corridaId ");
		sb.append("   and C.FECCORRIDA = :feccorrida ");

		Query query = getSession().createSQLQuery(sb.toString())
				.addScalar("corridaId", 		IntegerType.INSTANCE)
				.addScalar("feccorrida", 		StringType.INSTANCE)
				.addScalar("numCorrida", 		IntegerType.INSTANCE)
				.addScalar("fechorsalida", 		StringType.INSTANCE)			
				.addScalar("origenId", 			IntegerType.INSTANCE)
				.addScalar("destinoId", 		IntegerType.INSTANCE)
				.addScalar("tipoServicioId", 	IntegerType.INSTANCE)
				.addScalar("rolOperativoId", 	IntegerType.INSTANCE)
				.addScalar("claseServicioId", 	IntegerType.INSTANCE)
				.addScalar("empresaId", 		IntegerType.INSTANCE)
				.addScalar("marcaId", 			IntegerType.INSTANCE)
				.addScalar("tarifaEmbarcada", 	BooleanType.INSTANCE)
				.addScalar("rutaId", 			IntegerType.INSTANCE)
				.setResultTransformer(Transformers.aliasToBean(CorridaVO.class));
		
		query.setParameter("corridaId", corridaId.getCorridaId());
		query.setParameter("feccorrida", corridaId.getFeccorrida());
		
		return (CorridaVO)query.uniqueResult();

	}
	
	private void preencherTramoSequencia(CorridaVO corridaVO, Corrida corrida ) {

		StringBuilder sb = new StringBuilder();

		sb.append(" SELECT");
		sb.append("   CT.NUMSECUENCIA,");
		sb.append("   CT.ORIGEN_ID, ");
		sb.append("   CT.DESTINO_ID, ");
		sb.append("   CT.TRAMO_ID ");
		sb.append(" FROM CORRIDA C");
		sb.append(" JOIN CORRIDA_TRAMO CT ON CT.CORRIDA_ID = C.CORRIDA_ID AND CT.FECCORRIDA = C.FECCORRIDA");
		sb.append(" WHERE C.CORRIDA_ID = :corridaId AND C.FECCORRIDA = :feccorrida and CT.activo = 1 ");
		sb.append(" ORDER BY CT.NUMSECUENCIA ");

		Query query = getSession().createSQLQuery(sb.toString());

		query.setParameter("corridaId", corrida.getId().getCorridaId());
		query.setParameter("feccorrida", corrida.getId().getFeccorrida());

		List<SecuenciaVO> lsSecuenciaVO = new ArrayList<SecuenciaVO>();
		List<Integer> lsTramoVO = new ArrayList<Integer>();
		List<String> controle = new ArrayList<String>();
		
		List<Object[]> list = query.list();

		for (Object[] item : list) {
			final Integer origensecuencia = Integer.valueOf(item[0].toString());
			final Integer origen_id = Integer.valueOf(item[1].toString());

			final Integer destinosecuencia = Integer.valueOf(item[0].toString()) + 1;
			final Integer destino_id = Integer.valueOf(item[2].toString());

			adicionarSequencia(
					controle,
					lsSecuenciaVO,
					origensecuencia,
					origen_id);

			adicionarSequencia(
					controle,
					lsSecuenciaVO,
					destinosecuencia,
					destino_id);
			
			//adiciona o id do tramo
			lsTramoVO.add(Integer.valueOf(item[3].toString()));
		}

		corridaVO.setListTramos( lsTramoVO );
		corridaVO.setLsSecuenciaVO( lsSecuenciaVO );
	}
	
	private void adicionarSequencia(List<String> controle, List<SecuenciaVO> lsSecuenciaVO, final Integer numsecuencia, final Integer paradaId) {
		final String key = numsecuencia.toString() + "|" + paradaId.toString();

		if (!controle.contains(key)) {
			SecuenciaVO sequencia = new SecuenciaVO();
			sequencia.setSecuencia(numsecuencia);
			sequencia.setLocalidadeId(paradaId);

			lsSecuenciaVO.add(sequencia);

			controle.add(key);
		}
	}
	
	public Integer buscarOcupacaoCorrida(Corrida corrida) {
		try {
			if(corrida == null) {
				return 0;
			}
			//TODO: VERIFICAR ERRO NA PESQUISA
			StringBuilder sb = new StringBuilder();

			sb.append(" SELECT");
			sb.append("   COUNT(BOLETO_ID) ");
			sb.append(" FROM ");
			sb.append("   BOLETO ");
			sb.append(" WHERE ");
			sb.append(" 	ACTIVO = 1 AND motivocancelacion_id IS NULL AND ");
			sb.append("  	CORRIDA_ID = :corridaId AND FECCORRIDA = :feccorrida ");

			Query query = getSession().createSQLQuery(sb.toString());
			query.setParameter("corridaId", corrida.getId().getCorridaId());
			query.setParameter("feccorrida", corrida.getId().getFeccorrida());
			
			BigDecimal resultado = (BigDecimal) query.uniqueResult();

			return resultado.intValue();
		} catch (Exception e) {
			log.error("Erro ao buscar ocupacao da corrida: " + corrida.getId().getCorridaId() + " - " + corrida.getId().getFeccorrida(), e);
		}
		
		return 0;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<Corrida> buscarCorridas(Parada ori, Parada des, Date dataInicial, Date dataFinal, ClaseServicio cs,
			Ruta linha, Empresa empresa) {
		
		StringBuilder hql = new StringBuilder("");
		hql.append("select distinct ");
		hql.append("    new com.rjconsultores.ventaboletos.entidad.Corrida(");
		hql.append("	c.marca, ");
		hql.append("	c.id.corridaId, ");
		hql.append("	c.id.feccorrida, ");
		hql.append("	c.origem, ");
		hql.append("	c.destino, ");
		hql.append("	c.claseServicio, ");
		hql.append("	c.corridaCtrl.horario) ");
		hql.append("from ");
		hql.append("	Corrida c ");
		hql.append(" where c.activo = 1 ");
		
		if (empresa != null) {
			hql.append("	and c.empresa = :empresa ");
		}
		if (linha != null) {
			hql.append("	and c.ruta = :linha ");
		}
		if (ori != null) {
			hql.append("	and c.origem = :origen ");
		}
		if (des != null) {
			hql.append("	and c.destino = :destino");
		}
		if (cs != null) {
			hql.append("	and c.claseServicio = :claseServicio ");
		}
		if (dataInicial != null) {

			hql.append("	and c.corridaCtrl.horario >= :horaSalidaInicio");
		}
		if (dataFinal != null) {

			hql.append("	and c.corridaCtrl.horario <= :horaSalidaFin");
		}

		hql.append("  order by c.id.corridaId,c.corridaCtrl.horario");

		Query query = getSession().createQuery(hql.toString());
		
		if (empresa != null) {
			query.setParameter("empresa", empresa);
		}
		if (linha != null) {
			query.setParameter("linha", linha);
		}
		if (ori != null) {
			query.setParameter("origen", ori);
		}
		if (des != null) {
			query.setParameter("destino", des);
		}
		if (cs != null) {
			query.setParameter("claseServicio", cs);
		}

		if (dataInicial != null) {

			query.setParameter("horaSalidaInicio", dataInicial);
		}
		if (dataFinal != null) {
			query.setParameter("horaSalidaFin", dataFinal);

		}

		return query.list();
	}

	@Transactional
	public void borrar(Corrida entidad) {
		try {
			entidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
			entidad.setFecmodif(Calendar.getInstance().getTime());
			entidad.setActivo(0);
			actualizacion(entidad);
		} catch (Exception e) {
			log.error("Erro ao inativar Corrida ", e);
		}
	}
}
