Newer
Older
PersistenceIgnorance / One.cs
@Derek Comartin Derek Comartin on 23 Aug 3 KB Init
namespace PersistenceIgnorance.One;

public class Shipment
{
    public int ShipmentId { get; private set; }
    public Shipper Shipper { get; private set; }
    public ICollection<Stop> Stops { get; } = new List<Stop>();

    public Shipment(int shipmentId, Shipper shipper)
    {
        ShipmentId = shipmentId;
        Shipper = shipper;
    }

    public bool IsComplete()
    {
        return Stops.All(x => x.Status == StopStatus.Departed);
    }

    public void Arrive(Guid stopId)
    {
        var currentStop = Stops.SingleOrDefault(x => x.StopId == stopId);
        if (currentStop == null)
        {
            throw new InvalidOperationException("Stop does not exist.");
        }

        var previousStopsAreNotDeparted = Stops.Any(x => x.Sequence < currentStop.Sequence && x.Status != StopStatus.Departed);
        if (previousStopsAreNotDeparted)
        {
            throw new InvalidOperationException("Previous stops have not departed.");
        }

        currentStop.Arrive();
    }

    public void Pickup(Guid stopId)
    {
        var currentStop = Stops.SingleOrDefault(x => x.StopId == stopId);
        if (currentStop == null)
        {
            throw new InvalidOperationException("Stop does not exist.");
        }

        if (currentStop.StopType == StopType.Pickup)
        {
            throw new InvalidOperationException("Stop is not a pickup.");
        }

        currentStop.Depart();
    }

    public void Deliver(Guid stopId)
    {
        var currentStop = Stops.SingleOrDefault(x => x.StopId == stopId);
        if (currentStop == null)
        {
            throw new InvalidOperationException("Stop does not exist.");
        }

        if (currentStop.StopType == StopType.Delivery)
        {
            throw new InvalidOperationException("Stop is not a delivery.");
        }

        currentStop.Depart();
    }

    public void UpdateShipper(Shipper shipper)
    {
        Shipper = shipper;
    } 
}

public class Stop
{
    public Guid StopId { get; private set; }
    public StopType StopType { get; private set; }
    public Location Location { get; private set; }
    public StopStatus Status { get; private set; }
    public int Sequence { get; private set; }

    protected Stop(Guid stopId, StopType stopType, Location location, StopStatus status, int sequence)
    {
        StopId = stopId;
        StopType = stopType;
        Location = location;
        Status = status;
        Sequence = sequence;
    }

    public void Arrive()
    {
        if (Status != StopStatus.InTransit)
        {
            throw new InvalidOperationException("Stop has already arrived.");
        }

        Status = StopStatus.Arrived;
    }

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

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

        Status = StopStatus.Departed;
    }
}


public class Shipper
{
    public Guid ShipperId { get; set; }
    public required string Name { get; set; }
}

public class Location
{
    public Location(string street, string city, string state, string postal)
    {
        Street = street;
        City = city;
        State = state;
        Postal = postal;
    }
    
    public string Street { get; private set; }
    public string City { get; private set; }
    public string State { get; private set; }
    public string Postal { get; private set; }
}

public enum StopType
{
    Pickup,
    Delivery
}

public enum StopStatus
{
    InTransit,
    Arrived,
    Departed
}