private List <int> ParadasIntermedias(int idlinea, int idParadaOrigen, int idParadaDestino)
        {
            DAL_Global DAL_G    = new DAL_Global();
            var        res      = new List <int>();
            var        paradas  = DAL_G.obtenerParadasDeLinea(idlinea);
            bool       comienzo = false;

            foreach (var parada in paradas)
            {
                if (parada.id == idParadaOrigen)
                {
                    comienzo = true;
                }
                if (comienzo)
                {
                    res.Add(parada.id);
                }
                if (comienzo && parada.id == idParadaDestino)
                {
                    return(res);
                }
            }
            ;
            return(res);
        }
        private decimal PrecioRecorrido(int idlinea, int idParadaOrigen, int idParadaDestino, DateTime fecha)
        {
            DAL_Global DAL_G            = new DAL_Global();
            var        paradas          = DAL_G.obtenerParadasDeLinea(idlinea).Select(x => ParadaConverter.convert(x)).ToList();
            decimal    precio           = 0;
            bool       EstoyEnRecorrido = false;

            using (uruguay_busEntities db = new uruguay_busEntities())
            {
                foreach (var parada in paradas)
                {
                    if (EstoyEnRecorrido)
                    {
                        var valor = db.parada.FirstOrDefault(x => x.id == parada.id)?.tramo
                                    .FirstOrDefault(x => x.linea.id == idlinea)?.precio
                                    .OrderByDescending(x => x.fecha_validez)
                                    .FirstOrDefault(x => x.fecha_validez.Date <= fecha.Date)?.valor ?? 0;

                        precio += valor;
                        if (parada.id == idParadaDestino)
                        {
                            return(precio);
                        }
                    }
                    else if (parada.id == idParadaOrigen)
                    {
                        EstoyEnRecorrido = true;
                    }
                }
            }
            return(precio);
        }
        private bool ParadasOrdenadas(int idlinea, int idParadaOrigen, int idParadaDestino)
        {
            DAL_Global DAL_G          = new DAL_Global();
            var        paradas        = DAL_G.obtenerParadasDeLinea(idlinea).Select(x => ParadaConverter.convert(x)).ToList();
            bool?      encontroParada = null;

            foreach (var parada in paradas)
            {
                if (parada.id == idParadaOrigen && encontroParada == null)
                {
                    encontroParada = false;
                }
                else if (parada.id == idParadaDestino && encontroParada == false)
                {
                    return(true);
                }
            }
            return(encontroParada ?? false);
        }
        private int GetParadaAnterior(int idlinea, int?idParada)
        {
            DAL_Global DAL_G   = new DAL_Global();
            var        paradas = DAL_G.obtenerParadasDeLinea(idlinea).Select(x => ParadaConverter.convert(x)).ToList();

            // obtengo laparada de referencia y luego obtengo su indice en la coleccion
            parada paradaReferencia      = paradas.Where(x => x.id == idParada).FirstOrDefault();
            int    indexParadaReferencia = paradas.IndexOf(paradaReferencia);

            // si no se encuentra o si es la primera, devuelvo 0
            // si se encuentra la ubico en la coleccion y devuelvo su ID
            if (indexParadaReferencia <= 0)
            {
                return(0);
            }
            else
            {
                return(paradas.ElementAt(indexParadaReferencia - 1).id);
            }
        }
        private List <int> GetCantAsientosDisponiblies(viaje Viaje, int idParadaOrigen, int idParadaDestino)
        {
            DAL_Global DAL_G    = new DAL_Global();
            var        paradas  = DAL_G.obtenerParadasDeLinea(Viaje.horario.linea.id).Select(x => ParadaConverter.convert(x)).ToList();
            var        res      = new List <int>();
            List <int> ParadasI = ParadasIntermedias(Viaje.horario.linea.id, idParadaOrigen, idParadaDestino);

            using (uruguay_busEntities db = new uruguay_busEntities())
            {
                for (int i = 1; i < Viaje.horario.vehiculo.cant_asientos; i++)
                {
                    var pasajesParaElAsiento = Viaje.pasaje.Where(x => x.asiento == i).ToList();
                    if (pasajesParaElAsiento.Count() == 0)
                    {
                        res.Add(i);
                    }
                    else
                    {
                        var asientoDisponible = true;
                        foreach (var pasaje in pasajesParaElAsiento)
                        {
                            if (ParadasI.Intersect(ParadasIntermedias(Viaje.horario.linea.id, pasaje.parada_id_origen, pasaje.parada_id_destino)).Count() == 0)
                            {
                                continue;
                            }
                            asientoDisponible = pasaje.parada_id_destino == idParadaOrigen ||
                                                pasaje.parada_id_origen == idParadaDestino;
                            if (!asientoDisponible)
                            {
                                break;
                            }
                        }
                        if (asientoDisponible)
                        {
                            res.Add(i);
                        }
                    }
                }
            }
            return(res);
        }
        public ICollection <ViajeDisponibleDTO> ListarViajesDisponibles(DateTime fecha, int idParadaOrigen, int idParadaDestino)
        {
            using (uruguay_busEntities db = new uruguay_busEntities())
            {
                try
                {
                    DAL_Global DAL_G  = new DAL_Global();
                    var        viajes = db.viaje
                                        .Where(x => x.finalizado != true &&
                                               x.horario.linea.tramo.Any(y => y.parada_id == idParadaOrigen) &&
                                               x.horario.linea.tramo.Any(y => y.parada_id == idParadaDestino) &&
                                               !x.paso_por_parada.Any(y => y.parada_id == idParadaOrigen)).ToList();
                    viajes = viajes
                             .Where(x =>
                                    ParadasOrdenadas(x.horario.linea.id, idParadaOrigen, idParadaDestino) &&
                                    x.fecha.Date == fecha.Date)
                             .ToList();

                    var res = viajes.Select(x => new ViajeDisponibleDTO()
                    {
                        viaje_id          = x.id,
                        linea_id          = x.horario.linea.id,
                        linea_nombre      = x.horario.linea.nombre,
                        parada_id_destino = idParadaDestino,
                        parada_id_origen  = idParadaOrigen,
                        hora   = x.horario.hora,
                        precio = PrecioRecorrido(x.horario.linea.id, idParadaOrigen, idParadaDestino, fecha),
                        asientos_disponibles = GetCantAsientosDisponiblies(x, idParadaOrigen, idParadaDestino)
                    }).ToList();
                    return(res);
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
        }
        public ICollection <Usuario> RegistrarPasoPorParada(int idParada, int idViaje)
        {
            using (uruguay_busEntities db = new uruguay_busEntities())
            {
                try
                {
                    IDAL_Global           blg             = new DAL_Global();
                    ICollection <usuario> retSinConvertir = new List <usuario>();
                    viaje  v = db.viaje.Find(idViaje);
                    parada p = db.parada.Find(idParada);

                    if (v == null)
                    {
                        throw new Exception("No se encontro ningun viaje con ese ID");
                    }

                    if (p == null)
                    {
                        throw new Exception("No se encontro ninguna parada con ese ID");
                    }

                    vehiculo vh = v.horario.vehiculo;

                    paso_por_parada ppp = new paso_por_parada()
                    {
                        fecha_hora = DateTime.Now,
                        viaje      = v,
                        parada     = p
                    };

                    db.paso_por_parada.Add(ppp);

                    vh.latitud  = p.latitud;
                    vh.longitud = p.longitud;
                    db.SaveChanges();


                    ICollection <parada> paradasOrdenadas = ParadaConverter.convert(blg.obtenerParadasDeLinea(v.horario.linea.id));

                    parada siguienteParada = null;
                    for (int i = 0; i < paradasOrdenadas.Count; i++)
                    {
                        if (paradasOrdenadas.ElementAt(i).id == idParada && i + 1 < paradasOrdenadas.Count)
                        {
                            siguienteParada = paradasOrdenadas.ElementAt(i + 1);
                        }
                    }

                    if (siguienteParada == null)
                    {
                        return(new List <Usuario>());
                    }

                    retSinConvertir = siguienteParada.pasajes_origen
                                      .Where(x => x.usuario != null)
                                      .Select(x => x.usuario).ToList();

                    //foreach (var item in siguienteParada.pasaje1)
                    //{
                    //    retSinConvertir.Add(item.usuario);
                    //}

                    ICollection <Usuario> retConvertido = new List <Usuario>();

                    foreach (var item in retSinConvertir)
                    {
                        Usuario nuevo = UsuarioConverter.convert(item);
                        nuevo.persona = PersonaConverter.convert(item.persona);
                        retConvertido.Add(nuevo);
                    }

                    return(retConvertido);
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
        }