/// <summary> /// Seats a customer that is a walk-in /// </summary> /// <param name="when">A mock value of the date/time (Temporary - see remarks)</param> /// <param name="tableNumber">Table number to be seated</param> /// <param name="customerCount">Number of customers being seated</param> /// <param name="waiterId">Id of waiter that is serving</param> public void SeatCustomer(DateTime when, byte tableNumber, int customerCount, int waiterId) { var availableSeats = AvailableSeatingByDateTime(when.Date, when.TimeOfDay); using (var context = new RestaurantContext()) { List<string> errors = new List<string>(); // Rule checking: // - Table must be available - typically a direct check on the table, but proxied based on the mocked time here // - Table must be big enough for the # of customers if (!availableSeats.Exists(x => x.Table == tableNumber)) errors.Add("Table is currently not available"); else if (!availableSeats.Exists(x => x.Table == tableNumber && x.Seating >= customerCount)) errors.Add("Insufficient seating capacity for number of customers."); if (errors.Count > 0) throw new BusinessRuleException("Unable to seat customer", errors); Bill seatedCustomer = new Bill() { BillDate = when, NumberInParty = customerCount, WaiterID = waiterId, TableID = context.Tables.Single(x => x.TableNumber == tableNumber).TableID }; context.Bills.Add(seatedCustomer); context.SaveChanges(); } }
/// <summary> /// Seats a customer that is a walk-in /// </summary> /// <param name="when">A mock value of the date/time (Temporary - see remarks)</param> /// <param name="tableNumber">Table number to be seated</param> /// <param name="customerCount">Number of customers being seated</param> /// <param name="waiterId">Id of waiter that is serving</param> public void SeatCustomer(DateTime when, int reservationId, List<byte> tables, int waiterId) { var availableSeats = AvailableSeatingByDateTime(when.Date, when.TimeOfDay); using (var context = new RestaurantContext()) { List<string> errors = new List<string>(); // Rule checking: // - Reservation must be in Booked status // - Table must be available - typically a direct check on the table, but proxied based on the mocked time here // - Table must be big enough for the # of customers var reservation = context.Reservations.Find(reservationId); if (reservation == null) errors.Add("The specified reservation does not exist"); else if (reservation.ReservationStatus != Reservation.Booked) errors.Add("The reservation's status is not valid for seating. Only booked reservations can be seated."); var capacity = 0; foreach (var tableNumber in tables) { if (!availableSeats.Exists(x => x.Table == tableNumber)) errors.Add("Table " + tableNumber + " is currently not available"); else capacity += availableSeats.Single(x => x.Table == tableNumber).Seating; } if (capacity < reservation.NumberInParty) errors.Add("Insufficient seating capacity for number of customers. Alternate tables must be used."); if (errors.Count > 0) throw new BusinessRuleException("Unable to seat customer", errors); // 1) Create a blank bill with assigned waiter Bill seatedCustomer = new Bill() { BillDate = when, NumberInParty = reservation.NumberInParty, WaiterID = waiterId, ReservationID = reservation.ReservationID }; context.Bills.Add(seatedCustomer); // 2) Add the tables for the reservation and change the reservation's status to arrived foreach (var tableNumber in tables) reservation.Tables.Add(context.Tables.Single(x => x.TableNumber == tableNumber)); reservation.ReservationStatus = Reservation.Arrived; var updatable = context.Entry(context.Reservations.Attach(reservation)); updatable.Property(x => x.ReservationStatus).IsModified = true; //updatable.Reference(x=>x.Tables). // 3) Save changes context.SaveChanges(); } //string message = String.Format("Not yet implemented. Need to seat reservation {0} for waiter {1} at tables {2}", reservationId, waiterId, string.Join(", ", tables)); //throw new NotImplementedException(message); }
public void SplitBill(int billId, List<OrderItem> updatesToOriginalBillItems, List<OrderItem> newBillItems) { // TODO: Actually go through and split that bill into two using (var context = new RestaurantContext()) { // TODO: 0) Validation :) // 1) Get the bill var bill = context.Bills.Find(billId); if (bill == null) throw new ArgumentException("Invalid Bill ID - does not exist"); // 2) Loop through bill items, if item not in original, remove List<BillItem> toMove = new List<BillItem>(); foreach(var item in bill.Items) // the items already in the DB { bool inOriginal = updatesToOriginalBillItems.Any(x => x.ItemName == item.Item.Description); bool inNewItems = newBillItems.Any(x => x.ItemName == item.Item.Description); if(!inOriginal) { // TODO: clean if (!inNewItems) throw new Exception("Hey - someone's got to pay for that!"); toMove.Add(item); } } foreach (var item in toMove) context.BillItems.Remove(item); // 3) Make a new bill var newBill = new Bill() { BillDate = bill.BillDate, Comment = "Split from bill# " + bill.BillID, NumberInParty = bill.NumberInParty, // meh OrderPlaced = bill.OrderPlaced, OrderReady = bill.OrderReady, OrderServed = bill.OrderServed, WaiterID = bill.WaiterID // TODO: thorny question about rules around splitting bill for a single table vs. reservation }; // 4) Add the new missing items to the new bill foreach(var item in toMove) { newBill.Items.Add(new BillItem() { ItemID = item.ItemID, Notes = item.Notes, Quantity = item.Quantity, SalePrice = item.SalePrice, UnitCost = item.UnitCost }); } // 5) Add the new bill to the context context.Bills.Add(newBill); // 6) hope for the best. context.SaveChanges(); } }