Beispiel #1
0
        public async Task <bool> Handle(AdicionarPedidoCommand message, CancellationToken cancellationToken)
        {
            if (!ValidarComando(message))
            {
                return(false);
            }


            var cliente = await _clienteRepository.ObterPorId(message.ClienteId);

            var drone = _droneRepository.ObterTodos().Result.OrderByDescending(d => d.Autonomia).FirstOrDefault(d => d.Capacidade >= message.Peso);

            if (drone == null)
            {
                await _mediatr.PublicarNotificacao(new DomainNotification(message.MessageType, "Pedido acima do peso máximo aceito."));

                return(false);
            }

            double distancia = _localizacaoLoja.CalcularDistanciaEmKilometros(new Localizacao(cliente.Latitude, cliente.Longitude));

            distancia *= 2;

            int tempoTrajetoCompleto = distancia.CalcularTempoTrajetoEmMinutos(drone.Velocidade);

            if (tempoTrajetoCompleto > drone.Autonomia)
            {
                await _mediatr.PublicarNotificacao(new DomainNotification(message.MessageType, "Fora da área de entrega."));

                return(false);
            }

            var pedido = new Pedido(message.Peso, message.DataHora, message.Status, message.Valor);

            pedido.InformarCliente(cliente);

            pedido.AdicionarEvento(new PedidoAdicionadoEvent(pedido.Valor, message.BandeiraCartao, message.NumeroCartao, message.MesVencimentoCartao, message.AnoVencimentoCartao)
            {
                AggregateRoot = pedido.Id
            });
            await _pedidoRepository.Adicionar(pedido);

            return(await _pedidoRepository.UnitOfWork.Commit());
        }
Beispiel #2
0
        public string IsPedidoValido(Pedido pedido)
        {
            var drone = _droneRepository.ObterTodos().Result.FirstOrDefault(d => d.Capacidade >= pedido.Peso);

            if (drone == null)
            {
                return("Pedido acima do peso máximo aceito.");
            }

            double distancia = _localizacaoLoja.CalcularDistanciaEmKilometros(new Localizacao((double)pedido.Cliente.Latitude, (double)pedido.Cliente.Longitude));

            distancia *= 2;

            int tempoTrajetoCompleto = _localizacaoLoja.CalcularTempoTrajetoEmMinutos(distancia, drone.Velocidade);

            if (tempoTrajetoCompleto > drone.Autonomia)
            {
                return("Fora da área de entrega.");
            }

            return(String.Empty);
        }
Beispiel #3
0
        public async Task <bool> Handle(DespacharPedidoCommand message, CancellationToken cancellationToken)
        {
            if (!ValidarComando(message))
            {
                return(false);
            }


            var pedidos = _pedidoQueries.ObterPedidosEmAberto().Result.ToList();

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

            var dronesDisponiveis = _droneItinerarioQueries.ObterDronesDisponiveis().Result.ToList();

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

            var pedidosEntregar     = new List <PedidoViewModel>();
            var pedidosDistribuidos = new List <PedidoViewModel>();

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

                double distanciaTrajeto     = 0;
                double distanciaRetorno     = 0;
                double distanciaPercorrida  = 0;
                double distanciaTotal       = 0;
                int    tempoTrajetoCompleto = 0;
                var    capacidadeDisponivel = drone.Capacidade;
                var    autonomiaDisponivel  = drone.AutonomiaRestante;

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

                    Localizacao localizacaoOrigem;

                    if (pedido.Peso > capacidadeDisponivel)
                    {
                        continue;
                    }


                    if (pedidosEntregar.Any())
                    {
                        localizacaoOrigem = new Localizacao(pedidosEntregar.Last().Cliente.Latitude, pedidosEntregar.Last().Cliente.Longitude);
                    }
                    else
                    {
                        localizacaoOrigem = message.LocalizacaoLoja;
                    }


                    var localizacaoCliente = new Localizacao(pedido.Cliente.Latitude, pedido.Cliente.Longitude);

                    distanciaTrajeto = localizacaoOrigem.CalcularDistanciaEmKilometros(localizacaoCliente);
                    distanciaRetorno = localizacaoCliente.CalcularDistanciaEmKilometros(localizacaoOrigem);

                    distanciaTotal = distanciaPercorrida + distanciaTrajeto + distanciaRetorno;

                    tempoTrajetoCompleto = distanciaTotal.CalcularTempoTrajetoEmMinutos(drone.Velocidade);

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

                        distanciaPercorrida += distanciaTrajeto;

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


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

                    if (!pedidosEntregar.Any())
                    {
                        continue;
                    }


                    await _mediatr.EnviarComando(new AtualizarAutonomiaDroneCommand(drone.Id, autonomiaDisponivel));

                    await _mediatr.EnviarComando(new AdicionarDroneItinerarioCommand(DateTime.Now, drone.Id, EnumStatusDrone.EmTransito));

                    foreach (var pedidoentregar in pedidosEntregar)
                    {
                        var pedidoDespachado = await _pedidoRepository.ObterPorId(pedidoentregar.Id);

                        if (pedido == null)
                        {
                            return(false);
                        }

                        var entregador = await _droneRepository.ObterPorId(drone.Id);

                        if (entregador == null)
                        {
                            return(false);
                        }

                        pedidoDespachado.Drone = entregador;
                        pedidoDespachado.InformarStatus(EnumStatusPedido.EmTransito);
                        pedidoDespachado.AdicionarEvento(new PedidoDespachadoEvent()
                        {
                            AggregateRoot = pedido.Id
                        });
                        await _pedidoRepository.Atualizar(pedidoDespachado);

                        await _pedidoRepository.UnitOfWork.Commit();

                        pedidos.Remove(pedidoentregar);
                    }
                }
            }

            return(true);
        }