/// <summary> /// Creates a sales order given the cart and payment information. /// </summary> /// <param name="request">The request.</param> /// <returns>The response.</returns> protected override SaveCustomerOrderResponse Process(SaveCustomerOrderRequest request) { ThrowIf.Null(request, "request"); ThrowIf.Null(request.CartId, "request.CartId"); // Get the Sales Transaction SalesTransaction transaction = CustomerOrderWorkflowHelper.GetSalesTransaction(this.Context, request.CartId, request.ReceiptEmailAddress); // Update customer order fields before validation CustomerOrderWorkflowHelper.UpdateCustomerOrderFieldsOnCheckout(transaction); // Return validations switch (transaction.CustomerOrderMode) { case CustomerOrderMode.Return: CustomerOrderWorkflowHelper.ValidateOrderForReturn(this.Context, transaction); break; case CustomerOrderMode.CustomerOrderCreateOrEdit: case CustomerOrderMode.QuoteCreateOrEdit: CustomerOrderWorkflowHelper.ValidateOrderAndQuoteCreationAndUpdate(this.Context, transaction); break; default: throw new NotSupportedException( string.Format(CultureInfo.InvariantCulture, "Customer order mode {0} not supported.", transaction.CustomerOrderMode)); } // Add customer order specific missing dependencies to the sales transaction CustomerOrderWorkflowHelper.FillMissingRequirementsForOrder(this.Context, transaction); // Resolve addresses ShippingHelper.ValidateAndResolveAddresses(this.Context, transaction); // Validate shipping addresses ShippingHelper.ValidateShippingInformation(this.Context, transaction); // Validate required reason code lines has been filled ReasonCodesWorkflowHelper.ValidateRequiredReasonCodeLinesFilled(this.Context, transaction); // Fill in receipt id. Receipt id will be needed if paying with credit memo. transaction = CustomerOrderWorkflowHelper.FillInReceiptId(this.Context, transaction, request.ReceiptNumberSequence); // Handle payments if (request.TokenizedPaymentCard != null) { transaction = CustomerOrderWorkflowHelper.HandlePayments(this.Context, transaction, request.TokenizedPaymentCard); } else { transaction = CustomerOrderWorkflowHelper.HandlePayments(this.Context, transaction); } // Create order through transaction service SalesOrder salesOrder = CustomerOrderWorkflowHelper.SaveCustomerOrder(this.Context, transaction); CartWorkflowHelper.TryDeleteCart(this.Context, transaction); return(new SaveCustomerOrderResponse(salesOrder)); }
/// <summary> /// Execute method to be overridden by each derived class. /// </summary> /// <param name="request">The request.</param> /// <returns> /// The response. /// </returns> protected override UpdateDeliverySpecificationsResponse Process(UpdateDeliverySpecificationsRequest request) { ThrowIf.Null(request, "request"); ThrowIf.NullOrWhiteSpace(request.CartId, "request.CartId"); SalesTransaction transaction = CartWorkflowHelper.LoadSalesTransaction(this.Context, request.CartId); if (transaction == null) { string message = string.Format("Cart with identifer {0} was not found.", request.CartId); throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_ObjectNotFound, message); } if (request.UpdateOrderLevelDeliveryOptions) { transaction = this.UpdateOrderLevelDeliverySpecification(transaction, request.DeliverySpecification); } else { transaction = this.UpdateLineLevelDeliveryOptions(transaction, request.LineDeliverySpecifications); } // Validate and resolve addresses. ShippingHelper.ValidateAndResolveAddresses(this.Context, transaction); // Updating the shipping information should only affect charges, taxes, amount due and totals. CartWorkflowHelper.Calculate(this.Context, transaction, CalculationModes.Charges | CalculationModes.Taxes | CalculationModes.AmountDue | CalculationModes.Totals); CartWorkflowHelper.SaveSalesTransaction(this.Context, transaction); Cart updatedCart = CartWorkflowHelper.ConvertToCart(this.Context, transaction); CartWorkflowHelper.RemoveHistoricalTenderLines(updatedCart); return(new UpdateDeliverySpecificationsResponse(updatedCart)); }
/// <summary> /// Executes the workflow to fetch line level delivery options for given cart. /// </summary> /// <param name="request">Instance of <see cref="GetDeliveryOptionsRequest"/>.</param> /// <returns>Instance of <see cref="GetDeliveryOptionsResponse"/>.</returns> protected override GetDeliveryOptionsResponse Process(GetDeliveryOptionsRequest request) { ThrowIf.Null(request, "request"); ValidateRequest(request); // Get the Sales Transaction SalesTransaction salesTransaction = CartWorkflowHelper.LoadSalesTransaction(this.Context, request.CartId); if (salesTransaction == null) { throw new CartValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_CartNotFound, request.CartId); } GetDeliveryOptionsRequestHandler.ResetPreviousShippingAddressOnTransaction(salesTransaction); Collection <SalesLine> requestedSalesLines = null; // Used if line level delivery options were requested. if (!request.FetchDeliveryOptionsForLines) { salesTransaction.ShippingAddress = request.HeaderShippingAddress; } else { requestedSalesLines = new Collection <SalesLine>(); Dictionary <string, LineShippingAddress> shippingAddressByLineId = request.LineShippingAddresses.ToDictionary(lsa => lsa.LineId); foreach (var salesLine in salesTransaction.ActiveSalesLines) { LineShippingAddress lineShippingAddress; if (shippingAddressByLineId.TryGetValue(salesLine.LineId, out lineShippingAddress)) { salesLine.ShippingAddress = lineShippingAddress.ShippingAddress; requestedSalesLines.Add(salesLine); } } } // Validate and resolve addresses. ShippingHelper.ValidateAndResolveAddresses(this.Context, salesTransaction); // Get the delivery options. GetDeliveryOptionsResponse response; if (!request.FetchDeliveryOptionsForLines) { // Get the delivery options that are common to all the cart lines. var serviceRequest = new GetOrderDeliveryOptionsServiceRequest(salesTransaction); serviceRequest.QueryResultSettings = request.QueryResultSettings; var serviceResponse = this.Context.Execute <GetOrderDeliveryOptionsServiceResponse>(serviceRequest); response = new GetDeliveryOptionsResponse(serviceResponse.DeliveryOptions); } else { // Get the delivery options for each line. var serviceRequest = new GetLineDeliveryOptionsServiceRequest(requestedSalesLines); serviceRequest.QueryResultSettings = request.QueryResultSettings; var serviceResponse = this.Context.Execute <GetLineDeliveryOptionsServiceResponse>(serviceRequest); response = new GetDeliveryOptionsResponse(serviceResponse.LineDeliveryOptions); } return(response); }
protected override CreateOrderFromCartResponse Process(CreateOrderFromCartRequest request) { ThrowIf.Null(request, "request"); ThrowIf.Null(request.CartId, "request.CartId"); List <TenderLine> tenderLines = new List <TenderLine>(); // Get the Sales Transaction. SalesTransaction salesTransaction = null; ExecutionHandler( delegate { PopulateSalesTransaction(this.Context, request.CartId, request.ReceiptEmailAddress, out salesTransaction); }, SubmitOrderOperationType.GetSalesTransaction.ToString()); // Validate sales order for creation. ExecutionHandler( delegate { OrderWorkflowHelper.ValidateContextForCreateOrder(this.Context, salesTransaction); }, SubmitOrderOperationType.ValidateContextForCreateOrder.ToString()); // Validate addresses. ExecutionHandler( delegate { ShippingHelper.ValidateAndResolveAddresses(this.Context, salesTransaction); }, SubmitOrderOperationType.ValidateAndResolveAddresses.ToString()); // Add missing dependencies to the sales transaction. ExecutionHandler( delegate { OrderWorkflowHelper.FillMissingRequirementsForOrder(this.Context, salesTransaction); }, SubmitOrderOperationType.FillMissingRequirementsForOrder.ToString()); // Validate addresses for shipping. ExecutionHandler( delegate { ShippingHelper.ValidateShippingInformation(this.Context, salesTransaction); }, SubmitOrderOperationType.ValidateShippingAddresses.ToString()); // Validate required reason code lines has been filled. ExecutionHandler( () => ReasonCodesWorkflowHelper.ValidateRequiredReasonCodeLinesFilled(this.Context, salesTransaction), SubmitOrderOperationType.ValidateReasonCodes.ToString()); // Authorize payments. ExecutionHandler( delegate { tenderLines = OrderWorkflowHelper.ProcessPendingOrderPayments(this.Context, salesTransaction, request.CartTenderLines); }, SubmitOrderOperationType.AuthorizePayments.ToString()); SalesOrder salesOrder = null; try { // Create order and add all authorization payment blobs. ExecutionHandler( delegate { salesOrder = OrderWorkflowHelper.CreateSalesOrder(this.Context, salesTransaction); }, SubmitOrderOperationType.CreateSaleOrderInCrt.ToString()); } catch (Exception ex) { try { // Cancel the payment authorizations OrderWorkflowHelper.CancelPayments(this.Context, salesTransaction, tenderLines, request.CartTenderLines); } catch (PaymentException cancelPaymentsEx) { // Inside of CancelPayments() we always wrap Exception as PaymentException. RetailLogger.Log.CrtWorkflowCancelingPaymentFailure(ex, cancelPaymentsEx); } throw; } // We also need to delete the shopping cart. CartWorkflowHelper.TryDeleteCart( this.Context, new SalesTransaction { Id = request.CartId, TerminalId = salesTransaction.TerminalId, CustomerId = salesTransaction.CustomerId, }); return(new CreateOrderFromCartResponse(salesOrder)); }