示例#1
0
        public override async Task <bool> CreateOrderFromOrderProposal(OrderIdComponents orderId, SellerIdComponents sellerId, Uri orderProposalVersion, Order order)
        {
            // TODO more elegantly extract version UUID from orderProposalVersion (probably much further up the stack?)
            var version = new Guid(orderProposalVersion.ToString().Split('/').Last());

            var result = await FakeBookingSystem.Database.BookOrderProposal(
                orderId.ClientId,
                sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
                orderId.uuid,
                version);

            // TODO return enum to allow errors cases to be handled in the engine
            switch (result)
            {
            case FakeDatabaseBookOrderProposalResult.OrderSuccessfullyBooked:
                return(true);

            case FakeDatabaseBookOrderProposalResult.OrderProposalVersionOutdated:
                return(false);

            case FakeDatabaseBookOrderProposalResult.OrderProposalNotAccepted:
                throw new OpenBookingException(new OrderCreationFailedError(), "OrderProposal has not been accepted by the Seller");

            case FakeDatabaseBookOrderProposalResult.OrderWasNotFound:
                throw new OpenBookingException(new UnknownOrderError());

            default:
                throw new OpenBookingException(new OpenBookingError(), $"Unexpected FakeDatabaseDeleteOrderResult: {result}");
            }
        }
示例#2
0
 public override async Task DeleteLease(OrderIdComponents orderId, SellerIdComponents sellerId)
 {
     // Note if no lease support, simply do nothing here
     await FakeBookingSystem.Database.DeleteLease(
         orderId.ClientId,
         orderId.uuid,
         sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */
         );
 }
示例#3
0
        public async Task <ResponseContent> DeleteOrderQuote(string clientId, Uri sellerId, string uuidString)
        {
            var orderId = new OrderIdComponents {
                ClientId = clientId, OrderType = OrderType.OrderQuote, uuid = ConvertToGuid(uuidString)
            };

            using (await asyncDuplicateLock.LockAsync(GetParallelLockKey(orderId)))
            {
                await ProcessOrderQuoteDeletion(orderId, GetSellerIdComponentsFromApiKey(sellerId));

                return(ResponseContent.OpenBookingNoContentResponse());
            }
        }
        //TODO: Should we move Seller into the Abstract level? Perhaps too much complexity
        private O ValidateFlowRequest <O>(string clientId, Uri authenticationSellerId, FlowStage stage, string uuid, OrderType orderType, O orderQuote) where O : Order, new()
        {
            var orderId = new OrderIdComponents
            {
                ClientId  = clientId,
                uuid      = uuid,
                OrderType = orderType
            };

            // TODO: Add more request validation rules here

            SellerIdComponents sellerIdComponents = GetSellerIdComponentsFromApiKey(authenticationSellerId);

            ILegalEntity seller = settings.SellerStore.GetSellerById(sellerIdComponents);

            if (seller == null)
            {
                throw new OpenBookingException(new SellerNotFoundError());
            }

            if (orderQuote?.Seller?.Id != null && seller?.Id != orderQuote?.Seller?.Id)
            {
                throw new OpenBookingException(new SellerMismatchError());
            }

            // Check that taxMode is set in Seller
            if (!(seller?.TaxMode == TaxMode.TaxGross || seller?.TaxMode == TaxMode.TaxNet))
            {
                throw new EngineConfigurationException("taxMode must always be set in the Seller");
            }

            // Default to BusinessToConsumer if no customer provided
            TaxPayeeRelationship taxPayeeRelationship =
                orderQuote.Customer == null ?
                TaxPayeeRelationship.BusinessToConsumer :
                orderQuote.BrokerRole == BrokerType.ResellerBroker || orderQuote.Customer.IsOrganization
                        ? TaxPayeeRelationship.BusinessToBusiness : TaxPayeeRelationship.BusinessToConsumer;

            var payer = orderQuote.BrokerRole == BrokerType.ResellerBroker ? orderQuote.Broker : orderQuote.Customer;

            return(ProcessFlowRequest <O>(new BookingFlowContext {
                Stage = stage,
                OrderId = orderId,
                OrderIdTemplate = settings.OrderIdTemplate,
                Seller = seller,
                SellerId = sellerIdComponents,
                TaxPayeeRelationship = taxPayeeRelationship,
                Payer = payer
            }, orderQuote));
        }
示例#5
0
 /// <summary>
 /// Initiate customer cancellation for the specified OrderItems
 /// Note sellerId will always be null in Single Seller mode
 /// </summary>
 /// <returns>True if Order found, False if Order not found</returns>
 public override async Task <bool> CustomerCancelOrderItems(OrderIdComponents orderId, SellerIdComponents sellerId, List <OrderIdComponents> orderItemIds)
 {
     try
     {
         return(await FakeBookingSystem.Database.CancelOrderItems(
                    orderId.ClientId,
                    sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
                    orderId.uuid,
                    orderItemIds.Where(x => x.OrderItemIdLong.HasValue).Select(x => x.OrderItemIdLong.Value).ToList(), true));
     }
     catch (InvalidOperationException ex)
     {
         throw new OpenBookingException(new CancellationNotPermittedError(), ex.Message);
     }
 }
示例#6
0
        public void SingleIdTemplate_GetIdComponents_EnumToId()
        {
            var template = new OrderIdTemplate(
                "{+BaseUrl}api/{OrderType}/{uuid}",
                "{+BaseUrl}api/{OrderType}/{uuid}#/orderedItems/{OrderItemIdLong}"
                );

            template.RequiredBaseUrl = new Uri("https://example.com/");

            OrderIdComponents components = new OrderIdComponents
            {
                uuid            = new Guid("3cbb8557-ca8f-4889-b21f-a59f860f8d25"),
                OrderItemIdLong = 123,
                OrderType       = OrderType.Order
            };

            var id = template.RenderOrderItemId(components);

            Assert.Equal(new Uri("https://example.com/api/orders/3cbb8557-ca8f-4889-b21f-a59f860f8d25#/orderedItems/123"), id);
        }
        public void SingleIdTemplate_GetIdComponents_EnumToId()
        {
            var template = new OrderIdTemplate(
                "{+BaseUrl}api/{OrderType}/{uuid}",
                "{+BaseUrl}api/{OrderType}/{uuid}#/orderedItems/{OrderItemIdLong}"
                );

            template.RequiredBaseUrl = new Uri("https://example.com/");

            OrderIdComponents components = new OrderIdComponents
            {
                uuid            = "asdf",
                OrderItemIdLong = 123,
                OrderType       = OrderType.Order
            };

            var id = template.RenderOrderItemId(components);

            Assert.Equal(new Uri("https://example.com/api/orders/asdf#/orderedItems/123"), id);
        }
示例#8
0
        private async Task <(OrderIdComponents orderId, SellerIdComponents sellerIdComponents, ILegalEntity seller)> ConstructIdsFromRequest(string clientId, Uri authenticationSellerId, string uuidString, OrderType orderType)
        {
            var orderId = new OrderIdComponents
            {
                ClientId  = clientId,
                uuid      = ConvertToGuid(uuidString),
                OrderType = orderType
            };

            // TODO: Add more request validation rules here

            SellerIdComponents sellerIdComponents = GetSellerIdComponentsFromApiKey(authenticationSellerId);

            ILegalEntity seller = await settings.SellerStore.GetSellerById(sellerIdComponents);

            if (seller == null)
            {
                throw new OpenBookingException(new SellerNotFoundError());
            }

            return(orderId, sellerIdComponents, seller);
        }
示例#9
0
        public async Task <ResponseContent> ProcessOrderProposalUpdate(string clientId, Uri sellerId, string uuidString, string orderProposalJson)
        {
            var orderId = new OrderIdComponents {
                ClientId = clientId, OrderType = OrderType.OrderProposal, uuid = ConvertToGuid(uuidString)
            };

            using (await asyncDuplicateLock.LockAsync(GetParallelLockKey(orderId)))
            {
                OrderProposal      orderProposal      = OpenActiveSerializer.Deserialize <OrderProposal>(orderProposalJson);
                SellerIdComponents sellerIdComponents = GetSellerIdComponentsFromApiKey(sellerId);

                if (orderProposal == null || orderProposal.GetType() != typeof(Order))
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "OrderProposal is required for Order Cancellation");
                }

                // Check for PatchContainsExcessiveProperties
                OrderProposal orderProposalWithOnlyAllowedProperties = new OrderProposal
                {
                    OrderProposalStatus = orderProposal.OrderProposalStatus,
                    OrderCustomerNote   = orderProposal.OrderCustomerNote
                };
                if (OpenActiveSerializer.Serialize <OrderProposal>(orderProposal) != OpenActiveSerializer.Serialize <OrderProposal>(orderProposalWithOnlyAllowedProperties))
                {
                    throw new OpenBookingException(new PatchContainsExcessivePropertiesError());
                }

                // Check for PatchNotAllowedOnProperty
                if (orderProposal.OrderProposalStatus != OrderProposalStatus.CustomerRejected)
                {
                    throw new OpenBookingException(new PatchNotAllowedOnPropertyError(), "Only 'https://openactive.io/CustomerRejected' is permitted for this property.");
                }

                await ProcessOrderProposalCustomerRejection(orderId, sellerIdComponents, settings.OrderIdTemplate);

                return(ResponseContent.OpenBookingNoContentResponse());
            }
        }
示例#10
0
        public override async Task <DeleteOrderResult> DeleteOrder(OrderIdComponents orderId, SellerIdComponents sellerId)
        {
            var result = await FakeBookingSystem.Database.DeleteOrder(
                orderId.ClientId,
                orderId.uuid,
                sellerId.SellerIdLong ?? null /* Small hack to allow use of FakeDatabase when in Single Seller mode */);

            switch (result)
            {
            case FakeDatabaseDeleteOrderResult.OrderSuccessfullyDeleted:
            // "OrderWasAlreadyDeleted" is being treated as a success because the order did
            // exist - This maintains idempotency as requests that follow a successful request
            // will still return a 2xx.
            case FakeDatabaseDeleteOrderResult.OrderWasAlreadyDeleted:
                return(DeleteOrderResult.OrderSuccessfullyDeleted);

            case FakeDatabaseDeleteOrderResult.OrderWasNotFound:
                return(DeleteOrderResult.OrderDidNotExist);

            default:
                throw new OpenBookingException(new OpenBookingError(), $"Unexpected FakeDatabaseDeleteOrderResult: {result}");
            }
        }
示例#11
0
        public async Task <ResponseContent> DeleteOrder(string clientId, Uri sellerId, string uuidString)
        {
            var orderId = new OrderIdComponents {
                ClientId = clientId, OrderType = OrderType.Order, uuid = ConvertToGuid(uuidString)
            };

            using (await asyncDuplicateLock.LockAsync(GetParallelLockKey(orderId)))
            {
                var result = await ProcessOrderDeletion(orderId, GetSellerIdComponentsFromApiKey(sellerId));

                switch (result)
                {
                case DeleteOrderResult.OrderSuccessfullyDeleted:
                    return(ResponseContent.OpenBookingNoContentResponse());

                case DeleteOrderResult.OrderDidNotExist:
                    throw new OpenBookingException(new UnknownOrderError());

                default:
                    throw new OpenBookingException(new OpenBookingError(), $"Unexpected DeleteOrderResult: {result}");
                }
            }
        }
 protected abstract void ProcessOrderQuoteDeletion(OrderIdComponents orderId, SellerIdComponents sellerId);
 public abstract void ProcessCustomerCancellation(OrderIdComponents orderId, SellerIdComponents sellerId, OrderIdTemplate orderIdTemplate, List <OrderIdComponents> orderItemIds);
 public abstract bool CustomerCancelOrderItems(OrderIdComponents orderId, SellerIdComponents sellerId, OrderIdTemplate orderIdTemplate, List <OrderIdComponents> orderItemIds);
 public abstract void DeleteLease(OrderIdComponents orderId, SellerIdComponents sellerId);
示例#16
0
        //TODO: Should we move Seller into the Abstract level? Perhaps too much complexity
        protected BookingFlowContext ValidateFlowRequest <TOrder>(OrderIdComponents orderId, SellerIdComponents sellerIdComponents, ILegalEntity seller, FlowStage stage, TOrder order) where TOrder : Order, new()
        {
            // If being called from Order Status then expect Seller to already be a full object
            var sellerIdFromOrder = stage == FlowStage.OrderStatus ? order?.Seller.Object?.Id : order?.Seller.IdReference;

            if (sellerIdFromOrder == null)
            {
                throw new OpenBookingException(new SellerMismatchError());
            }

            if (seller?.Id != sellerIdFromOrder)
            {
                throw new OpenBookingException(new InvalidAuthorizationDetailsError());
            }

            // Check that taxMode is set in Seller
            if (!(seller?.TaxMode == TaxMode.TaxGross || seller?.TaxMode == TaxMode.TaxNet))
            {
                throw new InternalOpenBookingException(new InternalLibraryConfigurationError(), "taxMode must always be set in the Seller");
            }

            // Default to BusinessToConsumer if no customer provided
            TaxPayeeRelationship taxPayeeRelationship =
                order.Customer == null ?
                TaxPayeeRelationship.BusinessToConsumer :
                order.BrokerRole == BrokerType.ResellerBroker || order.Customer.IsOrganization
                        ? TaxPayeeRelationship.BusinessToBusiness : TaxPayeeRelationship.BusinessToConsumer;

            if (order.BrokerRole == null)
            {
                throw new OpenBookingException(new IncompleteBrokerDetailsError());
            }

            if (order.BrokerRole == BrokerType.NoBroker && order.Broker != null)
            {
                throw new OpenBookingException(new IncompleteBrokerDetailsError()); // TODO: Placeholder for https://github.com/openactive/open-booking-api/issues/167
            }

            // Throw error on incomplete customer details if C2, P or B if Broker type is not ResellerBroker
            if (order.BrokerRole != BrokerType.ResellerBroker)
            {
                if (stage != FlowStage.C1 && (order.Customer == null || string.IsNullOrWhiteSpace(order.Customer.Email)))
                {
                    throw new OpenBookingException(new IncompleteCustomerDetailsError());
                }
            }

            // Throw error on incomplete broker details
            if (order.BrokerRole != BrokerType.NoBroker && (order.Broker == null || string.IsNullOrWhiteSpace(order.Broker.Name)))
            {
                throw new OpenBookingException(new IncompleteBrokerDetailsError());
            }

            // Throw error if TotalPaymentDue is not specified at B or P
            if (order.TotalPaymentDue?.Price.HasValue != true && (stage == FlowStage.B || stage == FlowStage.P))
            {
                // TODO replace this with a more specific error
                throw new OpenBookingException(new OpenBookingError(), "TotalPaymentDue must have a price set");
            }

            var payer = order.BrokerRole == BrokerType.ResellerBroker ? order.Broker : order.Customer;

            return(new BookingFlowContext
            {
                Stage = stage,
                OrderId = orderId,
                OrderIdTemplate = settings.OrderIdTemplate,
                Seller = seller,
                SellerId = sellerIdComponents,
                TaxPayeeRelationship = taxPayeeRelationship,
                Payer = payer
            });
        }
示例#17
0
 public abstract Task <Order> ProcessOrderCreationFromOrderProposal(OrderIdComponents orderId, OrderIdTemplate orderIdTemplate, ILegalEntity seller, SellerIdComponents sellerId, Order order);
示例#18
0
 public abstract Task ProcessOrderProposalCustomerRejection(OrderIdComponents orderId, SellerIdComponents sellerId, OrderIdTemplate orderIdTemplate);
示例#19
0
 public override void DeleteOrder(OrderIdComponents orderId, SellerIdComponents sellerId)
 {
     FakeBookingSystem.Database.DeleteOrder(orderId.ClientId, orderId.uuid, sellerId.SellerIdLong ?? null /* Small hack to allow use of FakeDatabase when in Single Seller mode */);
 }
示例#20
0
        public async Task <ResponseContent> ProcessOrderUpdate(string clientId, Uri sellerId, string uuidString, string orderJson)
        {
            var orderId = new OrderIdComponents {
                ClientId = clientId, OrderType = OrderType.Order, uuid = ConvertToGuid(uuidString)
            };

            using (await asyncDuplicateLock.LockAsync(GetParallelLockKey(orderId)))
            {
                Order order = OpenActiveSerializer.Deserialize <Order>(orderJson);
                SellerIdComponents sellerIdComponents = GetSellerIdComponentsFromApiKey(sellerId);

                if (order == null || order.GetType() != typeof(Order))
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "Order is required for Order Cancellation");
                }

                // Check for PatchContainsExcessiveProperties
                Order orderWithOnlyAllowedProperties = new Order
                {
                    OrderedItem = order.OrderedItem.Select(x => new OrderItem {
                        Id = x.Id, OrderItemStatus = x.OrderItemStatus
                    }).ToList()
                };
                if (OpenActiveSerializer.Serialize <Order>(order) != OpenActiveSerializer.Serialize <Order>(orderWithOnlyAllowedProperties))
                {
                    throw new OpenBookingException(new PatchContainsExcessivePropertiesError());
                }

                // Check for PatchNotAllowedOnProperty
                if (!order.OrderedItem.TrueForAll(x => x.OrderItemStatus == OrderItemStatus.CustomerCancelled))
                {
                    throw new OpenBookingException(new PatchNotAllowedOnPropertyError(), "Only 'https://openactive.io/CustomerCancelled' is permitted for this property.");
                }

                List <OrderIdComponents> orderItemIds;
                try
                {
                    orderItemIds = order.OrderedItem.Select(x => settings.OrderIdTemplate.GetOrderItemIdComponents(clientId, x.Id)).ToList();
                }
                catch (ComponentFailedToParseException)
                {
                    throw new OpenBookingException(new OrderItemIdInvalidError());
                }

                // Check for mismatching UUIDs
                if (!orderItemIds.TrueForAll(x => x != null))
                {
                    throw new OpenBookingException(new OrderItemIdInvalidError());
                }

                // Check for mismatching UUIDs
                if (!orderItemIds.TrueForAll(x => x.OrderType == OrderType.Order && x.uuid == orderId.uuid))
                {
                    throw new OpenBookingException(new OrderItemNotWithinOrderError());
                }

                await ProcessCustomerCancellation(orderId, sellerIdComponents, settings.OrderIdTemplate, orderItemIds);

                return(ResponseContent.OpenBookingNoContentResponse());
            }
        }
示例#21
0
        public override async Task <Order> GetOrderStatus(OrderIdComponents orderId, SellerIdComponents sellerId, ILegalEntity seller)
        {
            var(getOrderResult, dbOrder, dbOrderItems) = await FakeBookingSystem.Database.GetOrderAndOrderItems(
                orderId.ClientId,
                sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
                orderId.uuid);

            if (getOrderResult == FakeDatabaseGetOrderResult.OrderWasNotFound)
            {
                throw new OpenBookingException(new UnknownOrderError());
            }

            var orderIdUri = RenderOrderId(dbOrder.OrderMode == OrderMode.Proposal ? OrderType.OrderProposal : dbOrder.OrderMode == OrderMode.Lease ? OrderType.OrderQuote : OrderType.Order, new Guid(dbOrder.OrderId));
            var orderItems = dbOrderItems.Select((orderItem) => new OrderItem
            {
                Id            = dbOrder.OrderMode != OrderMode.Lease ? RenderOrderItemId(OrderType.Order, new Guid(dbOrder.OrderId), orderItem.Id) : null,
                AcceptedOffer = new Offer
                {
                    Id    = orderItem.OfferJsonLdId,
                    Price = orderItem.Price
                },
                OrderedItem     = orderItem.OpportunityJsonLdId,
                OrderItemStatus =
                    orderItem.Status == BookingStatus.Confirmed ? OrderItemStatus.OrderItemConfirmed :
                    orderItem.Status == BookingStatus.CustomerCancelled ? OrderItemStatus.CustomerCancelled :
                    orderItem.Status == BookingStatus.SellerCancelled ? OrderItemStatus.SellerCancelled :
                    orderItem.Status == BookingStatus.Attended ? OrderItemStatus.AttendeeAttended :
                    orderItem.Status == BookingStatus.Absent ? OrderItemStatus.AttendeeAbsent : (OrderItemStatus?)null
            }).ToList();
            var order = RenderOrderFromDatabaseResult(orderIdUri, dbOrder, orderItems);

            // Map AcceptedOffer from object to IdReference
            var mappedOrderItems = order.OrderedItem.Select((orderItem) => new OrderItem
            {
                Id              = orderItem.Id,
                AcceptedOffer   = orderItem.AcceptedOffer.Object.Id,
                OrderedItem     = orderItem.OrderedItem,
                OrderItemStatus = orderItem.OrderItemStatus
            }).ToList();

            order.OrderedItem = mappedOrderItems;

            // These additional properties that are only available in the Order Status endpoint or B after P+A
            order.Seller     = new ReferenceValue <ILegalEntity>(seller);
            order.BrokerRole = BrokerRoleToBrokerType(dbOrder.BrokerRole);
            order.Broker     = order.BrokerRole == BrokerType.NoBroker ? null : new Organization
            {
                Name      = dbOrder.BrokerName,
                Url       = dbOrder.BrokerUrl,
                Telephone = dbOrder.BrokerTelephone
            };
            order.BrokerRole = BrokerRoleToBrokerType(dbOrder.BrokerRole);
            if (dbOrder.CustomerType == CustomerType.Organization)
            {
                order.Customer = new Organization
                {
                    Email = dbOrder.CustomerEmail,
                    Name  = dbOrder.CustomerOrganizationName,
                };
            }
            else if (dbOrder.CustomerType == CustomerType.Person)
            {
                order.Customer = new Person
                {
                    Email      = dbOrder.CustomerEmail,
                    Identifier = dbOrder.CustomerIdentifier,
                    GivenName  = dbOrder.CustomerGivenName,
                    FamilyName = dbOrder.CustomerFamilyName,
                    Telephone  = dbOrder.CustomerTelephone,
                };
            }
            // Payment Identifier is mandatory for non-free sessions
            if (dbOrder.PaymentIdentifier != null)
            {
                order.Payment = new Payment
                {
                    Identifier        = dbOrder.PaymentIdentifier,
                    PaymentProviderId = dbOrder.PaymentProviderId,
                    AccountId         = dbOrder.PaymentAccountId,
                    Name = dbOrder.PaymentName
                };
            }

            return(order);
        }
示例#22
0
 /// <summary>
 /// Reject specified OrderProposal
 /// Note sellerId will always be null in Single Seller mode
 /// </summary>
 /// <returns>True if OrderProposal found, False if OrderProposal not found</returns>
 public override async Task <bool> CustomerRejectOrderProposal(OrderIdComponents orderId, SellerIdComponents sellerId)
 {
     return(await FakeBookingSystem.Database.RejectOrderProposal(orderId.ClientId, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */, orderId.uuid, true));
 }
示例#23
0
 public override void DeleteLease(OrderIdComponents orderId, SellerIdComponents sellerId)
 {
     // Note if no lease support, simply do nothing here
     FakeBookingSystem.Database.DeleteLease(orderId.ClientId, orderId.uuid, sellerId.SellerIdLong.Value);
 }
示例#24
0
        public override async Task TriggerTestAction(OpenBookingSimulateAction simulateAction, OrderIdComponents orderId)
        {
            switch (simulateAction)
            {
            case SellerAcceptOrderProposalSimulateAction _:
                if (orderId.OrderType != OrderType.OrderProposal)
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected OrderProposal");
                }
                if (!await FakeBookingSystem.Database.AcceptOrderProposal(orderId.uuid))
                {
                    throw new OpenBookingException(new UnknownOrderError());
                }
                break;

            case SellerAmendOrderProposalSimulateAction _:
                if (orderId.OrderType != OrderType.OrderProposal)
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected OrderProposal");
                }
                var version = Guid.NewGuid();
                if (!await FakeBookingSystem.Database.AmendOrderProposal(orderId.uuid, version))
                {
                    throw new OpenBookingException(new UnknownOrderError());
                }
                break;

            case SellerRejectOrderProposalSimulateAction _:
                if (orderId.OrderType != OrderType.OrderProposal)
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected OrderProposal");
                }
                if (!await FakeBookingSystem.Database.RejectOrderProposal(null, null, orderId.uuid, false))
                {
                    throw new OpenBookingException(new UnknownOrderError());
                }
                break;

            case SellerRequestedCancellationWithMessageSimulateAction _:
                if (orderId.OrderType != OrderType.Order)
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order");
                }
                if (!await FakeBookingSystem.Database.CancelOrderItems(null, null, orderId.uuid, null, false, true))
                {
                    throw new OpenBookingException(new UnknownOrderError());
                }
                break;

            case SellerRequestedCancellationSimulateAction _:
                if (orderId.OrderType != OrderType.Order)
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order");
                }
                if (!await FakeBookingSystem.Database.CancelOrderItems(null, null, orderId.uuid, null, false))
                {
                    throw new OpenBookingException(new UnknownOrderError());
                }
                break;

            case AccessCodeUpdateSimulateAction _:
                if (orderId.OrderType != OrderType.Order)
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order");
                }
                if (!await FakeBookingSystem.Database.UpdateAccess(orderId.uuid, updateAccessCode: true))
                {
                    throw new OpenBookingException(new UnknownOrderError());
                }
                break;

            case AccessPassUpdateSimulateAction _:
                if (orderId.OrderType != OrderType.Order)
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order");
                }
                if (!await FakeBookingSystem.Database.UpdateAccess(orderId.uuid, updateAccessPass: true))
                {
                    throw new OpenBookingException(new UnknownOrderError());
                }
                break;

            case AttendeeAttendedSimulateAction _:
                if (orderId.OrderType != OrderType.Order)
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order");
                }
                if (!await FakeBookingSystem.Database.UpdateOpportunityAttendance(orderId.uuid, true))
                {
                    throw new OpenBookingException(new UnknownOrderError());
                }
                break;

            case AttendeeAbsentSimulateAction _:
                if (orderId.OrderType != OrderType.Order)
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order");
                }
                if (!await FakeBookingSystem.Database.UpdateOpportunityAttendance(orderId.uuid, false))
                {
                    throw new OpenBookingException(new UnknownOrderError());
                }
                break;

            case CustomerNoticeSimulateAction _:
                if (orderId.OrderType != OrderType.Order)
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order");
                }
                if (!await FakeBookingSystem.Database.AddCustomerNotice(orderId.uuid))
                {
                    throw new OpenBookingException(new UnknownOrderError());
                }
                break;

            case ReplacementSimulateAction _:
                if (orderId.OrderType != OrderType.Order)
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order");
                }
                if (!await FakeBookingSystem.Database.ReplaceOrderOpportunity(orderId.uuid))
                {
                    throw new OpenBookingException(new UnknownOrderError());
                }
                break;

            case AccessChannelUpdateSimulateAction _:
                if (orderId.OrderType != OrderType.Order)
                {
                    throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order");
                }
                if (!await FakeBookingSystem.Database.UpdateAccess(orderId.uuid, updateAccessChannel: true))
                {
                    throw new OpenBookingException(new UnknownOrderError());
                }
                break;
            }
        }
示例#25
0
 private static string GetParallelLockKey(OrderIdComponents orderId)
 {
     // Use parsed GUID value and system defined ClientId rather than string to protect locks from abuse
     return($"{orderId.ClientId}|{orderId.uuid}".ToUpperInvariant());
 }
示例#26
0
 protected abstract Task <Order> ProcessGetOrderStatus(OrderIdComponents orderId, SellerIdComponents sellerId, ILegalEntity seller);
示例#27
0
 protected abstract Task <DeleteOrderResult> ProcessOrderDeletion(OrderIdComponents orderId, SellerIdComponents sellerId);
示例#28
0
 /// <summary>
 /// Initiate customer cancellation for the specified OrderItems
 /// Note sellerId will always be null in Single Seller mode
 /// </summary>
 /// <returns>True if Order found, False if Order not found</returns>
 public override bool CustomerCancelOrderItems(OrderIdComponents orderId, SellerIdComponents sellerId, OrderIdTemplate orderIdTemplate, List <OrderIdComponents> orderItemIds)
 {
     //throw new OpenBookingException(new CancellationNotPermittedError());
     return(FakeBookingSystem.Database.CancelOrderItem(orderId.ClientId, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */, orderId.uuid, orderItemIds.Select(x => x.OrderItemIdLong.Value).ToList(), true));
 }