package com.rjconsultores.ventaboletos.dao.hibernate;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import com.rjconsultores.ventaboletos.constantes.TipoSeguro;
import com.rjconsultores.ventaboletos.dao.TarifaOficialDAO;
import com.rjconsultores.ventaboletos.dao.sqlbuilder.SQLBuilder;
import com.rjconsultores.ventaboletos.entidad.ClaseServicio;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.Marca;
import com.rjconsultores.ventaboletos.entidad.Moneda;
import com.rjconsultores.ventaboletos.entidad.OrgaoConcedente;
import com.rjconsultores.ventaboletos.entidad.Parada;
import com.rjconsultores.ventaboletos.entidad.Ruta;
import com.rjconsultores.ventaboletos.entidad.TarifaOficial;
import com.rjconsultores.ventaboletos.entidad.VigenciaTarifa;
import com.rjconsultores.ventaboletos.utilerias.ApplicationProperties;
import com.rjconsultores.ventaboletos.utilerias.CustomEnum;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.vo.comissao.TarifaOficialComComposicaoDoPedagioVo;
import com.rjconsultores.ventaboletos.vo.comissao.TarifaOficialVO;

@Repository("tarifaOficialDAO")
public class TarifaOficialHibernateDAO extends GenericHibernateDAO<TarifaOficial, Integer> implements TarifaOficialDAO {

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

	@Autowired
	private SQLBuilder sqlBuilder;

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

	@Override
	public Integer gerarTarifaPorCoeficiente(Integer rutaId, Integer usuarioId, OrgaoConcedente orgaoConcedente, List<Integer> idsEmpresas, Integer[] lsCasetaPeaje) {

		String sql = sqlBuilder.getSQLGerarTarifaOficial(rutaId, usuarioId, orgaoConcedente, idsEmpresas,lsCasetaPeaje);

		int qtd = getSession().createSQLQuery(sql).executeUpdate();

		return qtd;
	}

	@Override
	public Integer gerarTarifaArtesp(Integer rutaId, Integer usuarioId, Integer orgaoConcedenteId, List<Integer> idsEmpresas) {

		String sql = sqlBuilder.getSQLGerarTarifaOficialArtesp(rutaId, usuarioId, orgaoConcedenteId, idsEmpresas);

		int qtd = getSession().createSQLQuery(sql).executeUpdate();

		return qtd;
	}

	@Override
	public Integer gerarTabelaZerada(Integer rutaId, Integer usuarioId, Integer orgaoConcedenteId, List<Integer> idsEmpresas,List<Integer>lsParadaId) {

		String sql = sqlBuilder.getSQLGerarTabelaZerada(rutaId, usuarioId, orgaoConcedenteId, idsEmpresas,lsParadaId);

		int qtd = getSession().createSQLQuery(sql).executeUpdate();

		return qtd;
	}

	@Override
	public Integer atualizarTarifaCoeficiente(Integer rutaId, Integer usuarioId, OrgaoConcedente orgaoConcedente) {

		String sql = sqlBuilder.getSQLAtualizarTarifaOficial(rutaId, usuarioId, orgaoConcedente);

		int qtd = getSession().createSQLQuery(sql).executeUpdate();

		return qtd;
	}

	@Override
	public void limparTarifasOficiais(List<Empresa> lsEmpresaSelected) {

		String query = "DELETE FROM TarifaOficial ";
		if (lsEmpresaSelected != null && !lsEmpresaSelected.isEmpty()) {
			query += "WHERE tarifaOficialId IN ( ";
			query += " SELECT t.tarifaOficialId FROM TarifaOficial t WHERE t.marca.empresa.empresaId IN (";
			for (Empresa e : lsEmpresaSelected) {
				query += e.getEmpresaId() + ",";
			}
			query = query.substring(0, query.length() - 1);
			query += "))";
		}
		Query q = getSession().createQuery(query);
		q.executeUpdate();
	}

	private void apagarTarifasInativas(VigenciaTarifa vigenciaTarifa, Empresa empresa, OrgaoConcedente orgao) {
		StringBuilder sb = new StringBuilder("");
		sb.append("select ");
		sb.append("	tar.tarifaId   ");
		sb.append("from ");
		sb.append("	Tarifa tar,TarifaOficial tao ");
		sb.append("where ");
		sb.append("	tar.activo=0 ");
		sb.append("	and tao.activo = 1 ");
		sb.append("	and tar.tramo=tao.tramo  ");
		sb.append("	and tar.marca=tao.marca   ");
		sb.append("	and tar.claseServicio =tao.claseServicio   ");
		sb.append("	and tar.moneda=tao.moneda   ");
		sb.append("	and tar.orgaoConcedente=tao.orgaoConcedente ");
		sb.append("	and tar.ruta=tao.ruta ");
		sb.append("	and tar.vigenciaTarifa.vigenciatarifaId = :vigenciaId ");

		if (orgao != null) {
			sb.append("	and tar.orgaoConcedente = :orgao ");
		}
		if (empresa != null) {
			sb.append("	and tar.marca.empresa = :empresa ");
		}

		Query query = getSession().createQuery("DELETE FROM TarifaTipoptovta WHERE tarifa.tarifaId in (" + sb.toString() + ")");
		query.setParameter("vigenciaId", vigenciaTarifa.getVigenciatarifaId());

		if (orgao != null) {
			query.setParameter("orgao", orgao);
		}
		if (empresa != null) {
			query.setParameter("empresa", empresa);
		}

		int qtd = query.executeUpdate();
		log.info("qtd TarifaTipoptovta apagada = " + qtd);

		query = getSession().createQuery("DELETE FROM TarifaCategoria WHERE tarifa.tarifaId in (" + sb.toString() + ")");
		query.setParameter("vigenciaId", vigenciaTarifa.getVigenciatarifaId());
		if (orgao != null) {
			query.setParameter("orgao", orgao);
		}
		if (empresa != null) {
			query.setParameter("empresa", empresa);
		}

		qtd = query.executeUpdate();
		log.info("qtd TarifaCategoria apagada = " + qtd);

		query = getSession().createQuery("DELETE FROM Tarifa WHERE activo = 0 and tarifaId in (" + sb.toString() + ")");
		query.setParameter("vigenciaId", vigenciaTarifa.getVigenciatarifaId());
		if (orgao != null) {
			query.setParameter("orgao", orgao);
		}
		if (empresa != null) {
			query.setParameter("empresa", empresa);
		}

		qtd = query.executeUpdate();
		log.info("qtd Tarifa apagada = " + qtd);
	}

	@SuppressWarnings("unchecked")
	@Override
	public void copiarParaTarifa(VigenciaTarifa vigenciaTarifa, Integer usuarioId, Boolean calculaPegagio, Boolean calculaTarifa, Boolean calculaTaxaEmbarque, Boolean calculaSeguro, Boolean calculaTPP, Boolean calculaEmbarcada, Empresa empresa, OrgaoConcedente orgaoConcedente) {
		// Apago antes as tarifas que podem estar como activo =0
		apagarTarifasInativas(vigenciaTarifa, empresa, orgaoConcedente);

		// Insiro as tarifas que não existem
		SQLQuery querySQL = getSession().createSQLQuery(sqlBuilder.getSQLInserirTarifaPelaTarifaOficial(vigenciaTarifa.getVigenciatarifaId(), usuarioId, empresa, orgaoConcedente));
		querySQL.executeUpdate();
		// Atualizo o preço e o componente dos preços que já existem
		querySQL = getSession().createSQLQuery(sqlBuilder.getSQLSelecionarTarifaPorTarifaOficalParaAtualizar(vigenciaTarifa.getVigenciatarifaId(), empresa, orgaoConcedente));
		querySQL.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		List<Map<String, Object>> dados = querySQL.list();
		for (Map<String, Object> dado : dados) {
			querySQL = getSession().createSQLQuery(sqlBuilder.getSQLAtualizarTarifaPorTarifaOfical(dado, usuarioId, calculaPegagio, calculaTarifa, calculaTaxaEmbarque, calculaSeguro, calculaTPP));
			querySQL.executeUpdate();
		}
		
		if (Boolean.TRUE.equals(calculaEmbarcada)) {
			copiarParaTarifaEmbarcada(vigenciaTarifa, usuarioId, calculaPegagio, calculaTarifa, calculaTaxaEmbarque, calculaSeguro, calculaTPP, calculaEmbarcada, empresa, orgaoConcedente);
		}
	}
	
	@SuppressWarnings("unchecked")
	private void copiarParaTarifaEmbarcada(VigenciaTarifa vigenciaTarifa, Integer usuarioId, Boolean calculaPegagio, Boolean calculaTarifa, Boolean calculaTaxaEmbarque, Boolean calculaSeguro, Boolean calculaTPP, Boolean calculaEmbarcada, Empresa empresa, OrgaoConcedente orgaoConcedente) {
		// Apago antes as tarifas embarcadas que podem estar como activo =0
		apagarTarifasEmbarcadasInativas(vigenciaTarifa, empresa, orgaoConcedente);
		
		// Insiro as tarifas embarcadas que não existem
		SQLQuery querySQL = getSession().createSQLQuery(sqlBuilder.getSQLInserirTarifaEmbarcadaPelaTarifaOficial(vigenciaTarifa.getVigenciatarifaId(), usuarioId, empresa, orgaoConcedente));
		querySQL.executeUpdate();
		
		// Atualizo o preço e o componente dos preços que já existem
		querySQL = getSession().createSQLQuery(sqlBuilder.getSQLSelecionarTarifaEmbarcadaPorTarifaOficalParaAtualizar(vigenciaTarifa.getVigenciatarifaId(), empresa, orgaoConcedente));
		querySQL.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		
		List<Map<String, Object>> dados = querySQL.list();
		
		for (Map<String, Object> dado : dados) {
			querySQL = getSession().createSQLQuery(sqlBuilder.getSQLAtualizarTarifaEmbarcadaPorTarifaOfical(dado, usuarioId, calculaPegagio, calculaTarifa, calculaTaxaEmbarque, calculaSeguro, calculaTPP));
			querySQL.executeUpdate();
		}
	}
	
	@Override
	public void atualizarTaxaEmbarque(List<Ruta> lsRuta, Integer usuarioId, Integer orgaoConcedenteId, List<Integer> idsEmpresas,List<Integer> lsParadaIds) {

		int x = 0;

		if (lsRuta != null && !lsRuta.isEmpty()) {
			x = lsRuta.size();
		}

		do {
			Integer rutaId = null;

			if (lsRuta != null && !lsRuta.isEmpty()) {
				rutaId = lsRuta.get(x - 1).getRutaId();
			}

			// Atualizo a taxa de embarque de acordo a parada e km
			SQLQuery query = getSession().createSQLQuery(sqlBuilder.getAtualizarTaxaEmbarquePorKmParada(rutaId, usuarioId, orgaoConcedenteId, idsEmpresas,lsParadaIds));
			query.executeUpdate();

			// Atualizo a taxa de embarque de acordo a km do orgao
			query = getSession().createSQLQuery(sqlBuilder.getSQLAtualizarTaxaEmbarquePorKmOrgao(rutaId, usuarioId, orgaoConcedenteId, idsEmpresas,lsParadaIds));
			query.executeUpdate();

			// Atualizo a taxa de embarque de acordo a parada e valor fixo
			query = getSession().createSQLQuery(sqlBuilder.getSQLAtualizarTaxaEmbarquePorParadaFixo(rutaId, usuarioId, orgaoConcedenteId, idsEmpresas,lsParadaIds));
			query.executeUpdate();
			x--;
		} while (x > 0);
	}

	@Override
	public void atualizarSeguroPorKm(Integer rutaId, Integer orgaoId, Integer usuarioId, TipoSeguro tipoSeguro) {
		SQLQuery query = getSession().createSQLQuery(sqlBuilder.getSQLAtualizarSeguroPorKm(rutaId, usuarioId, orgaoId, tipoSeguro));
		query.executeUpdate();
	}

	@Override
	public void atualizarPrecioPorTPP(Integer rutaId, Integer orgaoId, Integer usuarioId, TipoSeguro tipoSeguro) {
		SQLQuery query = getSession().createSQLQuery(sqlBuilder.getSQLAtualizarPrecioPorTPP(rutaId, usuarioId, orgaoId, tipoSeguro));
		query.executeUpdate();
	}

	@Override
	public void atualizarSeguroPorTarifa(Integer rutaId, Integer orgaoId, Integer usuarioId) {
		SQLQuery query = getSession().createSQLQuery(sqlBuilder.getSQLAtualizarSeguroPorTarifa(rutaId, usuarioId, orgaoId));
		query.executeUpdate();
	}

	@Override
	public long obtenerCount(List<Empresa> lsEmpresaSelected) {
		String query = " select count(*) from  TarifaOficial ";
		if (lsEmpresaSelected != null && !lsEmpresaSelected.isEmpty()) {
			query += "WHERE tarifaOficialId IN ( ";
			query += " SELECT t.tarifaOficialId FROM TarifaOficial t WHERE t.marca.empresa.empresaId IN (";
			for (Empresa e : lsEmpresaSelected) {
				query += e.getEmpresaId() + ",";
			}
			query = query.substring(0, query.length() - 1);
			query += "))";
		}

		long qtd = 0;
		Query q = getSession().createQuery(query);

		qtd = (Long) q.list().get(0);

		return qtd;
	}

	@Override
	public void aplicarArredondamentoTarifa(Integer orgaoConcedenteId, Integer usuarioId, Boolean taxaEmbarque) {
		StringBuilder sql = new StringBuilder();
		sql.append(" UPDATE TarifaOficial tao ");
		sql.append(" SET tao.precio = FN_ARREDONDAMENTO_TARIFA(tao.precio,tao.orgaoConcedente.orgaoConcedenteId,tao.importeseguro,tao.importetaxaembarque,tao.importepedagio,tao.importeoutros,:txEmbarque), ");
		sql.append(" tao.activo = true , ");
		sql.append(" tao.fecmodif= CURRENT_TIMESTAMP(), ");
		sql.append(" tao.usuarioId =:usuarioId ");

		if (orgaoConcedenteId != null) {
			sql.append(" WHERE tao.orgaoConcedente.orgaoConcedenteId = :orgao ");
		}

		Query query = getSession().createQuery(sql.toString());
		if (orgaoConcedenteId != null) {
			query.setParameter("orgao", orgaoConcedenteId);
		}
		query.setInteger("txEmbarque", taxaEmbarque ? 1 : 0);
		query.setParameter("usuarioId", usuarioId);
		query.executeUpdate();
	}

	@Override
	@SuppressWarnings("deprecation")
	public void atualizarPedagio() {
		StringBuilder sql = new StringBuilder();

		if (ApplicationProperties.getInstance().isCustomHabilitado(CustomEnum.ARTESP_PEDAGIO_IDA_VOLTA_DIV_POR2.getDescricao())) {
			sql.append(" merge into tarifa_oficial  ");
			sql.append(" using  ");
			sql.append(" ( ");
			sql.append(" WITH tarifas_ofic as ( ");
			sql.append(" select tarifaoficial_id, ORGAOCONCEDENTE_ID, ruta_id , origen_id , DESTINO_ID, MARCA_ID  from tarifa_oficial where  activo = 1");
			sql.append(" ),  ");

			sql.append(" 		      noArtesp as (select  p.destino_id dest, p.origen_id as orig , p.ruta_id as idruta ,p.orgaoconcedente_id as idorgao, ");
			sql.append(" 		        p.importepeaje as importe , p.activo as actv,  m.marca_id as marca from peaje p inner join tarifas_ofic tof on ");
			sql.append(" 		      p.ORGAOCONCEDENTE_ID = tof.ORGAOCONCEDENTE_ID and p.ruta_id = tof.ruta_id ");
			sql.append(" 		      and p.ORIGEN_ID = tof.ORIGEN_ID and p.DESTINO_ID = tof.DESTINO_ID and p.activo = 1 ");
			sql.append("              inner join ruta_empresa re on p.ruta_id=re.ruta_id ");
			sql.append("              inner join marca m on m.marca_id=tof.marca_id where re.empresa_id=m.empresa_id), ");

			sql.append(" 		     linha as ( select * from ruta where ruta_id in (select ruta_id from tarifas_ofic   ) )   , ");
			sql.append(" 		     linha_voltaId as (select ru.ruta_id rutavolta_id, t_1.ruta_id as ida from ruta ru  ");
			sql.append(" 		                                 inner join linha t_1 on ru.prefixo like t_1.prefixo  ");
			sql.append(" 		                                 and ru.orgaoconcedente_id = t_1.orgaoconcedente_id  ");
			sql.append(" 		                                 and ru.indsentidoIda <> t_1.indsentidoIda ");
			sql.append(" 		                                 and   (   (ru.numruta like t_1.numruta) or    (ru.numruta like (to_char(to_Number(t_1.numruta)+1)))   ) ");
			sql.append(" 		                                 and ru.ruta_id <> t_1.ruta_id  ");
			sql.append(" 		                                 and ru.claseservicio_id = t_1.claseservicio_id ");
			sql.append(" 		                                 where ru.activo = 1), ");

			sql.append(" 		    artesp as ( ");
			sql.append(" 		      SELECT * ");
			sql.append(" 		      FROM peaje p ");
			sql.append(" 		      INNER JOIN tarifas_ofic tof ");
			sql.append(" 		      ON p.ORGAOCONCEDENTE_ID = tof.ORGAOCONCEDENTE_ID ");
			sql.append(" 		      AND p.ruta_id           = tof.ruta_id ");
			sql.append(" 		      AND p.ORIGEN_ID         = tof.ORIGEN_ID ");
			sql.append(" 		      AND p.DESTINO_ID        = tof.DESTINO_ID ");
			sql.append(" 		      AND p.activo            = 1  ");

			sql.append(" 		      union ");

			sql.append(" 		      SELECT * ");
			sql.append(" 		      FROM peaje p ");
			sql.append(" 		      INNER JOIN tarifas_ofic tof ");
			sql.append(" 		      ON p.ORGAOCONCEDENTE_ID = tof.ORGAOCONCEDENTE_ID ");
			sql.append(" 		      AND p.ruta_id           = (select rutavolta_id from  linha_voltaId where linha_voltaId.ida =  tof.ruta_id) ");
			sql.append(" 		      AND p.DESTINO_ID         = tof.ORIGEN_ID ");
			sql.append(" 	          AND p.ORIGEN_ID        = tof.DESTINO_ID ");
			sql.append(" 		      AND p.activo            = 1 ");
			sql.append(" 		      AND p.ruta_id           = (select rutavolta_id from  linha_voltaId where linha_voltaId.ida =  tof.ruta_id) ");
			sql.append(" 		    ) , ");
			sql.append(" 		    resultado as ( ");
			sql.append(" 		    select distinct tof.tarifaoficial_id tarifaoficial_id, tof.ruta_id as ruta, ");
			sql.append(" 		          ( case  tof.orgaoconcedente_id ");
			sql.append(" 		            when 21 then ( select (sum(round(importepeaje,2))/2) from artesp ar where ar.tarifaoficial_id  = tof.tarifaoficial_id ) ");
			sql.append(" 		            else (  select distinct sum(noar.importe) from noArtesp noar where noar.idorgao = tof.ORGAOCONCEDENTE_ID and noar.idruta = tof.ruta_id ");
			sql.append(" 		                    and noar.ORIG = tof.ORIGEN_ID and noar.DEST = tof.DESTINO_ID and noar.actv = 1  )  ");
			sql.append(" 		            end ) importepeaje from tarifas_ofic tof ");
			sql.append(" 		            ), ");
			sql.append(" 				peaje_tarifas as ( select * from resultado  ) ");
			sql.append("     select  pf.tarifaoficial_id , sum(round(importepeaje,2)) as soma from peaje_tarifas pf Group by pf.tarifaoficial_id ");
			sql.append("    ");
			sql.append(" ) tarifa_importe ");
			sql.append(" on (tarifa_oficial.tarifaoficial_id =  tarifa_importe.tarifaoficial_id) ");
			sql.append(" when matched then  ");
			sql.append(" update set  ");
			sql.append(" importepedagio = tarifa_importe.soma ");
		} else {			
			sql.append(" merge into tarifa_oficial  ");
			sql.append(" using  ");
			sql.append(" ( ");
			sql.append("   WITH tarifas_ofic as ( ");
			sql.append("     select tarifaoficial_id, ORGAOCONCEDENTE_ID, ruta_id , origen_id , DESTINO_ID  from tarifa_oficial ");
			sql.append("   ), ");
			sql.append("   peaje_tarifas as ( ");
			sql.append("     select * from peaje p inner join tarifas_ofic tof on  ");
			sql.append("     p.ORGAOCONCEDENTE_ID = tof.ORGAOCONCEDENTE_ID and p.ruta_id = tof.ruta_id  ");
			sql.append("     and p.ORIGEN_ID = tof.ORIGEN_ID and p.DESTINO_ID = tof.DESTINO_ID  and p.activo = 1 ");
			sql.append("   ) ");
			sql.append("     select  pf.tarifaoficial_id , sum(round(importepeaje,2)) as soma,");
			sql.append(" LISTAGG(casetapeaje_id||';'||peaje_id,',') WITHIN GROUP (ORDER BY casetapeaje_id) as  composicaoDoPeaje ");
			sql.append(" from peaje_tarifas pf Group by pf.tarifaoficial_id ");
			sql.append("    ");
			sql.append(" ) tarifa_importe ");
			sql.append(" on (tarifa_oficial.tarifaoficial_id =  tarifa_importe.tarifaoficial_id) ");
			sql.append(" when matched then  ");
			sql.append(" update set  ");
			sql.append(" composicao_do_peaje = tarifa_importe.composicaoDoPeaje,");
			sql.append(" importepedagio = tarifa_importe.soma ");

		}

		Connection conn = getSession().connection();
		Statement stmt;
		try {
			stmt = conn.createStatement();
			stmt.executeUpdate(sql.toString());
		} catch (SQLException e) {
			e.printStackTrace();
			log.error("Erro na atualização do pedágio");
		}
	}

	@Override
	public List<TarifaOficialVO> obterTarifaOficialPorFiltroVO(Moneda moneda, Marca marca, List<Marca> lsMarcas, Parada origem, Parada destino, ClaseServicio claseServicio, Ruta ruta, String numRuta, Boolean vende) {
		// TODO Auto-generated method stub

		StringBuilder sql = new StringBuilder(" SELECT ");
		sql.append(" t.tarifaoficial_id tarifaoficialid,");
		sql.append(" t.PRECIO precio,");
		sql.append(" t.PRECIOORIGINAL preciooriginal,");
		sql.append(" t.IMPORTEPEDAGIO importepedagio,");
		sql.append(" t.IMPORTETAXAEMBARQUE importetaxaembarque,");
		sql.append(" t.IMPORTESEGURO importeseguro,");
		sql.append(" t.IMPORTETPP importetpp,");
		sql.append(" t.IMPORTEOUTROS importeoutros,");		
		sql.append(" origem.DESCPARADA descparadaOrigem,");
		sql.append(" destino.DESCPARADA descparadaDestino,");
		sql.append(" via.NOMBVIA nomeVia,");
		sql.append(" ma.DESCMARCA descMarca,");
		sql.append(" cl.DESCCLASE descclasse,");
		sql.append(" oc.DESCORGAO descorgao,");
		sql.append(" r.prefixo rutaprefixo,");
		sql.append(" r.numruta numruta");
		sql.append(" FROM TARIFA_OFICIAL t");
		sql.append(" LEFT JOIN TRAMO tr on (tr.TRAMO_ID = t.TRAMO_ID)");
		sql.append(" LEFT JOIN ruta r ON ( r.ruta_id = t.ruta_id )");
		sql.append(" LEFT JOIN VIA via on (VIA.VIA_ID=tr.VIA_ID)");
		sql.append(" LEFT JOIN PARADA origem on (origem.PARADA_ID=tr.ORIGEN_ID)");
		sql.append(" LEFT JOIN PARADA destino on (destino.PARADA_ID=tr.DESTINO_ID)");
		sql.append(" LEFT JOIN MARCA ma on (ma.MARCA_ID = t.MARCA_ID)");	
		sql.append(" LEFT JOIN CLASE_SERVICIO cl ON (cl.CLASESERVICIO_ID=t.CLASESERVICIO_ID)");
		sql.append(" LEFT JOIN ORGAO_CONCEDENTE oc ON (oc.ORGAOCONCEDENTE_ID=t.ORGAOCONCEDENTE_ID)");

		if (vende != null) {
			sql.append(" LEFT JOIN RUTA_COMBINACION rc on (rc.tramo_id = tr.tramo_id)");
		}
		sql.append(" WHERE ");
		sql.append(" t.activo=1 ");
		if (moneda != null) {
			sql.append(" and t.moneda_id=" + moneda.getMonedaId());
		}
		if (marca != null) {
			sql.append(" and t.marca_id=" + marca.getMarcaId());
		} else {
			String stringMarca =" and t.marca_id in (";
			int contador =0;
			for(Marca m:lsMarcas){
				if(contador==0){
					stringMarca=stringMarca+m.getMarcaId().toString();
				}else{
					stringMarca=stringMarca+","+m.getMarcaId();
				}
				contador++;
				if(lsMarcas.size()==contador){
					stringMarca=stringMarca+")";
				}
			}
			sql.append(stringMarca);

		}
		if (ruta != null) {
			sql.append(" and t.ruta_id=" + ruta.getRutaId());
		}
		if (numRuta != null) {
			sql.append(" and r.numruta=" + numRuta);
		}
		if (origem != null) {
			sql.append(" and origem.parada_id=" + origem.getParadaId());
		}
		if (destino != null) {
			sql.append(" and destino.parada_id=" + destino.getParadaId());
		}
		if (claseServicio != null) {
			sql.append(" and t.claseservicio_id=" + claseServicio.getClaseservicioId());
		}

		if (vende != null) {
			int simNao = vende ? 1 : 0;
			sql.append(" and rc.tramo_id=t.tramo_id and rc.ruta_id=t.ruta_id and rc.activo=1 and rc.INDVENTA=" + simNao);
		}
	
		Query qr = getSession().createSQLQuery(sql.toString()).addScalar("tarifaoficialid", Hibernate.INTEGER).addScalar("precio", Hibernate.BIG_DECIMAL).addScalar("preciooriginal", Hibernate.BIG_DECIMAL).addScalar("importepedagio", Hibernate.BIG_DECIMAL).addScalar("importetaxaembarque", Hibernate.BIG_DECIMAL).addScalar("importeseguro", Hibernate.BIG_DECIMAL).addScalar("importetpp", Hibernate.BIG_DECIMAL).addScalar("importeoutros", Hibernate.BIG_DECIMAL).addScalar("descparadaorigem", Hibernate.STRING).addScalar("descparadadestino", Hibernate.STRING).addScalar("nomevia", Hibernate.STRING).addScalar("descmarca", Hibernate.STRING).addScalar("descclasse", Hibernate.STRING).addScalar("descorgao", Hibernate.STRING).addScalar("rutaprefixo", Hibernate.STRING).addScalar("numruta", Hibernate.STRING).setResultTransformer(Transformers.aliasToBean(TarifaOficialVO.class));
	
		return (List<TarifaOficialVO>) qr.list();
	}
	
	private void apagarTarifasEmbarcadasInativas(VigenciaTarifa vigenciaTarifa, Empresa empresa, OrgaoConcedente orgao) {
		StringBuilder sb = new StringBuilder("");
		sb.append("select ");
		sb.append("	tar.tarifaembarcadaId   ");
		sb.append("from ");
		sb.append("	TarifaEmbarcada tar,TarifaOficial tao ");
		sb.append("where ");
		sb.append("	tar.activo=0 ");
		sb.append("	and tao.activo = 1 ");
		sb.append("	and tar.tramo=tao.tramo  ");
		sb.append("	and tar.marca=tao.marca   ");
		sb.append("	and tar.claseServicio =tao.claseServicio   ");
		sb.append("	and tar.moneda=tao.moneda   ");
		sb.append("	and tar.orgaoConcedente=tao.orgaoConcedente ");
		sb.append("	and tar.ruta=tao.ruta ");
		sb.append("	and tar.vigenciaTarifa.vigenciatarifaId = :vigenciaId ");

		if (orgao != null) {
			sb.append("	and tar.orgaoConcedente = :orgao ");
		}
		if (empresa != null) {
			sb.append("	and tar.marca.empresa = :empresa ");
		}

		Query query = getSession().createQuery("DELETE FROM TarifaEmbarcada WHERE activo = 0 and tarifaembarcadaId in (" + sb.toString() + ")");
		query.setParameter("vigenciaId", vigenciaTarifa.getVigenciatarifaId());
		if (orgao != null) {
			query.setParameter("orgao", orgao);
		}
		if (empresa != null) {
			query.setParameter("empresa", empresa);
		}

		int qtd = query.executeUpdate();
		log.info("qtd Tarifa Embarcada apagada = " + qtd);
	}
	
	@Override
	public List<TarifaOficialComComposicaoDoPedagioVo> oberTarifaOficialComComposicaoDoPedagioVo(Integer empresaId) {
		StringBuilder sql = new StringBuilder(" SELECT ");
		sql.append(" tof.tarifaoficial_id as tarifaOficialId, ");
		sql.append(" ta.COMPOSICAO_DO_PEAJE as composicaoDoPedagioNaTarifa, ");
		sql.append(" LISTAGG(p.casetapeaje_id||';'||p.peaje_id,',')\r\n"
				+ "WITHIN GROUP (ORDER BY p.casetapeaje_id) as  composicaoDoPedagioNaTarifaOficialComPeaje");
		sql.append(" FROM tarifa_oficial tof ");
		sql.append(" INNER JOIN marca m ON m.marca_id=tof.marca_id ");
		sql.append(" INNER join tarifa ta on ");
		sql.append(" ( tof.MARCA_ID   = ta.MARCA_ID ");
		sql.append(" AND tof.CLASESERVICIO_ID   = ta.CLASESERVICIO_ID ");
		sql.append(" AND tof.TRAMO_ID           = ta.TRAMO_ID ");
		sql.append(" AND tof.MONEDA_ID          = ta.MONEDA_ID ");
		sql.append(" AND tof.RUTA_ID            = ta.RUTA_ID ");
		sql.append(" AND tof.ORGAOCONCEDENTE_ID = ta.ORGAOCONCEDENTE_ID ");
		sql.append(" AND tof.ACTIVO = 1 ");
		sql.append(" AND ta.ACTIVO = 1 ) ");

		sql.append(" INNER JOIN VIGENCIA_TARIFA vg on ta.VIGENCIATARIFA_ID=vg.VIGENCIATARIFA_ID");
		sql.append(" and vg.FECINICIOVIGENCIA<= TO_DATE(:dataInicial,'DD/MM/YYYY hh24:mi') ");
		sql.append(" and vg.FECFINVIGENCIA>= TO_DATE(:dataFinal,'DD/MM/YYYY hh24:mi')");
		sql.append(" INNER JOIN PEAJE p");
		sql.append(" ON p.ORGAOCONCEDENTE_ID = tof.ORGAOCONCEDENTE_ID");
		sql.append(" AND p.ruta_id= tof.ruta_id");
		sql.append(" AND p.ORIGEN_ID         = tof.ORIGEN_ID");
		sql.append(" AND p.DESTINO_ID        = tof.DESTINO_ID");
		sql.append(" AND p.activo            = 1");
		sql.append(" AND m.empresa_id=:empresaId ");
		sql.append(" AND m.activo            = 1 ");
		sql.append(" AND ta.ORIGEN_ID = tof.ORIGEN_ID ");
		sql.append(" AND ta.DESTINO_ID = tof.DESTINO_ID ");
		sql.append(" AND p.ORIGEN_ID  = ta.ORIGEN_ID ");
		sql.append(" AND p.DESTINO_ID  = ta.DESTINO_ID ");
		sql.append(" AND p.ruta_id= ta.ruta_id ");
		sql.append(" AND p.ORGAOCONCEDENTE_ID = ta.ORGAOCONCEDENTE_ID ");
		sql.append(" group by ta.tarifa_id,tof.tarifaoficial_id,ta.tarifa_id,ta.COMPOSICAO_DO_PEAJE");
		
		Query query = getSession().createSQLQuery(sql.toString());
				
		Query qr = getSession().createSQLQuery(sql.toString()).addScalar("tarifaOficialId", Hibernate.INTEGER).addScalar("composicaoDoPedagioNaTarifa", Hibernate.STRING).addScalar("composicaoDoPedagioNaTarifaOficialComPeaje", Hibernate.STRING).setResultTransformer(Transformers.aliasToBean(TarifaOficialComComposicaoDoPedagioVo.class));
		qr.setParameter("empresaId", empresaId);
		qr.setParameter("dataInicial", DateUtil.getStringDate(DateUtil.inicioFecha(new Date()), "dd/MM/yyyy HH:mm"));
		qr.setParameter("dataFinal", DateUtil.getStringDate(DateUtil.fimFecha(new Date()), "dd/MM/yyyy HH:mm"));

		return (List<TarifaOficialComComposicaoDoPedagioVo>) qr.list();
		
		

		
	}

	@Override
	public void atualizarPedagioComFiltroDePracaDePedagio(Integer tarifaOficialId, BigDecimal importePedagio, String composicaoPedagio) {
		StringBuilder sb = new StringBuilder("");
		sb.append("update tarifa_oficial set IMPORTEPEDAGIO =:importePedagio,  ");
		sb.append("COMPOSICAO_DO_PEAJE =:composicaoDoPedagio  ");
		sb.append("WHERE tarifaoficial_id=:tarifaOficialId");
		
		Query query = getSession().createSQLQuery(sb.toString());
		query.setBigDecimal("importePedagio", importePedagio);
		query.setString("composicaoDoPedagio", composicaoPedagio);
		query.setInteger("tarifaOficialId", tarifaOficialId);
		
		query.executeUpdate();
		
	}

	@Override
	public void removerDuplicidadeNaTarifaOficial() {
		String sql = sqlBuilder.getSqlRemoverDuplicidadeNaTarifaOficial();
		Query q = getSession().createSQLQuery(sql);
		q.executeUpdate();
	}
	
	
	
	
}