protected async Task UpdateParcelStatusAsync(Guid parcelId, Action <Parcel> update) { var parcel = await _parcelsRepository.GetAsync(parcelId); update(parcel); await _parcelsRepository.UpdateAsync(parcel); }
public async Task HandleAsync(DeliveryCompleted @event) { var parcel = await _parcelsRepository.GetAsync(@event.ParcelId); if (parcel is null) { throw new InvalidOperationException($"Parcel with id: {@event.ParcelId} was not found."); } parcel.CompleteDelivery(); await _parcelsRepository.UpdateAsync(parcel); _logger.LogInformation($"The delivery for parcel with id: {@event.ParcelId} has completed."); }
public async Task<ParcelDto> GetAsync(Guid id) { var parcel = await _parcelsRepository.GetAsync(id); return parcel is null ? null : new ParcelDto { Id = parcel.Id, Address = parcel.Address, Size = parcel.Size.ToString().ToLowerInvariant(), State = parcel.State.ToString() }; }
public async Task HandleAsync(StartDelivery command) { if (command.Parcels is null) { throw new Exception("Parcels to be delivered were not specified."); } var parcels = new HashSet <Parcel>(); foreach (var parcelId in command.Parcels) { var parcel = await _parcelsRepository.GetAsync(parcelId); if (parcel is null) { throw new Exception($"Parcel with id: {parcelId} to be delivered was not found."); } if (await _deliveriesRepository.IsParcelInDeliveryAsync(parcelId)) { throw new Exception($"Parcel with id: {parcelId} is unavailable."); } parcels.Add(parcel); } if (!parcels.Any()) { throw new Exception($"Delivery cannot be started without the parcels."); } _logger.LogInformation("Calculating the route..."); var route = await _routingServiceClient.GetAsync(parcels.Select(p => p.Address)); if (route is null) { throw new Exception("Route was not found."); } _logger.LogInformation("Route was calculated."); await _deliveriesRepository.AddAsync(new Delivery(command.DeliveryId, parcels, new Route(route.Addresses, route.TotalDistance))); var eventsToPublish = parcels.Select(p => _messageBroker.PublishAsync( new DeliveryStarted(command.DeliveryId, p.Id))); await Task.WhenAll(eventsToPublish); _logger.LogInformation($"Started a delivery with id: {command.DeliveryId}"); }
public async Task HandleAsync(DeliveryFailed @event) { var parcel = await _parcelsRepository.GetAsync(@event.ParcelId); if (parcel is null) { throw new InvalidOperationException($"Parcel with id: {@event.ParcelId} was not found."); } parcel.FailDelivery(@event.Reason); await _parcelsRepository.UpdateAsync(parcel); _logger.LogInformation($"The delivery for parcel with id: {@event.ParcelId} has failed " + $"reason: {@event.Reason}."); }
public async Task <ParcelDetailsDto> HandleAsync(GetParcel query) { var parcel = await _parcelsRepository.GetAsync(query.ParcelId); return(parcel is null ? null : new ParcelDetailsDto { Id = parcel.Id, Address = parcel.Address, Name = parcel.Name, Notes = parcel.Notes, Size = parcel.Size.ToString(), Status = parcel.Status.ToString() }); }
public async Task HandleAsync(DeleteParcel command) { var parcel = await _parcelsRepository.GetAsync(command.ParcelId); if (parcel is null) { throw new Exception($"Parcel: {command.ParcelId:N} was not found."); } if (parcel.Status != Status.Available) { throw new Exception($"Parcel: {command.ParcelId:N} cannot be deleted, status: {parcel.Status}."); } await _parcelsRepository.DeleteAsync(command.ParcelId); _logger.LogInformation($"Deleted a parcel: {command.ParcelId:N}."); await _dispatcher.PublishAsync(new ParcelDeleted(command.ParcelId)); }
public async Task HandleAsync(DeleteParcel command) { var parcel = await _parcelsRepository.GetAsync(command.ParcelId); if (parcel is null) { throw new Exception($"Parcel with id: {command.ParcelId} was not found."); } if (parcel.Status != Status.New) { throw new InvalidOperationException($"Parcel with id: {command.ParcelId} " + $"and status: {parcel.Status} cannot be deleted."); } await _parcelsRepository.DeleteAsync(command.ParcelId); await _messageBroker.PublishAsync(new ParcelDeleted(command.ParcelId)); _logger.LogInformation($"Deleted a parcel with id: {command.ParcelId}"); }
public async Task HandleAsync(DeliveryStatusChanged @event) { var deliveryDto = Map(@event.Delivery); var parcels = new List <ParcelInDeliveryDto>(); foreach (var parcelDto in deliveryDto.Parcels) { var parcel = await _parcelsRepository.GetAsync(parcelDto.Id); parcels.Add(new ParcelInDeliveryDto { Id = parcel.Id, Name = parcel.Name, Address = parcel.Address }); } deliveryDto.Parcels = parcels; await _storage.SetAsync(deliveryDto); _logger.LogInformation($"Set DTO for delivery: {@event.Delivery.Id} in storage."); }
public async Task HandleAsync(StartDelivery command) { if (command.Parcels is null) { throw new Exception("Parcels to be delivered were not specified."); } var parcels = new HashSet <Parcel>(); foreach (var parcelId in command.Parcels) { var parcel = await _parcelsRepository.GetAsync(parcelId); if (parcel is null) { throw new Exception($"Parcel: {parcelId:N} to be delivered was not found."); } if (await _deliveriesRepository.HasParcelInDelivery(parcelId)) { throw new Exception($"Parcel: {parcelId:N} is unavailable."); } parcels.Add(parcel); } if (!parcels.Any()) { throw new Exception($"Delivery cannot be started without the parcels."); } _logger.LogInformation("Calculating the route..."); var route = await _routingServiceClient.GetAsync(parcels.Select(p => p.Address)); if (route is null) { throw new Exception("Route was not found."); } _logger.LogInformation("Route was calculated."); var delivery = new Delivery(command.DeliveryId, parcels.Select(p => p.Id), new Route(route.Addresses, route.Distance)); delivery.Start(); await _deliveriesRepository.AddAsync(delivery); _logger.LogInformation($"Started a delivery: {command.DeliveryId:N}"); var domainEvents = delivery.Events; foreach (var domainEvent in domainEvents) { await _domainEventPublisher.PublishAsync(domainEvent); } delivery.ClearEvents(); var events = parcels.Select(p => new DeliveryStarted(command.DeliveryId, p.Id)); foreach (var @event in events) { await _dispatcher.PublishAsync(@event); } }