Ejemplo n.º 1
0
        //TODO: This should reuse code of LeaseOrderItem
        protected override async ValueTask BookOrderItems(List <OrderItemContext <FacilityOpportunity> > orderItemContexts, StoreBookingFlowContext flowContext, OrderStateContext stateContext, OrderTransaction databaseTransaction)
        {
            // Check that there are no conflicts between the supplied opportunities
            // Also take into account spaces requested across OrderItems against total spaces in each opportunity
            foreach (var ctxGroup in orderItemContexts.GroupBy(x => x.RequestBookableOpportunityOfferId))
            {
                // Check that the Opportunity ID and type are as expected for the store
                if (ctxGroup.Key.OpportunityType != OpportunityType.FacilityUseSlot || !ctxGroup.Key.SlotId.HasValue)
                {
                    throw new OpenBookingException(new UnableToProcessOrderItemError(), "Opportunity ID and type are as not expected for the FacilityStore, during booking");
                }

                // Attempt to book for those with the same IDs, which is atomic
                var(result, bookedOrderItemInfos) = await FakeDatabase.BookOrderItemsForFacilitySlot(
                    databaseTransaction.FakeDatabaseTransaction,
                    flowContext.OrderId.ClientId,
                    flowContext.SellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
                    flowContext.OrderId.uuid,
                    ctxGroup.Key.SlotId.Value,
                    RenderOpportunityId(ctxGroup.Key),
                    RenderOfferId(ctxGroup.Key),
                    ctxGroup.Count(),
                    false
                    );

                switch (result)
                {
                case ReserveOrderItemsResult.Success:
                    foreach (var(ctx, bookedOrderItemInfo) in ctxGroup.Zip(bookedOrderItemInfos, (ctx, bookedOrderItemInfo) => (ctx, bookedOrderItemInfo)))
                    {
                        // Set OrderItemId and access properties for each orderItemContext
                        ctx.SetOrderItemId(flowContext, bookedOrderItemInfo.OrderItemId);
                        BookedOrderItemHelper.AddPropertiesToBookedOrderItem(ctx, bookedOrderItemInfo);
                    }
                    break;

                case ReserveOrderItemsResult.SellerIdMismatch:
                    throw new OpenBookingException(new SellerMismatchError(), "An OrderItem SellerID did not match");

                case ReserveOrderItemsResult.OpportunityNotFound:
                    throw new OpenBookingException(new UnableToProcessOrderItemError(), "Opportunity not found");

                case ReserveOrderItemsResult.NotEnoughCapacity:
                    throw new OpenBookingException(new OpportunityHasInsufficientCapacityError());

                case ReserveOrderItemsResult.OpportunityOfferPairNotBookable:
                    throw new OpenBookingException(new UnableToProcessOrderItemError(), "Opportunity and offer pair were not bookable");

                default:
                    throw new OpenBookingException(new OrderCreationFailedError(), "Booking failed for an unexpected reason");
                }
            }
        }