OBPIH-7113 dynamic sorting on receiving locations#5282
Conversation
grails-app/controllers/org/pih/warehouse/api/InternalLocationApiController.groovy
Show resolved
Hide resolved
| activityCodeParams.allActivityCodes = params.allActivityCodes ? params.list("allActivityCodes") as ActivityCode[]: [] | ||
| activityCodeParams.anyActivityCodes = params.anyActivityCodes ? params.list("anyActivityCodes") as ActivityCode[]: [] | ||
| activityCodeParams.ignoreActivityCodes = params.ignoreActivityCodes ? params.list("ignoreActivityCodes") as ActivityCode[] : [] | ||
| def list(InternalLocationSearchCommand command) { |
There was a problem hiding this comment.
I didn't originally implement this with a command but locationService.getInternalLocations was so annoying to work with when activityCodeParams was a Map because I needed optional params and the compiler was complaining that it couldn't distinguish between methods so I got fed up enough to refactor it.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #5282 +/- ##
============================================
+ Coverage 8.34% 8.42% +0.08%
- Complexity 995 1025 +30
============================================
Files 647 656 +9
Lines 43466 43829 +363
Branches 10539 10612 +73
============================================
+ Hits 3626 3694 +68
- Misses 39278 39562 +284
- Partials 562 573 +11 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
awalkowiak
left a comment
There was a problem hiding this comment.
Overall feels to me that the sort util is redundant here, and I'd just stick to command + criteria builder or command + sort
| /** | ||
| * A POJO for holding a sorting condition on an entity. | ||
| */ | ||
| class SortParam { |
There was a problem hiding this comment.
Why POJOs instead Command objects?
There was a problem hiding this comment.
it's used by command objects (See the new ReceivingBinSearchCommand). Idk if that makes it a command itself but probably it's just a semantics thing. If you prefer, I'm fine with naming these SortParamCommand and SortParamListCommand if that is clearer
| /** | ||
| * A POJO for holding a list of sorting conditions on an entity. | ||
| */ | ||
| class SortParamList { |
There was a problem hiding this comment.
Same quesition here with the command as above
| * | ||
| * @param sortString A string of the form "x,-y,z" | ||
| */ | ||
| static SortParamList bindSortParams(String sortString) { |
There was a problem hiding this comment.
Could this be achieved by auto-binding with a command? Do we need to add a util for it?
There was a problem hiding this comment.
It actually is auto-binding. SortParamListValueConverter is where the logic is. All it does is call this method so we could probably just move this method there if we don't want to expose the behaviour to the rest of the app
| /** | ||
| * Sorts a given list of entities using the provided sort parameters. | ||
| */ | ||
| static <T> List<T> sort(List<T> toSort, SortParamList sortParams) { |
There was a problem hiding this comment.
Is there a case that will utilize it? Feels like this is basically achieving exactly the same what command + criteria builder would do or command + .sort { }
There was a problem hiding this comment.
it's used in LocationService. In that code, we've already fetched from the db and so have a List that we need to sort. So yes we're essentially doing the equivalient of List.sort(), it's just for convenience so that we can simply provide a SortParamList to sort by (which is provided by the user via the ?sort=x,y,z query param.
The big thing is that it allows us to dynamically sort by a user-given list of params, instead of a fixed set of params defined in the command object that List.sort() would do.
We could also make a new util method that would take in a SortParamList and output criteria that we can use to query the db with.
| /** | ||
| * Used to filter the returned results when listing/searching internal receiving bin locations. | ||
| */ | ||
| class ReceivingBinSearchCommand extends InternalLocationSearchCommand { |
There was a problem hiding this comment.
I know the term "receiving bin" has been used a lot throughout the system and maybe in requirements, but I would love to get rid of the notion of a "receiving bin" once and for all. It's more appropriate to call these locations "receiving locations". It's usually not a bin in the typical sense of a "storage bin" or "bin location". It's a staging location on the floor of the warehouse near the dock door.
Co-authored-by: Walkowiak <[email protected]>

✨ Description of Change
Link to GitHub issue or Jira ticket: https://pihemr.atlassian.net/browse/OBPIH-7113
Description:
Video recording describing the PR: https://jam.dev/c/b2a026dc-56f9-4abc-9b9d-932cf401081f
Adds the ability to provide the "sort" query param when fetching internal locations. The param is a comma separated list of fields and you can put a '-' in front of a field to have it sort descending. For example: "?sort=x,-y" means sort ascending by x then descending by y.
I achieved this by adding a new SortParam class. We can bind the "sort" query param to a list of SortParam and then use SortUtil to easily sort a list of objects.
So for example, if we want to sort Locations by order then by name, both ascending:
And to use it in an API:
GET /api/locations?sort=order,nameNote that this should only be used when we can't sort in the query itself since doing it in the query is typically faster.
I was originally going to implement this as the ticket suggested and just have the default sort behaviour be to sort by location type but I was worried about the changes it would have on other places in the code so I ended up implementing the full solution.
📷 Screenshots & Recordings (optional)
https://jam.dev/c/bd9c2d59-1a28-4830-aede-4336923bf636