예제 #1
0
        private async Task DistribuirPedidos()
        {
            var pedidos = new List <Pedido>();


            // pedidos mais antigos vao primeiro
            pedidos = _repositoryPedido.ObterPedidosEmAberto().Result.ToList();


            if (!pedidos.Any())
            {
                return;
            }

            var droneItinerarios = _droneItinerarioRepository.ObterTodos().Result
                                   .Where(d => d.StatusDrone == EnumStatusDrone.Disponivel)
                                   .ToList();

            foreach (var droneItinerario in droneItinerarios)
            {
                droneItinerario.Drone = await _droneRepository.ObterPorId(droneItinerario.DroneId);
            }

            var dronesDisponiveis = droneItinerarios.Select(d => d.Drone).OrderBy(d => d.Capacidade).ToList();

            if (!dronesDisponiveis.Any())
            {
                return;
            }

            IDictionary <Drone, IList <Pedido> > pedidosPorDrone = new Dictionary <Drone, IList <Pedido> >();
            IList <Pedido> pedidosEntregar      = new List <Pedido>();
            IList <Pedido> pedidosDistribuidos  = new List <Pedido>();
            double         distanciaTrajeto     = 0;
            double         distanciaRetorno     = 0;
            double         distanciaPercorrida  = 0;
            double         distanciaTotal       = 0;
            decimal        latitudeOrigem       = 0;
            decimal        longitudeOrigem      = 0;
            int            tempoTrajetoCompleto = 0;

            foreach (var drone in dronesDisponiveis)
            {
                pedidosEntregar.Clear();

                distanciaTrajeto     = 0;
                distanciaRetorno     = 0;
                distanciaPercorrida  = 0;
                distanciaTotal       = 0;
                latitudeOrigem       = 0;
                longitudeOrigem      = 0;
                tempoTrajetoCompleto = 0;

                int capacidadeDisponivel = drone.Capacidade;
                int autonomiaDisponivel  = drone.AutonomiaRestante;

                foreach (var pedido in pedidos)
                {
                    if (pedidosDistribuidos.Contains(pedido))
                    {
                        continue;
                    }

                    if (pedido.Peso <= capacidadeDisponivel)
                    {
                        if (pedidosEntregar.Any())
                        {
                            latitudeOrigem  = pedidosEntregar.Last().Cliente.Latitude;
                            longitudeOrigem = pedidosEntregar.Last().Cliente.Longitude;
                        }
                        else
                        {
                            latitudeOrigem  = _latitudeLoja;
                            longitudeOrigem = _longitudeLoja;
                        }

                        distanciaTrajeto = CalcularDistanciaEmKilometros((double)latitudeOrigem, (double)longitudeOrigem, (double)pedido.Cliente.Latitude, (double)pedido.Cliente.Longitude);
                        distanciaRetorno = CalcularDistanciaEmKilometros((double)pedido.Cliente.Latitude, (double)pedido.Cliente.Longitude, (double)_latitudeLoja, (double)_longitudeLoja);

                        distanciaTotal = distanciaPercorrida + distanciaTrajeto + distanciaRetorno;

                        tempoTrajetoCompleto = CalcularTempoTrajetoEmMinutos(distanciaTotal, drone.Velocidade);

                        if (tempoTrajetoCompleto <= drone.AutonomiaRestante)
                        {
                            pedidosEntregar.Add(pedido);

                            distanciaPercorrida += distanciaTrajeto;

                            capacidadeDisponivel -= pedido.Peso;
                            autonomiaDisponivel   = drone.AutonomiaRestante - tempoTrajetoCompleto;
                        }
                    }
                    else
                    {
                        continue;
                    }

                    // se não cabe mais, nao precisa verificar os demais pedidos
                    if (capacidadeDisponivel <= 0 || tempoTrajetoCompleto >= drone.AutonomiaRestante)
                    {
                        break;
                    }
                }

                if (pedidosEntregar.Any())
                {
                    drone.AutonomiaRestante = autonomiaDisponivel;

                    if (!pedidosPorDrone.ContainsKey(drone))
                    {
                        pedidosPorDrone.Add(drone, new List <Pedido>());
                    }

                    foreach (var pedido in pedidosEntregar)
                    {
                        pedidosPorDrone[drone].Add(pedido);
                    }

                    pedidosDistribuidos = pedidosDistribuidos.Concat(pedidosEntregar).ToList();
                }
            }

            if (pedidosPorDrone.Count > 0)
            {
                foreach (var item in pedidosPorDrone)
                {
                    Drone drone = item.Key;

                    DroneItinerario droneItinerario = droneItinerarios.FirstOrDefault(d => d.DroneId == drone.Id);
                    droneItinerario.DataHora    = DateTime.Now;
                    droneItinerario.Drone       = drone;
                    droneItinerario.DroneId     = drone.Id;
                    droneItinerario.StatusDrone = EnumStatusDrone.EmTransito;

                    await _droneRepository.Atualizar(drone);

                    await _droneItinerarioRepository.Atualizar(droneItinerario);

                    foreach (var pedido in item.Value)
                    {
                        pedido.Drone = drone;
                        pedido.InformarStatus(EnumStatusPedido.EmTransito);

                        await _repositoryPedido.Atualizar(pedido);
                    }
                }
            }
        }
예제 #2
0
        public async Task <bool> Update(Drone drone)
        {
            await _droneRepository.Atualizar(drone);

            return(await _droneRepository.UnitOfWork.Commit());
        }