I am in the process of implementing a custom view for the order list within the Commerce section. It's pretty much a copy + paste of the original Vendr angular components but with a couple of sortable columns added in.
The two fields are Order Properties.
I am just wondering what the best way to account for this in the back end is. Most of the functionality is absolutely identical, I just need some way of sorting the result set server side. Do I need to effectively reimplement the whole controller action and sprinkle in my sorting functionality? Or are there Notifications that I can hook into?
Hmm, the only thing we have is a OrderSearchingNotification but this doesn't have an ability to customize the sort order unfortunately so yea, that would mean re-implementing the API controller too to support this.
I also don't think our OrderSearch specifications support sorting on custom properties either so you are likely going to need to implement the search logic too unfortunately 😔
Just a couple of related questions, is the right way to go to use IOrderService.SearchOrders in the API endpoint? Is that what the normal Order List api endpoint uses?
[HttpGet]
public PagedResult<CustomOrderViewItemDto> GetOrders(string searchTerm = "", long pageNumber = 1, long pageSize = 30, string orderBy = "", string orderDirection = "")
{
var searcher = new OrderSearchableFieldsMatchSpecification(searchTerm, StringComparisonType.Contains);
var sorter = new SortByArrivalDateDescendingSpecification();
var results = _orderService.SearchOrders(searcher, sorter, pageNumber, pageSize);
//... rest of code
And if so, using the ISortSpecification<OrderReadOnly> to handle the sorting, it gives me an Accept function. Just wondering what that is for? Is it safe to just leave it unimplemented like so?
internal class SortByArrivalDateDescendingSpecification : ISortSpecification<OrderReadOnly>
{
public void Accept(IVisitor visitor, IVisitContext context)
{
}
public IOrderedEnumerable<OrderReadOnly> InvokeSort(IEnumerable<OrderReadOnly> collection)
{
return collection.OrderByDescending(prop =>
DateTime.TryParse(prop.Properties[Constants.Orders.Properties.ArrivalDate], out var arrivalDate)
? arrivalDate
: default);
}
public IOrderedEnumerable<OrderReadOnly> InvokeSort(IOrderedEnumerable<OrderReadOnly> collection)
{
return collection.OrderByDescending(prop =>
DateTime.TryParse(prop.Properties[Constants.Orders.Properties.ArrivalDate], out var arrivalDate)
? arrivalDate
: default);
}
}
RE your sort by specification, these implement the visitor pattern and so you would need to implement that method. Generally speaking though, they are just implemented like
public void Accept(IVisitor visitor, IVisitContext context)
=> visitor.Visit(this, context);
The bigger issue you have is that specifications have 2 halves, and in memory implementation (which is what you have) but also a NPoco implementation which uses the visitor pattern to visit all the specifications and generate the relevant SQL. Unfortunately this isn't extendable as really we only officially want people to use the clauses we support.
This is why I mentioned previously that you may end up needing to bypass the SearchOrders method entirely in favour of your own direct SQL statement.
Sorting Orders in the back end
Hi Matt,
I am in the process of implementing a custom view for the order list within the Commerce section. It's pretty much a copy + paste of the original Vendr angular components but with a couple of sortable columns added in.
The two fields are Order Properties.
I am just wondering what the best way to account for this in the back end is. Most of the functionality is absolutely identical, I just need some way of sorting the result set server side. Do I need to effectively reimplement the whole controller action and sprinkle in my sorting functionality? Or are there Notifications that I can hook into?
Any help is greatly appreciated!
Hey Philip,
Hmm, the only thing we have is a
OrderSearchingNotification
but this doesn't have an ability to customize the sort order unfortunately so yea, that would mean re-implementing the API controller too to support this.I also don't think our
OrderSearch
specifications support sorting on custom properties either so you are likely going to need to implement the search logic too unfortunately 😔Matt
Hi Matt,
Thanks for the (very) swift response!
No problem, I thought that may be the case.
Just a couple of related questions, is the right way to go to use
IOrderService.SearchOrders
in the API endpoint? Is that what the normal Order List api endpoint uses?And if so, using the
ISortSpecification<OrderReadOnly>
to handle the sorting, it gives me an Accept function. Just wondering what that is for? Is it safe to just leave it unimplemented like so?Hey Philip,
You can see an example of how to use the
SearchOrders
API here https://our.umbraco.com/packages/website-utilities/vendr/vendr-support/108589-searchorders-no-longer-working-after-upgrade#comment-337232RE your sort by specification, these implement the visitor pattern and so you would need to implement that method. Generally speaking though, they are just implemented like
The bigger issue you have is that specifications have 2 halves, and in memory implementation (which is what you have) but also a NPoco implementation which uses the visitor pattern to visit all the specifications and generate the relevant SQL. Unfortunately this isn't extendable as really we only officially want people to use the clauses we support.
This is why I mentioned previously that you may end up needing to bypass the
SearchOrders
method entirely in favour of your own direct SQL statement.is working on a reply...