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)); } }
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()); } }
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)); } }
public override ValueTask UpdateOrderProposal(OrderProposal responseOrderProposal, StoreBookingFlowContext flowContext, OrderStateContext stateContext, OrderTransaction databaseTransaction) { // Does nothing at the moment return(new ValueTask()); }
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); }