Accelerator RMA

Hi I’m working with the RMA part of the Accelerator and I’m having a bit of trouble to get it to work properly. I’m trying to follow the steps described in the docs (API testing)

  1. This part doesn’t fire even though I’ve ensured that the RMA state is Completed the OrderState.ReturnConfirmed transitions in the OrderStateBulder doesn’t get hit.
    stateManager.RmaStateMachine.AddRelatedState((short)RmaState.Completed, FiniteStateMachineType.Order, (short)OrderState.ReturnConfirmed);
    Because of this my SalesReturnOrder never leaves OrderStatus Init.

  2. In the DeliveryStateBuilder of the Accelerator DeliveryState.Returned should fire _orderUtilities.ReturnOrCancelAllPayments which does the refunding (Klarna in our case).
    The trouble seems to be that when the SalesReturnOrder gets created in the state transition RmaState.Processing → RmaState.Completed. In the implementation of Litium.Foundation.Modules.ECommerce.Plugins.ReturnManagement.SalesReturnOrderDeliveryBuilder the deliveryCarrier.DeliveryStatus gets set to Returned. I think this causes bypassing of the accelerator DeliveryStateBuilder, right?

Does it make sense? :slight_smile:

Litium version: 7.6.1

Not sure about the issues in the Accelerator, seems some changes has been made internally and are not reflected in the package.

But a very simplified implementation of the full return flow could look something like this:

using Litium.Accelerator.StateTransitions;
using Litium.Accelerator.Utilities;
using Litium.Foundation.Modules.ECommerce;
using Litium.Foundation.Modules.ECommerce.Plugins.ReturnManagement;
using Litium.Foundation.Security;
using Litium.Runtime.DependencyInjection;
using Litium.Sales;
using Litium.Security;
using System;
using System.Linq;

namespace Litium.Accelerator.Services
{
	[Service(ServiceType = typeof(ReturnOrderService))]
	public class ReturnOrderService
	{
		private readonly RmaFactory _rmaFactory;
		private readonly RmaService _rmaService;
		private readonly RmaStateService _rmaStateService;
		private readonly OrderSummaryService _orderSummaryService;
		private readonly OrderUtilities _orderUtilities;
		private readonly SecurityContextService _securityContextService;

		public ReturnOrderService(RmaFactory rmaFactory,
			RmaService rmaService,
			RmaStateService rmaStateService,
			OrderSummaryService orderSummaryService,
			OrderUtilities orderUtilities,
			SecurityContextService securityContextService)
		{
			_rmaFactory = rmaFactory;
			_rmaService = rmaService;
			_rmaStateService = rmaStateService;
			_orderSummaryService = orderSummaryService;
			_orderUtilities = orderUtilities;
			_securityContextService = securityContextService;
		}

		public bool ReturnOrder(string id)
		{
			try
			{
				var order = ModuleECommerce.Instance.Orders.GetOrder(id, SecurityToken.CurrentSecurityToken);

				// 1. Create RMA
				var rma = _rmaFactory.Create(new Sales.RmaCreateArgs { SalesOrderSystemId = order.ID });

				// Approve it right away
				rma.ApprovalCode = ApprovalCode.Approved;
				rma.ReceivedBy = SecurityToken.CurrentSecurityToken.UserID;
				rma.ApprovedBy = SecurityToken.CurrentSecurityToken.UserID;

				using (_securityContextService.ActAsSystem())
				{
					_rmaService.Create(rma);
				}

				// 2. Transition RMA through its states
				_rmaStateService.SetState(rma.SystemId, RmaState.PackageReceived);
				_rmaStateService.SetState(rma.SystemId, RmaState.Processing);
				_rmaStateService.SetState(rma.SystemId, RmaState.Completed); // this transition will create the sales return order

				var orderSummary = _orderSummaryService.GetByRmaSystemId(rma.SystemId);
				var salesReturnOrder = orderSummary.RelatedOrderCarriers.FirstOrDefault(x => x.RmaSystemId == rma.SystemId && x.Type == OrderType.SalesReturnOrder);

				// 3. Confirm return order
				var returnOrder = ModuleECommerce.Instance.Orders.GetOrder(salesReturnOrder.ID, SecurityToken.CurrentSecurityToken);
				returnOrder.SetOrderStatus((short)OrderState.ReturnConfirmed, SecurityToken.CurrentSecurityToken);

				// 4. Refund money
				_orderUtilities.ReturnOrCancelAllPayments(returnOrder, SecurityToken.CurrentSecurityToken);
			}
			catch (Exception ex)
			{
				// log error
				return false;
			}

			return true;
		}
	}
}

You can create the RMA from a ReturnSlip instead to have partial returns.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.