public Result <CustomerQueue> AddTicket(
     TicketId ticketId,
     int ticketNumber) =>
 QueuedTickets.CanAddFrom(ticketId, ticketNumber)
 .OnSuccess(() => ApplyChange(new TicketAdded(Id, ticketId, ticketNumber)))
 .OnSuccess(_ => AvailableCounters.MapFirstFree(counter => ApplyChange(new CustomerTaken(Id, counter.Id, ticketId))))
 .ToTypedResult(this);
 public CustomerQueue(
     Guid id,
     ulong version,
     AvailableCounters availableCounters,
     QueuedTickets queuedTickets) : base(id, version)
 {
     AvailableCounters = availableCounters;
     QueuedTickets     = queuedTickets;
 }
 private CustomerQueue Apply(CustomerRevoked e)
 {
     AvailableCounters.RemoveServingTicket(e.CounterName.ToCounterName());
     return(this);
 }
 public Result <CustomerQueue> RevokeCustomer(CounterName counterName) =>
 AvailableCounters.GetMaybeServingTicket(counterName)
 .OnSuccess(maybeServingTicket => maybeServingTicket.Map(
                servingTicket => ApplyChange(new CustomerRevoked(Id, counterName, servingTicket.Id))))
 .ToTypedResult(this);
 private CustomerQueue Apply(CustomerTaken e)
 {
     AvailableCounters.SetServingTicketFor(e.CounterName.ToCounterName(), QueuedTickets.GetWithId(e.TicketId.ToTicketId()));
     QueuedTickets = QueuedTickets.RemoveWithId(e.TicketId.ToTicketId());
     return(this);
 }
 public Result <CustomerQueue> TakeNextCustomer(CounterName counterName) => AvailableCounters
 .GetMaybeServingTicket(counterName)
 .OnSuccess(maybeServingTicketId => ApplyCustomerServedIfTicketIsBeingServed(maybeServingTicketId, counterName))
 .OnSuccess(_ => ApplyCustomerTakenIfThereIsPendingTicketInTheQueue(counterName))
 .ToTypedResult(this);
 private CustomerQueue Apply(CounterAdded e)
 {
     AvailableCounters = AvailableCounters.AddNewWith(e.CounterName.ToCounterName());
     return(this);
 }
 public Result <CustomerQueue> AddCounter(CounterName counterName) =>
 AvailableCounters.CheckIfCounterIsAvailableWith(counterName)
 .OnSuccess(() => ApplyChange(new CounterAdded(Id, counterName)))
 .ToTypedResult(this);