Beispiel #1
0
        public async Task <ResponseContent> ProcessOrderProposalCreationP(string clientId, Uri sellerId, string uuidString, string orderJson)
        {
            // Note B will never contain OrderItem level errors, and any issues that occur will be thrown as exceptions.
            // If C1 and C2 are used correctly, P should not fail except in very exceptional cases.
            OrderProposal order = OpenActiveSerializer.Deserialize <OrderProposal>(orderJson);

            if (order == null || order.GetType() != typeof(OrderProposal))
            {
                throw new OpenBookingException(new UnexpectedOrderTypeError(), "OrderProposal is required for P");
            }
            var(orderId, sellerIdComponents, seller) = await ConstructIdsFromRequest(clientId, sellerId, uuidString, OrderType.OrderProposal);

            using (await asyncDuplicateLock.LockAsync(GetParallelLockKey(orderId)))
            {
                return(ResponseContent.OpenBookingResponse(OpenActiveSerializer.Serialize(await ProcessFlowRequest(ValidateFlowRequest <OrderProposal>(orderId, sellerIdComponents, seller, FlowStage.P, order), order)), HttpStatusCode.Created));
            }
        }
Beispiel #2
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());
            }
        }
Beispiel #3
0
        public static Order CreateOrderFromOrderMode(OrderMode orderMode, Uri orderId, Guid?proposalVersionId, ProposalStatus?proposalStatus)
        {
            switch (orderMode)
            {
            case OrderMode.Booking:
                return(new Order());

            case OrderMode.Lease:
                return(new OrderQuote());

            case OrderMode.Proposal:
                var o = new OrderProposal();
                o.OrderProposalVersion = new Uri($"{orderId}/versions/{proposalVersionId.ToString()}");
                o.OrderProposalStatus  = proposalStatus == ProposalStatus.AwaitingSellerConfirmation ? OrderProposalStatus.AwaitingSellerConfirmation :
                                         proposalStatus == ProposalStatus.CustomerRejected ? OrderProposalStatus.CustomerRejected :
                                         proposalStatus == ProposalStatus.SellerAccepted ? OrderProposalStatus.SellerAccepted :
                                         proposalStatus == ProposalStatus.SellerRejected ? OrderProposalStatus.SellerRejected : (OrderProposalStatus?)null;
                return(o);

            default:
                throw new ArgumentOutOfRangeException(nameof(orderMode));
            }
        }
Beispiel #4
0
 public override ValueTask UpdateOrderProposal(OrderProposal responseOrderProposal, StoreBookingFlowContext flowContext, OrderStateContext stateContext, OrderTransaction databaseTransaction)
 {
     // Does nothing at the moment
     return(new ValueTask());
 }
Beispiel #5
0
        public override async ValueTask <(Guid, OrderProposalStatus)> CreateOrderProposal(OrderProposal responseOrderProposal, StoreBookingFlowContext flowContext, OrderStateContext stateContext, OrderTransaction databaseTransaction)
        {
            if (!responseOrderProposal.TotalPaymentDue.Price.HasValue)
            {
                throw new OpenBookingException(new OpenBookingError(), "Price must be set on TotalPaymentDue");
            }

            var version      = Guid.NewGuid();
            var customerType = flowContext.Customer == null ? CustomerType.None : (flowContext.Customer.GetType() == typeof(Organization) ? CustomerType.Organization : CustomerType.Person);
            var result       = await FakeDatabase.AddOrder(
                flowContext.OrderId.ClientId,
                flowContext.OrderId.uuid,
                flowContext.BrokerRole == BrokerType.AgentBroker?BrokerRole.AgentBroker : flowContext.BrokerRole == BrokerType.ResellerBroker?BrokerRole.ResellerBroker : BrokerRole.NoBroker,
                flowContext.Broker.Name,
                flowContext.Broker.Url,
                flowContext.Broker.Telephone,
                flowContext.SellerId.SellerIdLong ?? null, // Small hack to allow use of FakeDatabase when in Single Seller mode
                customerType == CustomerType.None?null : flowContext.Customer.Email,
                customerType,
                customerType == CustomerType.None?null : (customerType == CustomerType.Organization ? flowContext.Customer.Name : null),
                customerType == CustomerType.None?null : flowContext.Customer.Identifier.HasValue?flowContext.Customer.Identifier.Value.ToString() : null,
                customerType == CustomerType.None?null : (customerType == CustomerType.Organization ? null : flowContext.Customer.GivenName),
                customerType == CustomerType.None?null : (customerType == CustomerType.Organization ? null : flowContext.Customer.FamilyName),
                customerType == CustomerType.None?null : (customerType == CustomerType.Organization ? null : flowContext.Customer.Telephone),
                flowContext.Payment?.Identifier,
                flowContext.Payment?.Name,
                flowContext.Payment?.PaymentProviderId,
                flowContext.Payment?.AccountId,
                responseOrderProposal.TotalPaymentDue.Price.Value,
                databaseTransaction.FakeDatabaseTransaction,
                version,
                ProposalStatus.AwaitingSellerConfirmation);

            if (!result)
            {
                throw new OpenBookingException(new OrderAlreadyExistsError());
            }

            return(version, OrderProposalStatus.AwaitingSellerConfirmation);
        }