Overview
The primary driver in determining item resolution is speed of delivery.
Factors used to determine item resolution are:
Circulation status
Loans
Holds
Geographic proximity
Rules
On-shelf ranks above loans, ranks above holds
When all items are loaned, the item due soonest is selected
When all items have holds, the item with the least number of holds is selected
When all item resolution determinants are equal (e.g. all items on-shelf) and geographic proximity is enabled and preferred suppliers are not enabled, use geographic proximity to determine the item for resolution
When preferred suppliers are also enabled, use a preferred supplier from the same group.
If more than one supplier in the same group, use geographic proximity OR load balancing to make the selection
If a preferred supplier is not found, and more than one supplier is outside the preferred group, use geographic proximity or load balancing to make the selection.
Filter and Sort / Pool and Rank
Selectable Pool
Applies to all resolution strategies (including manual selection)
These suppression and selection factors determine (and limit) the pool of potentially resolvable items
CONTRIBUTED / DISCOVERABLE (BIB)
Bib suppression / discovery flag
Per library bib suppression rules
DISPLAYABLE (ITEM)
Display Suppression
Deleted items
Per library suppression rules
Shelving location
CIRCULATABLE (ITEM)
Item is from cancelling supplier
Item Ranking
Applies to all resolution strategies, except manual selection
Items are sorted and resolved in order
Item is from borrowing library’s preferred supplier group
Item is available (on shelf)
Item is currently loaned
due soonest
Item has holds
fewest holds
Geographic proximity
Technical Notes
Resolution strategy
How re-resolution should work with preferred supplier and load balancing features
Previously included in the context of DCB-1411 (Ian Ibbotson)
Currently org.olf.dcb.request.resolution.PatronRequestResolutionService has a method resolvePatronRequest which is called once in the flow. This story will cause re-execution of this method.
Currently the method performs the following steps
return Mono.just(Resolution.forPatronRequest(patronRequest)) .zipWhen(this::getAvailableItems, Resolution::trackAllItems) .map(this::filterItems) .flatMap(this::decideResolutionStrategy) .flatMap(function(this::applyResolutionStrategy)) .doOnError(error -> log.warn( "There was an error in the liveAvailabilityService.getAvailableItems stream : {}", error.getMessage())) .switchIfEmpty(Mono.defer(() -> Mono.just(noItemsSelectable(patronRequest))));
There are three item resolution strategies currently defined:
FirstRequestableItemResolutionStrategy.java
GeoDistanceResolutionStrategy.java
ManualSelectionStrategy.java
The default for normal book lending is Geo Distance. Any implementation can change the default strategy with an environment variable. New strategies can be added at any point. It is important to maintain the item resolver interface ResolutionStrategy.
public interface ResolutionStrategy { String MANUAL_SELECTION = "ManualSelection"; // Resolution Strategies must return a code which can be used to select // an implementation based on config String getCode(); Mono<Item> chooseItem(List<Item> items, UUID clusterRecordId, PatronRequest patronRequest); }
As long as we maintain this clean separation, different choices with requesting groups and load balancing are constrained to the applyResolutionStrategy section - so this code does not interact in any way with requesting or re-reqesting. All that happens is that the resolutionStrategy has to return a specific item to try and get hold of. It is essential that any resolution strategy tries to reduce the list of possible items down to a specific one to “Try next”.
It is expected that a new GeneralResolutionStrategy will be created which allows systems to specify the sort and filter criteria of the items in the input List. For example - Filter [“available items”, “Not already tried”], sort by [“MyLendingGroup”, “GeoDistance”] or “Sort by [“My Lending Group”, “SupplierLoad”].
GeneralResolutionStrategy will then choose the item that sorted highest as the next item to try and request.
In this way resolution strategies are entirely isolated from the re-request process.
Sort order
Previously posted in #dcb-requirements
Ian Ibbotson
"As a developer" I think it over complicates the work to separate out on shelf from holds. We should blend the two. Due date is not a good guide to availability-date once queue depth is > 0 because it's the return date of the current loan so it gives no indication of when future loans may be returned. All of these concepts should be blended into "AvailabilityDate" which defaults to now() if the item is on shelf, due date if the item is on loan but hold count is 0, or due date + ( default loan period * hold queue depth) for queue depths > 0.
The "Default" system wide sort order will be [ "availability-date" ]. The system works by sorting by availability date desc and them choosing the first item available from a supplier not already tried.
Libraries need to be able to configure the sort criteria for their patrons. On a per library basis in the admin app the sort order can be changed for an institution. Sort order is a list of criteria which includes availability-date and the following fields:
geo-distance from pickup library to lending library
supplier-group priority (1,2,3,4,5..) Each library will configure it's preferences
Libraries will be allowed to choose the order - so [ 'availability-date', supplier-group-priority, 'geo-distance' ] - would give items on shelf priority and within that supplier group and then geo distance.e.g.
DueDate - Supplier Group - Geo-distance
01-Jan-2025 - 0 - 1.356
01-Jan-2025 - 0 - 6.4
01-Jan-2025 - 1 - 34.6
01-Jan-2025 - 2 - 10.4
01-Feb-2025 - 0 - 2.5
Tim Auger
Are you saying that availability-date is something that libraries could choose sort independently or just Supplier Group and Geo-distance? It seems that you are saying that all would be configurable by supplier library.
Ian Ibbotson
Well - we might not want to allow the first sort criteria to be selectable - but thats a UI thing - backend its all part of the same mechanism yes