/*
 * 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.util.Date;
import java.util.List;

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.Restrictions;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.hibernate.type.LongType;
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 com.rjconsultores.ventaboletos.dao.BoletoDAO;
import com.rjconsultores.ventaboletos.entidad.Boleto;
import com.rjconsultores.ventaboletos.utilerias.ActivoUtil;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.utilerias.MoneyHelper;
import com.rjconsultores.ventaboletos.vo.embarcada.PtoVtaUsuarioUltimaVendaDispositivoVO;

/**
 * 
 * @author Fabricio
 */
@Repository("boletoDAO")
public class BoletoHibernateDAO extends GenericHibernateDAO<Boleto, Long> implements BoletoDAO {
	private static final Logger log = LogManager.getLogger(BoletoHibernateDAO.class);
	@Autowired
	public BoletoHibernateDAO(@Qualifier("sessionFactory") SessionFactory factory) {
		setSessionFactory(factory);
	}

	public List<PtoVtaUsuarioUltimaVendaDispositivoVO> buscarUltimaVendaDosDispositivosEmbarcada(){
		StringBuilder sb = new StringBuilder();
		sb.append("select p.puntoventa_id as puntoventaId, u.usuario_id as usuarioId, u.nombusuario as nombusuario, p.nombpuntoventa as nombpuntoventa, d.imei as imei ");
		sb.append("from ");
		sb.append("    ctrl_serie_embarcada c ");
		sb.append("    left join usuario u on u.usuario_id = c.usuario_id ");
		sb.append("    left join punto_venta p on p.puntoventa_id = c.puntoventa_id ");
		sb.append("    left join dispositivo_embarcada d on d.dispositivoembarcada_id = c.dispositivoembarcada_id ");
		
		
		SQLQuery qry = getSession().createSQLQuery(sb.toString())
				.addScalar("puntoventaId", LongType.INSTANCE)
				.addScalar("usuarioId", LongType.INSTANCE)
				.addScalar("nombusuario", StringType.INSTANCE)
				.addScalar("nombpuntoventa", StringType.INSTANCE)
				.addScalar("imei", StringType.INSTANCE);
		qry.setResultTransformer(new AliasToBeanResultTransformer(PtoVtaUsuarioUltimaVendaDispositivoVO.class));
		return qry.list();
	}

	public Boleto buscarPeloImeiDoDispositivo(String imei) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq("imeiDispositivoEmbarcada", imei));
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));
		c.addOrder(Order.desc("fechorventa"));
		c.setFirstResult(0);
		c.setMaxResults(1);

		return (Boleto) c.uniqueResult();
	}
	
	public boolean isExisteBoletoPorCorrida(Integer corridaId, Date fecCorrida) {
		try {
			
			StringBuilder hql = new StringBuilder();
			hql.append(" select ");
			hql.append(" count(*) from boleto b where " );
			hql.append(" b.corrida_id = :corridaId and b.feccorrida = :feccorrida  and ROWNUM =  1 and b.activo = :isActivo");
			Query query = getSession().createSQLQuery(hql.toString());
			query.setInteger("isActivo", ActivoUtil.ATIVO);
			query.setDate("feccorrida", fecCorrida);
			query.setInteger("corridaId", corridaId);
			
			BigDecimal qtde = (BigDecimal) query.uniqueResult();
			return qtde !=null && MoneyHelper.isMaior(qtde, BigDecimal.ZERO) ;
		}catch(Exception e) {
			log.error("Erro buscar Bole to por corrida para corrida=" + corridaId + "data:" + DateUtil.getStringDate(fecCorrida), e);
			return false;
		}
		
	}
	
	public boolean isExisteBoletoPorCorridaOrigemIdOuDestinoId(Integer corridaId, Date fecCorrida, Integer origemId, Integer destinoId) {
		try {
			
			StringBuilder hql = new StringBuilder();
			hql.append(" select ");
			hql.append(" count(*) from boleto b where " );
			hql.append(" b.corrida_id = :corridaId and b.feccorrida = :feccorrida  and ROWNUM =  1 and b.activo = :isActivo and (b.origen_id=:origemId or b.destino_id=:destinoId)");
			Query query = getSession().createSQLQuery(hql.toString());
			query.setInteger("isActivo", ActivoUtil.ATIVO);
			query.setDate("feccorrida", fecCorrida);
			query.setInteger("corridaId", corridaId);
			query.setInteger("origemId", origemId);
			query.setInteger("destinoId", destinoId);
			
			BigDecimal qtde = (BigDecimal) query.uniqueResult();
			return qtde !=null && MoneyHelper.isMaior(qtde, BigDecimal.ZERO) ;
		}catch(Exception e) {
			log.error("Erro buscar Bole to por corrida para corrida=" + corridaId + "data:" + DateUtil.getStringDate(fecCorrida), e);
			return false;
		}
		
	}
	
	public String getSequenciaBoletoId(){
		String sql = "SELECT BOLETO_SEQ.nextval FROM DUAL";
		Object o = this.getSession().createSQLQuery(sql).uniqueResult();
		return o.toString();
	}
	
	public String getSequenciaNumOperacion(){
		String sql = "SELECT NUMEOPERACION_SEQ.nextval FROM DUAL";
		Object o = this.getSession().createSQLQuery(sql).uniqueResult();
		return o.toString();
	}
	
	public String getSequenciaNumReservacion(){
		String sql = "SELECT NUMERESERVACION_SEQ.nextval FROM DUAL";
		Object o = this.getSession().createSQLQuery(sql).uniqueResult();
		return o.toString();
	}
	
	@Override
	public void insertBoletoReserva(Boleto miBoletoTemporal){
		SQLQuery query = getSession().createSQLQuery(getSqlInsertBoletoRserva());

		query.setLong("boletoId",	miBoletoTemporal.getBoletoId());
		query.setLong("boletooriginalId",	miBoletoTemporal.getBoletooriginalId());
		query.setInteger("categoriaId",	miBoletoTemporal.getCategoriaId());
		query.setInteger("clienteId",	miBoletoTemporal.getClienteId());
		query.setInteger("claseservicioId",	miBoletoTemporal.getClaseservicioId());
		query.setInteger("corridaId", miBoletoTemporal.getCorridaId());
		query.setInteger("destinoId",	miBoletoTemporal.getDestinoId());
		query.setString("desctipodoc",	miBoletoTemporal.getDesctipodoc());
		query.setString("descnumdoc",	miBoletoTemporal.getDescnumdoc());
		query.setInteger("empresacorridaId",	miBoletoTemporal.getEmpresacorridaId());
		query.setInteger("empresapuntoventaId",	miBoletoTemporal.getEmpresapuntoventaId());
		query.setInteger("estacionId",	miBoletoTemporal.getEstacionId());
		query.setDate("feccreacion",	miBoletoTemporal.getFeccreacion());
		query.setDate("fecmodif",	miBoletoTemporal.getFecmodif());
		query.setDate("fechorventa",	miBoletoTemporal.getFechorventa());
		query.setDate("fechorventaH",	miBoletoTemporal.getFechorventaH());
		query.setDate("fechorviaje",	miBoletoTemporal.getFechorviaje());
		query.setDate("feccorrida",	miBoletoTemporal.getFeccorrida());
		query.setInteger("corridaId",	miBoletoTemporal.getCorridaId());
		query.setInteger("indcancelacion", Boolean.TRUE.equals(miBoletoTemporal.getIndcancelacion()) ? 1 :0 );
		query.setInteger("indreimpresion",	Boolean.TRUE.equals(miBoletoTemporal.getIndreimpresion()) ? 1 :0 );
		query.setInteger("indextraviado",	Boolean.TRUE.equals(miBoletoTemporal.getIndextraviado()) ? 1 :0 );
		query.setString("indstatusoperacion", miBoletoTemporal.getIndstatusoperacion() );
		query.setInteger("indreplica",	Boolean.TRUE.equals(miBoletoTemporal.getIndreplica()) ? 1 :0 );
		query.setString("indstatusboleto",	miBoletoTemporal.getIndstatusboleto());
		query.setInteger("indviajeredondo",	Boolean.TRUE.equals(miBoletoTemporal.getIndviajeredondo()) ? 1 :0 );
		query.setBigDecimal("importetaxaembarque",	miBoletoTemporal.getImportetaxaembarque());
		query.setBigDecimal("importeseguro",	miBoletoTemporal.getImporteseguro());
		query.setBigDecimal("importepedagio",	miBoletoTemporal.getImportepedagio());
		query.setBigDecimal("importeoutros",	miBoletoTemporal.getImporteoutros());
		query.setInteger("marcaId",	miBoletoTemporal.getMarcaId());
		query.setInteger("monedaId", miBoletoTemporal.getMonedaId());
		query.setInteger("nodoId",	miBoletoTemporal.getNodoId());
		query.setBigDecimal("numkmviaje",	miBoletoTemporal.getNumkmviaje());
		query.setString("nombpasajero",	miBoletoTemporal.getNombpasajero());
		query.setString("numasiento",	miBoletoTemporal.getNumasiento());
		query.setString("numfidelidad",	miBoletoTemporal.getNumfidelidad());
		query.setString("numoperacion",	miBoletoTemporal.getNumoperacion());
		query.setString("numreservacion",	miBoletoTemporal.getNumreservacion());
		query.setInteger("origenId",	miBoletoTemporal.getOrigenId());
		query.setBigDecimal("preciopagado",	miBoletoTemporal.getPreciopagado());
		query.setBigDecimal("preciobase",	miBoletoTemporal.getPreciobase());
		query.setInteger("ptovtaventaId",	miBoletoTemporal.getPtovtaventaId());
		query.setInteger("puntoventaId",	miBoletoTemporal.getPuntoVentaId());
		query.setInteger("rutaId",	miBoletoTemporal.getRutaId());
		query.setInteger("temporeservafidelidade",	miBoletoTemporal.getTemporeservafidelidade());
		query.setInteger("tipoventaId",	miBoletoTemporal.getTipoventaId());
		query.setInteger("usuarioautorizacionId",	miBoletoTemporal.getUsuarioautorizacionId());
		query.setInteger("usuarioId",	miBoletoTemporal.getUsuario().getUsuarioId());
		query.setInteger("activo",	Boolean.TRUE.equals(miBoletoTemporal.getActivo()) ? 1: 0);
		query.executeUpdate();

	}
	
	
	private String getSqlInsertBoletoRserva() {
		StringBuilder sql = new StringBuilder();
		sql.append(" INSERT INTO boleto ( ");
		sql.append(" activo,"); //1
		sql.append(" aidf_id,"); //2 - null
		sql.append(" boletoanterior_id,");//3 - null
		sql.append(" boletooriginal_id,"); //4 
		sql.append(" cantpuntos,"); //5 - null
		sql.append(" canttransferencia,"); //6 - null
		sql.append(" categoria_id,"); //7
		sql.append(" ccf,"); //8 - null
		sql.append(" claseservicio_id,"); //9
		sql.append(" cliente_id,"); //10
		sql.append(" clientefidelidad_id,"); //11 - null
		sql.append(" conveniodet_id,"); //12 - null
		sql.append(" corrida_id,"); //13
		sql.append(" desccorreo,"); //14 - null
		sql.append(" descnumdoc,"); //15
		sql.append(" descnumdoc2,"); //16 - null
		sql.append(" descorgaodoc,"); //17 - null
		sql.append(" desctelefono,"); //18 - null
		sql.append(" desctipodoc,"); //19
		sql.append(" desctipodoc2,"); //20
		sql.append(" descuentoamparado,"); //21
		sql.append(" destino_id,"); //22
		sql.append(" dispositivoembarcada,"); //23
		sql.append(" empresacorrida_id,"); //24
		sql.append(" empresapuntoventa_id,"); //25
		sql.append(" entregaboleto_id,"); //26
		sql.append(" estacion_id,"); //27
		sql.append(" estadocivil_id,"); //28
		sql.append(" estadofolio_id,"); //29
		sql.append(" feccorrida,"); //30
		sql.append(" feccreacion,"); //31
		sql.append(" fechorventa,"); //32
		sql.append(" fechorventa_h,"); //33
		sql.append(" fechorviaje,"); //34
		sql.append(" fecmodif,"); //35
		sql.append(" fecnacimiento,"); //36
		sql.append(" imei_dispositivo_embarcada,"); //37
		sql.append(" importecategoria,"); //38
		sql.append(" importeoutros,"); //39
		sql.append(" importepedagio,"); //40
		sql.append(" importeseguro,"); //41
		sql.append(" importetaxaembarque,"); //42
		sql.append(" indcancelacion,"); //43
		sql.append(" indconexion,"); //44
		sql.append(" indextraviado,"); //45
		sql.append(" indreimpresion,"); // 46
		sql.append(" indreplica,"); //47
		sql.append(" indsegundaviaimpressa,"); //48
		sql.append(" indstatusboleto,"); //49
		sql.append(" indstatusoperacion,"); //50
		sql.append(" indviajeredondo,"); //51
		sql.append(" infopasajero,"); //52
		sql.append(" levante_id,"); //53
		sql.append(" marca_id,"); //54
		sql.append(" moneda_id,"); //55
		sql.append(" motivocancelacion_id,"); //56
		sql.append(" motivoreimpresion_id,"); //57
		sql.append(" nacionalidad,"); //58
		sql.append(" nodo_id,"); //59
		sql.append(" nombpasajero,"); //60
		sql.append(" numasiento,"); //61
		sql.append(" numasientovinculado,"); //62
		sql.append(" numdocdescuento,"); //63
		sql.append(" numerobilheteembarcada,"); //64
		sql.append(" numfidelidad,"); //65
		sql.append(" numfoliopreimpreso,"); //66
		sql.append(" numfoliosistema,"); //67
		sql.append(" numidentificacion,"); //68
		sql.append(" numkmviaje,"); //69
		sql.append(" numoperacion,"); //70
		sql.append(" numreservacion,"); //71
		sql.append(" numseriepreimpresa,"); //72
		sql.append(" opcional1,"); // 73
		sql.append(" opcional2,"); // 74
		sql.append(" opcional3,"); // 75
		sql.append(" origen_id,"); // 76
		sql.append(" paridad,"); // 77
		sql.append(" porccategoria,"); // 78
		sql.append(" preciobase,"); //79
		sql.append(" preciocargoextra,"); // 80
		sql.append(" preciopagado,"); //81
		sql.append(" preciopricing,"); // 82
		sql.append(" ptovtaventa_id,"); //83
		sql.append(" puntoventa_id,"); //84
		sql.append(" puntoventaremoto_id,"); // 85
		sql.append(" rmd_id,"); //86
		sql.append(" ruta_id,"); //87
		sql.append(" serieimpfiscal,"); //88
		sql.append(" serieimpfiscaloriginal,"); // 89
		sql.append(" sexo,"); //90
		sql.append(" temporeservafidelidade,"); //91
		sql.append(" tipoidentificacion_id,"); // 92
		sql.append(" tipoidentificaciondoc_id,"); //93
		sql.append(" tipoventa_id,"); //94
		sql.append(" turno_id,"); //95
		sql.append(" usuario_id,"); //96
		sql.append(" usuarioautorizacion_id,"); //97
		sql.append(" usuarioremoto_id,"); // 98
		sql.append(" boleto_id");  //99
		// Values
		sql.append(" ) VALUES ( ");
		sql.append(" :activo,"); //1
		sql.append(" null,"); //2
		sql.append(" null,"); //3
		sql.append(" :boletooriginalId,");//4
		sql.append(" null,");//5
		sql.append(" null,");//6
		sql.append(" :categoriaId,");//7
		sql.append(" null,");//8
		sql.append(" :claseservicioId,"); //9
		sql.append(" :clienteId,"); //10
		sql.append(" null,");//11
		sql.append(" null,");//12
		sql.append(" :corridaId,");//13
		sql.append("  null,"); //14
		sql.append(" :descnumdoc,"); //15
		sql.append(" null,"); //16
		sql.append(" null,"); //17
		sql.append(" null,"); //18
		sql.append(" :desctipodoc,"); //19
		sql.append(" null,"); //20
		sql.append(" null,"); //21
		sql.append(" :destinoId,"); //22
		sql.append(" null,"); //23
		sql.append(" :empresacorridaId,"); //24
		sql.append(" :empresapuntoventaId,"); //25
		sql.append(" null,"); //26
		sql.append(" :estacionId,"); //27
		sql.append(" null,"); //28
		sql.append(" null,"); //29
		sql.append(" :feccorrida,");//30
		sql.append(" :feccreacion,");//31
		sql.append(" :fechorventa,"); //32
		sql.append(" :fechorventaH,"); //33
		sql.append(" :fechorviaje,"); //34
		sql.append(" :fecmodif,"); //35
		sql.append(" null,"); //36
		sql.append(" null,"); //37
		sql.append(" null,"); //38
		sql.append(" :importeoutros,"); //39
		sql.append(" :importepedagio,"); //40
		sql.append(" :importeseguro,"); //41
		sql.append(" :importetaxaembarque,"); //42
		sql.append(" :indcancelacion,"); //43
		sql.append(" null,"); //44
		sql.append(" :indextraviado,"); //45
		sql.append(" :indreimpresion,"); //46
		sql.append(" :indreplica,"); //47
		sql.append(" null,"); //48
		sql.append(" :indstatusboleto,"); //49
		sql.append(" :indstatusoperacion,"); //50
		sql.append(" :indviajeredondo,"); //51
		sql.append(" null,");//52
		sql.append(" null,");//53
		sql.append(" :marcaId,"); //54
		sql.append(" :monedaId,"); //55
		sql.append(" null,"); //56
		sql.append(" null,"); //57
		sql.append(" null,"); //58
		sql.append(" :nodoId,");//59
		sql.append(" :nombpasajero,"); //60
		sql.append(" :numasiento,"); //61
		sql.append(" null,"); //62
		sql.append(" null,"); //63
		sql.append(" null,"); //64
		sql.append(" :numfidelidad,"); //65
		sql.append(" null,"); //66
		sql.append(" null,"); //67
		sql.append(" null,"); //68
		sql.append(" :numkmviaje,"); //69
		sql.append(" :numoperacion,"); //70
		sql.append(" :numreservacion,"); //71
		sql.append(" null,"); //72
		sql.append(" null,"); //73
		sql.append(" null,"); //74
		sql.append(" null,"); //75
		sql.append(" :origenId,"); //76
		sql.append(" null,"); //77
		sql.append(" null,"); //78
		sql.append(" :preciobase,"); //79
		sql.append(" null,"); //80
		sql.append(" :preciopagado,"); //81
		sql.append(" null,"); //82
		sql.append(" :ptovtaventaId,"); //83
		sql.append(" :puntoventaId,"); //84
		sql.append(" null,"); //85
		sql.append(" null,"); //86
		sql.append(" :rutaId,"); //87
		sql.append(" null,"); //88
		sql.append(" null,"); //89
		sql.append(" null,"); //90
		sql.append(" :temporeservafidelidade,"); //91
		sql.append(" null,"); //92
		sql.append(" null,"); //93
		sql.append(" :tipoventaId,"); //94
		sql.append(" null,"); //95
		sql.append(" :usuarioId,"); //96
		sql.append(" :usuarioautorizacionId,"); //97
		sql.append(" null,"); //98
		sql.append(" :boletoId"); //99
		sql.append("    )");
		
		return sql.toString();
	}
}
