Search for orders using abstractions
4 min
/// <summary>
/// Finds orders with a specific <see cref="OrderSearchFilter"/> for a specific <typeparamref name="TOrderGroup"/>.
/// </summary>
/// <typeparam name="TOrderGroup">The given order type for filter.</typeparam>
/// <param name="filter">The search filter.</param>
/// <returns>The order search results.</returns>
OrderSearchResults Find(OrderSearchFilter filter) where TOrderGroup : class, IOrderGroup;The Find method returns OrderSearchResults for the orders matching the supplied OrderSearchFilter and TOrderGroup type parameter.
Filter orders in search
OrderSearchFilter defines criteria for filtering orders in the search results:
- CreatedFrom – The earliest creation time for returned orders (inclusive).
- CreatedTo – The latest creation time for returned orders (inclusive).
- MarketId – Restricts results to orders created in the specified markets.
- ModifiedFrom – The earliest modification time for returned orders (inclusive).
- ModifiedTo – The latest modification time for returned orders (inclusive).
- StartingIndex – The starting index for paging through results.
- RecordsToRetrieve – The number of records to retrieve per page.
📘 Note The search is inclusive; begin and end values are included for datetime filters (CreatedFrom, CreatedTo, ModifiedFrom, ModifiedTo).
Search results for orders
OrderSearchResults contains the matching orders in Orders (an IEnumerable<T>) and the total match count in TotalRecords.
As with other abstraction APIs, you can replace the default implementation with a custom one.
using EPiServer.Framework;
using EPiServer.ServiceLocation;
using Mediachase.Commerce.Orders;
using Mediachase.Commerce.Orders.Search;
using Mediachase.MetaDataPlus.Extensions;
using System;
using System.Linq;
namespace EPiServer.Commerce.Order.Internal {
/// <summary>
/// This class is intended to be used internally by EPiServer.
/// We do not support any backward compatibility on this.
///
/// Default implementation of .
/// </summary>
[ServiceConfiguration(ServiceType = typeof (IOrderSearchService), Lifecycle = ServiceInstanceScope.Singleton)]
public class DefaultOrderSearchService: IOrderSearchService {
private readonly ICartSearchService _cartSearch;
public DefaultOrderSearchService(ICartSearchService cartSearch) {
Validator.ThrowIfNull(nameof(cartSearch), cartSearch);
_cartSearch = cartSearch;
}
public virtual OrderSearchResults Find(OrderSearchFilter filter) where TOrderGroup: class, IOrderGroup {
Validator.ThrowIfNull(nameof(filter), filter);
var type = typeof (TOrderGroup);
if (IsCart(type)) {
var carts = _cartSearch.FindCarts(filter.CreatedFrom, filter.CreatedTo,
filter.MarketId, filter.StartingIndex ?? 0,
filter.RecordsToRetrieve ?? int.MaxValue,
out int totalRecords).OfType();
return new OrderSearchResults(carts, totalRecords);
}
string sqlMetaWhereClause = $ @ "(META.Created BETWEEN '{(filter.CreatedFrom ?? DateTime.MinValue.TruncateToSqlDateTimeRange()).ToString("
s ")}'
AND '{(filter.CreatedTo ?? DateTime.MaxValue.TruncateToSqlDateTimeRange()).ToString("s")}')
";
sqlMetaWhereClause += $ @ " AND (META.Modified BETWEEN '{(filter.ModifiedFrom ?? DateTime.MinValue.TruncateToSqlDateTimeRange()).ToString("
s ")}'
AND '{(filter.ModifiedTo ?? DateTime.MaxValue.TruncateToSqlDateTimeRange()).ToString("s")}')
";
var parameters = new OrderSearchParameters() {
SqlMetaWhereClause = sqlMetaWhereClause
};
if (!string.IsNullOrEmpty(filter.MarketId)) {
parameters.SqlWhereClause = $ "MarketId = '{filter.MarketId}'";
}
var options = new OrderSearchOptions {
StartingRecord = filter.StartingIndex ?? 0,
RecordsToRetrieve = filter.RecordsToRetrieve ?? int.MaxValue
};
if (IsPurchaseOrder(type)) {
options.Classes.Add(OrderContext.Current.PurchaseOrderMetaClass.Name);
var orders = OrderContext.Current.FindPurchaseOrders(parameters, options, out int totalRecords).OfType();
return new OrderSearchResults(orders, totalRecords);
}
if (IsPaymentPlan(type)) {
options.Classes.Add(OrderContext.Current.PaymentPlanMetaClass.Name);
var paymentplans = OrderContext.Current.FindPaymentPlans(parameters, options, out int totalRecords).OfType();
return new OrderSearchResults(paymentplans, totalRecords);
}
throw new InvalidOperationException($"The type {typeof(TOrderGroup)} is not supported.");
}
private static bool IsCart(Type type) {
return typeof (ICart).IsAssignableFrom(type);
}
private static bool IsPurchaseOrder(Type type) {
return typeof (IPurchaseOrder).IsAssignableFrom(type);
}
private static bool IsPaymentPlan(Type type) {
return typeof (IPaymentPlan).IsAssignableFrom(type);
}
}
}Extension methods
IOrderSearchServiceExtensions provides convenient extension methods for IOrderSearchService:
- FindCarts
- FindPurchaseOrders
- FindPaymentPlans
var orderFilter = new OrderSearchFilter {
CreatedFrom = DateTime.UtcNow.AddDays(-365),
CreatedTo = DateTime.UtcNow
};
var orderSearchService = ServiceLocator.Current.GetInstance<IOrderSearchService>();
var searchResult = orderSearchService.FindPurchaseOrders(orderFilter);
var orders = searchResult.Orders;
var totalRecords = searchResult.TotalRecords;