Newer
Older
TransactionScriptVsDomain / TrxScript / Pickup.cs
@Derek Comartin Derek Comartin on 26 Jan 2022 1 KB Init
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Demo;
using Demo.EventSourced;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace TransactionScriptVsDomain.TrxScript
{
    public class Pickup : IRequest
    {
        public int ShipmentId { get; set; }
        public int StopId { get; set; }
        public DateTime Departed { get; set; }
    }

    public class PickupHandler : IRequestHandler<Pickup>
    {
        private readonly ShipmentDbContext _dbContext;
        private readonly IBus _bus;

        public PickupHandler(ShipmentDbContext dbContext, IBus bus)
        {
            _dbContext = dbContext;
            _bus = bus;
        }

        public async Task<Unit> Handle(Pickup request, CancellationToken cancellationToken)
        {
            var stop = await _dbContext.Stops.SingleOrDefaultAsync(x => x.StopId == request.StopId);

            if (stop == null)
            {
                throw new InvalidOperationException("Stop does not exist.");
            }

            if (stop.Status == StopStatus.Departed)
            {
                throw new InvalidOperationException("Stop has already departed.");
            }

            if (stop.Status == StopStatus.InTransit)
            {
                throw new InvalidOperationException("Stop hasn't arrived yet.");
            }

            if (request.Departed < stop.Arrived)
            {
                throw new InvalidOperationException("Departed Date/Time cannot be before Arrived Date/Time.");
            }

            stop.Status = StopStatus.Departed;
            stop.Departed = request.Departed;

            await _dbContext.SaveChangesAsync();

            await _bus.Publish(new PickedUp(request.StopId, request.Departed));
            
            return Unit.Value;
        }
    }
}