Skip to content

Instantly share code, notes, and snippets.

@dcomartin
Created June 1, 2022 21:38
Show Gist options
  • Save dcomartin/85f66527e7b939224c7a5ea38b26a9d2 to your computer and use it in GitHub Desktop.
Save dcomartin/85f66527e7b939224c7a5ea38b26a9d2 to your computer and use it in GitHub Desktop.
public class ShipmentAggregateRoot
{
private readonly SortedList<int, Stop> _stops = new();
private ShipmentAggregateRoot(IReadOnlyList<Stop> stops)
{
for(var x = 0; x < stops.Count; x++)
{
_stops.Add(x, stops[x]);
}
}
public static ShipmentAggregateRoot Factory(PickupStop pickup, DeliveryStop delivery)
{
return new ShipmentAggregateRoot(new Stop[] { pickup, delivery });
}
public static ShipmentAggregateRoot Factory(Stop[] stops)
{
if (stops.Length < 2)
{
throw new InvalidOperationException("Shipment requires at least 2 stops.");
}
if (stops.First() is not PickupStop)
{
throw new InvalidOperationException("First stop must be a Pickup");
}
if (stops.Last() is not DeliveryStop)
{
throw new InvalidOperationException("first stop must be a Pickup");
}
return new ShipmentAggregateRoot(stops);
}
private KeyValuePair<int, Stop> CurrentStop()
{
return _stops.FirstOrDefault(x => x.Value.Status != StopStatus.Departed);
}
public void Arrive(DateTime arrived)
{
var currentStop = CurrentStop();
if (currentStop.Value == null)
{
throw new InvalidOperationException("Stop does not exist.");
}
var previousStopsAreNotDeparted = _stops.Any(x => x.Key < currentStop.Key && x.Value.Status != StopStatus.Departed);
if (previousStopsAreNotDeparted)
{
throw new InvalidOperationException("Previous stops have not departed.");
}
currentStop.Value.Arrive(arrived);
}
public void Pickup(DateTime departed)
{
var currentStop = CurrentStop();
if (currentStop.Value == null)
{
throw new InvalidOperationException("Stop does not exist.");
}
if (currentStop.Value is not PickupStop)
{
throw new InvalidOperationException("Stop is not a pickup.");
}
if (currentStop.Value.Status != StopStatus.Arrived)
{
Arrive(departed);
}
currentStop.Value.Depart(departed);
}
public void Deliver(DateTime departed)
{
var currentStop = CurrentStop();
if (currentStop.Value == null)
{
throw new InvalidOperationException("Stop does not exist.");
}
if (currentStop.Value is not DeliveryStop)
{
throw new InvalidOperationException("Stop is not a delivery.");
}
if (currentStop.Value.Status != StopStatus.Arrived)
{
Arrive(departed);
}
currentStop.Value.Depart(departed);
}
public bool IsComplete()
{
return _stops.All(x => x.Value.Status == StopStatus.Departed);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment