LP#1508208: Only look at holds that age protection allows
authorMike Rylander <mrylander@gmail.com>
Tue, 10 Dec 2019 22:17:38 +0000 (17:17 -0500)
committerChris Sharp <csharp@georgialibraries.org>
Wed, 28 Oct 2020 20:29:44 +0000 (16:29 -0400)
When hold capture is attempted, we look at (currently) the first 100
holds ordered by Best Hold Sort Selection Order.  If a very long list
of holds are targetting an age-protected item then op capture may not
have a chance to see a viable hold for that copy.

This commit attempts to take into account the age protection currently
set for the copy by restricting the holds to just those where the
hold-copy-map proximity is less than or equal to the maximum proximity
allowed by the age protection.  This works now because we store the
hold proximity in the hold copy map, where we did not before.

Being based on the hold-copy-map proximity, which is calculated
proximity, means this is an approximation and the final hold capture
logic may still reject some holds for the copy.  Likewise, this does
not entirely eliminate the possibility that there may be a better hold
to capture the copy for if the in-range set of holds is very, very
long, but this should allow hold capture to proceed if even
imperfectly.

If no age protection is set for the copy, the current behavior
(looking at all holds) is maintained.

Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Jason Etheridge <jason@EquinoxInitiative.org>
Signed-off-by: Chris Sharp <csharp@georgialibraries.org>

Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm

index 5762f84..94ea9cd 100644 (file)
@@ -571,12 +571,16 @@ sub nearest_hold {
             JOIN action.hold_copy_map hm ON (hm.hold = h.id)
             JOIN actor.usr au ON (au.id = h.usr)
             JOIN permission.grp_tree pgt ON (au.profile = pgt.id)
+            JOIN asset.copy acp ON (hm.target_copy = acp.id)
+            LEFT JOIN config.rule_age_hold_protect cahp ON (acp.age_protect = cahp.id)
             LEFT JOIN actor.usr_standing_penalty ausp
                 ON ( au.id = ausp.usr AND ( ausp.stop_date IS NULL OR ausp.stop_date > NOW() ) )
             LEFT JOIN config.standing_penalty csp
                 ON ( csp.id = ausp.standing_penalty AND csp.block_list LIKE '%CAPTURE%' )
             $addl_join
           WHERE hm.target_copy = ?
+            /* not protected, or protection is expired or we're in range */
+            AND (cahp.id IS NULL OR (AGE(NOW(),acp.active_date) >= cahp.age OR cahp.prox >= hm.proximity))
             AND (AGE(NOW(),h.request_time) >= CAST(? AS INTERVAL) OR hm.proximity = 0 OR p.prox = 0)
             AND h.capture_time IS NULL
             AND h.cancel_time IS NULL