/// <summary> /// Places a new <c>Order</c>. /// </summary> /// <param name="options">Options for creating a new <c>StoreContext</c>.</param> /// <param name="orderId">The ID of a previously saved <c>Order</c>.</param> /// <param name="maxQuantity">The maximum amount of <c>Product</c> that may be present in an <c>Order</c>.</param> /// <returns>A <c>PlaceOrderResult</c> detailing whether the operation completed successfully.</returns> public static PlaceOrderResult PlaceOrder(this DbContextOptions <StoreContext> options, Guid?orderId, int maxQuantity) { if (orderId == null) { throw new NullReferenceException("Missing orderId"); } using (var db = new StoreContext(options)) { var order = db.GetOrderById(orderId); if (order == null) { return(PlaceOrderResult.OrderNotFound); } if (order.OrderLineItems.Count() == 0) { return(PlaceOrderResult.NoLineItems); } var totalOrderPrice = 0.0; var totalItemQuantity = 0; var location = order.Location; using (var transaction = db.Database.BeginTransaction()) { foreach (var lineItem in order.OrderLineItems) { var locationInventory = db.FindInventoryId(location, lineItem.Product); if (locationInventory == null) { return(PlaceOrderResult.OutOfStock); } var newStockQuantity = locationInventory.TryAdjustQuantity(-lineItem.Quantity); if (newStockQuantity == null) { transaction.Rollback(); return(PlaceOrderResult.OutOfStock); } var lineItemPrice = lineItem.Quantity * lineItem.Product.Price; totalOrderPrice += lineItemPrice; lineItem.AmountCharged = lineItemPrice; totalItemQuantity += lineItem.Quantity; db.SaveChanges(); } if (totalItemQuantity > maxQuantity) { return(PlaceOrderResult.HighQuantityRejection); } order.AmountPaid = totalOrderPrice; order.TimeSubmitted = DateTime.Now; db.SaveChanges(); transaction.Commit(); } return(PlaceOrderResult.Ok); } }