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); } } } }
public async Task <bool> Update(Drone drone) { await _droneRepository.Atualizar(drone); return(await _droneRepository.UnitOfWork.Commit()); }