[open-ils-commits] [GIT] Evergreen ILS branch master updated. 967a96332af446b7224e4c236b6a3a87f601b2a1
Evergreen Git
git at git.evergreen-ils.org
Tue Jul 24 11:51:36 EDT 2012
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".
The branch, master has been updated
via 967a96332af446b7224e4c236b6a3a87f601b2a1 (commit)
via ef0842aba78178d9df85c1edbfb295c54109630a (commit)
via bd98f2adea3937bd848cf0386e8220095e3d8118 (commit)
via fecdfe5dcb1a87cd2b12733b4b06c56e5c5ab4b5 (commit)
via 08075458b3fad3d9112d8dc2f2f6655056f8513d (commit)
via 169731b8569a378bae748c98514e42bd89954d17 (commit)
via 1b36e7a6af73c06417a4cbf19bf0585125b32a36 (commit)
via 266fc54ebaab9806af3ee86ba39b778bc192ebf8 (commit)
via a8155fc4c4728adbfd3e734a9ede7eca1f067c78 (commit)
via ae0e26ed0862b3694415806ce2dc05e128868c24 (commit)
from ea3a318233a63168882f93945add1cdd8a18ff61 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 967a96332af446b7224e4c236b6a3a87f601b2a1
Author: Mike Rylander <mrylander at gmail.com>
Date: Tue Jul 24 11:51:29 2012 -0400
Stamping upgrade script for Capture/Fulfill penalty blocks
Signed-off-by: Mike Rylander <mrylander at gmail.com>
diff --git a/Open-ILS/src/sql/Pg/002.schema.config.sql b/Open-ILS/src/sql/Pg/002.schema.config.sql
index a527fd3..bfcc219 100644
--- a/Open-ILS/src/sql/Pg/002.schema.config.sql
+++ b/Open-ILS/src/sql/Pg/002.schema.config.sql
@@ -87,7 +87,7 @@ CREATE TRIGGER no_overlapping_deps
BEFORE INSERT OR UPDATE ON config.db_patch_dependencies
FOR EACH ROW EXECUTE PROCEDURE evergreen.array_overlap_check ('deprecates');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0720', :eg_version); -- berick/miker
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0721', :eg_version); -- berick/miker
CREATE TABLE config.bib_source (
id SERIAL PRIMARY KEY,
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql b/Open-ILS/src/sql/Pg/upgrade/0721.data.hold_cap_fill_penalty_blocks.sql
similarity index 99%
rename from Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql
rename to Open-ILS/src/sql/Pg/upgrade/0721.data.hold_cap_fill_penalty_blocks.sql
index 2b991a9..9046c47 100644
--- a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/0721.data.hold_cap_fill_penalty_blocks.sql
@@ -1,6 +1,8 @@
BEGIN;
+SELECT evergreen.upgrade_deps_block_check('0721', :eg_version);
+
UPDATE config.standing_penalty
SET block_list = REPLACE(block_list, 'HOLD', 'HOLD|CAPTURE')
WHERE
commit ef0842aba78178d9df85c1edbfb295c54109630a
Author: Bill Erickson <berick at esilibrary.com>
Date: Tue Jul 17 09:19:46 2012 -0400
Apply HOLD block on new holds, CAPTURE block on existing
With the addition of the CAPTURE block, the HOLD block should only apply
for newly placed holds in the hold permit test
(action.hold_request_permit_test).
Signed-off-by: Bill Erickson <berick at esilibrary.com>
Signed-off-by: Jason Stephenson <jstephenson at mvlc.org>
Signed-off-by: Mike Rylander <mrylander at gmail.com>
diff --git a/Open-ILS/src/sql/Pg/110.hold_matrix.sql b/Open-ILS/src/sql/Pg/110.hold_matrix.sql
index 5131afb..be2ff65 100644
--- a/Open-ILS/src/sql/Pg/110.hold_matrix.sql
+++ b/Open-ILS/src/sql/Pg/110.hold_matrix.sql
@@ -236,12 +236,20 @@ DECLARE
frozen_hold_count INT;
context_org_list INT[];
done BOOL := FALSE;
+ hold_penalty TEXT;
BEGIN
SELECT INTO user_object * FROM actor.usr WHERE id = match_user;
SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( pickup_ou );
result.success := TRUE;
+ -- The HOLD penalty block only applies to new holds.
+ -- The CAPTURE penalty block applies to existing holds.
+ hold_penalty := 'HOLD';
+ IF retargetting THEN
+ hold_penalty := 'CAPTURE';
+ END IF;
+
-- Fail if we couldn't find a user
IF user_object.id IS NULL THEN
result.fail_part := 'no_user';
@@ -353,7 +361,7 @@ BEGIN
WHERE usr = match_user
AND usp.org_unit IN ( SELECT * FROM unnest(context_org_list) )
AND (usp.stop_date IS NULL or usp.stop_date > NOW())
- AND csp.block_list LIKE '%HOLD%' LOOP
+ AND csp.block_list LIKE '%' || hold_penalty || '%' LOOP
result.fail_part := standing_penalty.name;
result.success := FALSE;
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql
index 560cf29..2b991a9 100644
--- a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql
@@ -1,4 +1,5 @@
+BEGIN;
UPDATE config.standing_penalty
SET block_list = REPLACE(block_list, 'HOLD', 'HOLD|CAPTURE')
@@ -18,3 +19,231 @@ UPDATE config.standing_penalty
AND block_list NOT LIKE '%FULFILL%';
+-- apply the HOLD vs CAPTURE block logic
+CREATE OR REPLACE FUNCTION action.hold_request_permit_test( pickup_ou INT, request_ou INT, match_item BIGINT, match_user INT, match_requestor INT, retargetting BOOL ) RETURNS SETOF action.matrix_test_result AS $func$
+DECLARE
+ matchpoint_id INT;
+ user_object actor.usr%ROWTYPE;
+ age_protect_object config.rule_age_hold_protect%ROWTYPE;
+ standing_penalty config.standing_penalty%ROWTYPE;
+ transit_range_ou_type actor.org_unit_type%ROWTYPE;
+ transit_source actor.org_unit%ROWTYPE;
+ item_object asset.copy%ROWTYPE;
+ item_cn_object asset.call_number%ROWTYPE;
+ item_status_object config.copy_status%ROWTYPE;
+ item_location_object asset.copy_location%ROWTYPE;
+ ou_skip actor.org_unit_setting%ROWTYPE;
+ result action.matrix_test_result;
+ hold_test config.hold_matrix_matchpoint%ROWTYPE;
+ use_active_date TEXT;
+ age_protect_date TIMESTAMP WITH TIME ZONE;
+ hold_count INT;
+ hold_transit_prox INT;
+ frozen_hold_count INT;
+ context_org_list INT[];
+ done BOOL := FALSE;
+ hold_penalty TEXT;
+BEGIN
+ SELECT INTO user_object * FROM actor.usr WHERE id = match_user;
+ SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( pickup_ou );
+
+ result.success := TRUE;
+
+ -- The HOLD penalty block only applies to new holds.
+ -- The CAPTURE penalty block applies to existing holds.
+ hold_penalty := 'HOLD';
+ IF retargetting THEN
+ hold_penalty := 'CAPTURE';
+ END IF;
+
+ -- Fail if we couldn't find a user
+ IF user_object.id IS NULL THEN
+ result.fail_part := 'no_user';
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ RETURN;
+ END IF;
+
+ SELECT INTO item_object * FROM asset.copy WHERE id = match_item;
+
+ -- Fail if we couldn't find a copy
+ IF item_object.id IS NULL THEN
+ result.fail_part := 'no_item';
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ RETURN;
+ END IF;
+
+ SELECT INTO matchpoint_id action.find_hold_matrix_matchpoint(pickup_ou, request_ou, match_item, match_user, match_requestor);
+ result.matchpoint := matchpoint_id;
+
+ SELECT INTO ou_skip * FROM actor.org_unit_setting WHERE name = 'circ.holds.target_skip_me' AND org_unit = item_object.circ_lib;
+
+ -- Fail if the circ_lib for the item has circ.holds.target_skip_me set to true
+ IF ou_skip.id IS NOT NULL AND ou_skip.value = 'true' THEN
+ result.fail_part := 'circ.holds.target_skip_me';
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ RETURN;
+ END IF;
+
+ -- Fail if user is barred
+ IF user_object.barred IS TRUE THEN
+ result.fail_part := 'actor.usr.barred';
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ RETURN;
+ END IF;
+
+ SELECT INTO item_cn_object * FROM asset.call_number WHERE id = item_object.call_number;
+ SELECT INTO item_status_object * FROM config.copy_status WHERE id = item_object.status;
+ SELECT INTO item_location_object * FROM asset.copy_location WHERE id = item_object.location;
+
+ -- Fail if we couldn't find any matchpoint (requires a default)
+ IF matchpoint_id IS NULL THEN
+ result.fail_part := 'no_matchpoint';
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ RETURN;
+ END IF;
+
+ SELECT INTO hold_test * FROM config.hold_matrix_matchpoint WHERE id = matchpoint_id;
+
+ IF hold_test.holdable IS FALSE THEN
+ result.fail_part := 'config.hold_matrix_test.holdable';
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ END IF;
+
+ IF item_object.holdable IS FALSE THEN
+ result.fail_part := 'item.holdable';
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ END IF;
+
+ IF item_status_object.holdable IS FALSE THEN
+ result.fail_part := 'status.holdable';
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ END IF;
+
+ IF item_location_object.holdable IS FALSE THEN
+ result.fail_part := 'location.holdable';
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ END IF;
+
+ IF hold_test.transit_range IS NOT NULL THEN
+ SELECT INTO transit_range_ou_type * FROM actor.org_unit_type WHERE id = hold_test.transit_range;
+ IF hold_test.distance_is_from_owner THEN
+ SELECT INTO transit_source ou.* FROM actor.org_unit ou JOIN asset.call_number cn ON (cn.owning_lib = ou.id) WHERE cn.id = item_object.call_number;
+ ELSE
+ SELECT INTO transit_source * FROM actor.org_unit WHERE id = item_object.circ_lib;
+ END IF;
+
+ PERFORM * FROM actor.org_unit_descendants( transit_source.id, transit_range_ou_type.depth ) WHERE id = pickup_ou;
+
+ IF NOT FOUND THEN
+ result.fail_part := 'transit_range';
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ END IF;
+ END IF;
+
+ FOR standing_penalty IN
+ SELECT DISTINCT csp.*
+ FROM actor.usr_standing_penalty usp
+ JOIN config.standing_penalty csp ON (csp.id = usp.standing_penalty)
+ WHERE usr = match_user
+ AND usp.org_unit IN ( SELECT * FROM unnest(context_org_list) )
+ AND (usp.stop_date IS NULL or usp.stop_date > NOW())
+ AND csp.block_list LIKE '%' || hold_penalty || '%' LOOP
+
+ result.fail_part := standing_penalty.name;
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ END LOOP;
+
+ IF hold_test.stop_blocked_user IS TRUE THEN
+ FOR standing_penalty IN
+ SELECT DISTINCT csp.*
+ FROM actor.usr_standing_penalty usp
+ JOIN config.standing_penalty csp ON (csp.id = usp.standing_penalty)
+ WHERE usr = match_user
+ AND usp.org_unit IN ( SELECT * FROM unnest(context_org_list) )
+ AND (usp.stop_date IS NULL or usp.stop_date > NOW())
+ AND csp.block_list LIKE '%CIRC%' LOOP
+
+ result.fail_part := standing_penalty.name;
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ END LOOP;
+ END IF;
+
+ IF hold_test.max_holds IS NOT NULL AND NOT retargetting THEN
+ SELECT INTO hold_count COUNT(*)
+ FROM action.hold_request
+ WHERE usr = match_user
+ AND fulfillment_time IS NULL
+ AND cancel_time IS NULL
+ AND CASE WHEN hold_test.include_frozen_holds THEN TRUE ELSE frozen IS FALSE END;
+
+ IF hold_count >= hold_test.max_holds THEN
+ result.fail_part := 'config.hold_matrix_test.max_holds';
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ END IF;
+ END IF;
+
+ IF item_object.age_protect IS NOT NULL THEN
+ SELECT INTO age_protect_object * FROM config.rule_age_hold_protect WHERE id = item_object.age_protect;
+ IF hold_test.distance_is_from_owner THEN
+ SELECT INTO use_active_date value FROM actor.org_unit_ancestor_setting('circ.holds.age_protect.active_date', item_cn_object.owning_lib);
+ ELSE
+ SELECT INTO use_active_date value FROM actor.org_unit_ancestor_setting('circ.holds.age_protect.active_date', item_object.circ_lib);
+ END IF;
+ IF use_active_date = 'true' THEN
+ age_protect_date := COALESCE(item_object.active_date, NOW());
+ ELSE
+ age_protect_date := item_object.create_date;
+ END IF;
+ IF age_protect_date + age_protect_object.age > NOW() THEN
+ IF hold_test.distance_is_from_owner THEN
+ SELECT INTO item_cn_object * FROM asset.call_number WHERE id = item_object.call_number;
+ SELECT INTO hold_transit_prox prox FROM actor.org_unit_proximity WHERE from_org = item_cn_object.owning_lib AND to_org = pickup_ou;
+ ELSE
+ SELECT INTO hold_transit_prox prox FROM actor.org_unit_proximity WHERE from_org = item_object.circ_lib AND to_org = pickup_ou;
+ END IF;
+
+ IF hold_transit_prox > age_protect_object.prox THEN
+ result.fail_part := 'config.rule_age_hold_protect.prox';
+ result.success := FALSE;
+ done := TRUE;
+ RETURN NEXT result;
+ END IF;
+ END IF;
+ END IF;
+
+ IF NOT done THEN
+ RETURN NEXT result;
+ END IF;
+
+ RETURN;
+END;
+$func$ LANGUAGE plpgsql;
+
+
+COMMIT;
commit bd98f2adea3937bd848cf0386e8220095e3d8118
Author: Bill Erickson <berick at esilibrary.com>
Date: Thu Jun 21 14:37:11 2012 -0400
Avoid CAPTURE-blocked holds in pull list (IDL view)
Update the new IDL holds pull list view to avoid returning holds for
users that have CAPTURE penalties.
Note that items are blocked from the pull list only if the hold pickup
lib is within the CAPTURE penalty org unit range. This means that users
could be blocked at one branch, but use a pickup lib at another to avoid
the block. To prevent this type of abuse, set the org_depth to 0 on any
penalties that apply the CAPTURE block.
Signed-off-by: Bill Erickson <berick at esilibrary.com>
Signed-off-by: Jason Stephenson <jstephenson at mvlc.org>
Signed-off-by: Mike Rylander <mrylander at gmail.com>
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index a3cda7c..dba33cf 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -5048,6 +5048,18 @@ SELECT usr,
JOIN asset.call_number_prefix acnp ON (acn.prefix = acnp.id)
JOIN asset.call_number_suffix acns ON (acn.suffix = acns.id)
JOIN actor.usr au ON (au.id = ahr.usr)
+ LEFT JOIN actor.usr_standing_penalty ausp
+ ON (ahr.usr = 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%' AND (
+ (csp.org_depth IS NULL AND ahr.pickup_lib = ausp.org_unit) OR
+ (csp.org_depth IS NOT NULL AND ahr.pickup_lib IN (
+ SELECT id FROM actor.org_unit_descendants(ausp.org_unit, csp.org_depth))
+ )
+ )
+ )
LEFT JOIN serial.issuance siss
ON (ahr.hold_type = 'I' AND siss.id = ahr.target)
LEFT JOIN asset.copy_location_order acplo
@@ -5056,6 +5068,7 @@ SELECT usr,
WHERE
ahr.capture_time IS NULL AND
ahr.cancel_time IS NULL AND
+ csp.id IS NULL AND
(ahr.expire_time is NULL OR ahr.expire_time > NOW())
]]></oils_persist:source_definition>
<fields oils_persist:primary="id">
commit fecdfe5dcb1a87cd2b12733b4b06c56e5c5ab4b5
Author: Bill Erickson <berick at esilibrary.com>
Date: Thu Jun 21 14:26:25 2012 -0400
hold CAP/FILL blocks : pair FULFILL with CIRC in stock penalties
FULFILL is really a block on circulation, not holds, so pair the FULFILL
block with CIRC blocks for the stock data.
Signed-off-by: Bill Erickson <berick at esilibrary.com>
Signed-off-by: Jason Stephenson <jstephenson at mvlc.org>
Signed-off-by: Mike Rylander <mrylander at gmail.com>
diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
index 0c0744c..f76ae20 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -20,13 +20,13 @@ INSERT INTO config.standing (id, value) VALUES (2, oils_i18n_gettext(2, 'Barred'
SELECT SETVAL('config.standing_id_seq'::TEXT, 100);
INSERT INTO config.standing_penalty (id,name,label,block_list,staff_alert)
- VALUES (1,'PATRON_EXCEEDS_FINES',oils_i18n_gettext(1, 'Patron exceeds fine threshold', 'csp', 'label'),'CIRC|HOLD|CAPTURE|FULFILL|RENEW', TRUE);
+ VALUES (1,'PATRON_EXCEEDS_FINES',oils_i18n_gettext(1, 'Patron exceeds fine threshold', 'csp', 'label'),'CIRC|FULFILL|HOLD|CAPTURE|RENEW', TRUE);
INSERT INTO config.standing_penalty (id,name,label,block_list,staff_alert)
- VALUES (2,'PATRON_EXCEEDS_OVERDUE_COUNT',oils_i18n_gettext(2, 'Patron exceeds max overdue item threshold', 'csp', 'label'),'CIRC|HOLD|CAPTURE|FULFILL|RENEW', TRUE);
+ VALUES (2,'PATRON_EXCEEDS_OVERDUE_COUNT',oils_i18n_gettext(2, 'Patron exceeds max overdue item threshold', 'csp', 'label'),'CIRC|FULFILL|HOLD|CAPTURE|RENEW', TRUE);
INSERT INTO config.standing_penalty (id,name,label,block_list,staff_alert)
- VALUES (3,'PATRON_EXCEEDS_CHECKOUT_COUNT',oils_i18n_gettext(3, 'Patron exceeds max checked out item threshold', 'csp', 'label'),'CIRC', TRUE);
+ VALUES (3,'PATRON_EXCEEDS_CHECKOUT_COUNT',oils_i18n_gettext(3, 'Patron exceeds max checked out item threshold', 'csp', 'label'),'CIRC|FULFILL', TRUE);
INSERT INTO config.standing_penalty (id,name,label,block_list,staff_alert)
- VALUES (4,'PATRON_EXCEEDS_COLLECTIONS_WARNING',oils_i18n_gettext(4, 'Patron exceeds pre-collections warning fine threshold', 'csp', 'label'),'CIRC|HOLD|CAPTURE|FULFILL|RENEW', TRUE);
+ VALUES (4,'PATRON_EXCEEDS_COLLECTIONS_WARNING',oils_i18n_gettext(4, 'Patron exceeds pre-collections warning fine threshold', 'csp', 'label'),'CIRC|FULFILL|HOLD|CAPTURE|RENEW', TRUE);
INSERT INTO config.standing_penalty (id,name,label,staff_alert) VALUES (20,'ALERT_NOTE',oils_i18n_gettext(20, 'Alerting Note, no blocks', 'csp', 'label'),TRUE);
INSERT INTO config.standing_penalty (id,name,label) VALUES (21,'SILENT_NOTE',oils_i18n_gettext(21, 'Note, no blocks', 'csp', 'label'));
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql
index b2c25c3..560cf29 100644
--- a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql
@@ -1,11 +1,20 @@
UPDATE config.standing_penalty
- SET block_list = REPLACE(block_list, 'HOLD', 'HOLD|CAPTURE|FULFILL')
+ SET block_list = REPLACE(block_list, 'HOLD', 'HOLD|CAPTURE')
+ WHERE
+ -- STAFF_ penalties have names that match their block list
+ name NOT LIKE 'STAFF_%'
+ -- belt & suspenders, also good for testing
+ AND block_list NOT LIKE '%CAPTURE%';
+
+ -- CIRC|FULFILL is now the same as CIRC previously was by itself
+UPDATE config.standing_penalty
+ SET block_list = REPLACE(block_list, 'CIRC', 'CIRC|FULFILL')
WHERE
-- STAFF_ penalties have names that match their block list
name NOT LIKE 'STAFF_%'
-- belt & suspenders, also good for testing
- AND block_list NOT LIKE '%CAPTURE%'
AND block_list NOT LIKE '%FULFILL%';
+
commit 08075458b3fad3d9112d8dc2f2f6655056f8513d
Author: Bill Erickson <berick at esilibrary.com>
Date: Thu Jun 21 14:11:47 2012 -0400
hold CAP/FILL blocks : more event test collection repairs
Further improving the logic which decides which patron permit events are
valid for a given set of circumstances.
Signed-off-by: Bill Erickson <berick at esilibrary.com>
Signed-off-by: Jason Stephenson <jstephenson at mvlc.org>
Signed-off-by: Mike Rylander <mrylander at gmail.com>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
index 8139155..262e0ba 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
@@ -1104,23 +1104,26 @@ sub run_patron_permit_scripts {
if ($self->is_noncat) {
# no_item result is OK during noncat checkout
@trimmed_results = grep { ($_->{fail_part} || '') ne 'no_item' } @$results;
+
} else {
- @trimmed_results = @$results;
- }
- if ($self->checkout_is_for_hold) {
- # if this checkout will fulfill a hold, ignore CIRC blocks
- # and rely instead on the (later-checked) FULFILL block
+ if ($self->checkout_is_for_hold) {
+ # if this checkout will fulfill a hold, ignore CIRC blocks
+ # and rely instead on the (later-checked) FULFILL block
- my @pen_names = grep {$_} map {$_->{fail_part}} @$results;
- my $fblock_pens = $self->editor->search_config_standing_penalty(
- {name => [@pen_names], block_list => {like => '%CIRC%'}});
+ my @pen_names = grep {$_} map {$_->{fail_part}} @$results;
+ my $fblock_pens = $self->editor->search_config_standing_penalty(
+ {name => [@pen_names], block_list => {like => '%CIRC%'}});
+
+ for my $res (@$results) {
+ my $name = $res->{fail_part} || '';
+ next if grep {$_->name eq $name} @$fblock_pens;
+ push(@trimmed_results, $res);
+ }
- for my $res (@$results) {
- my $name = $res->{fail_part} || '';
- next if grep {$_->name eq $name} @$fblock_pens or
- ($self->is_noncat and $name eq 'no_item');
- push(@trimmed_results, $res);
+ } else {
+ # not for hold or noncat
+ @trimmed_results = @$results;
}
}
commit 169731b8569a378bae748c98514e42bd89954d17
Author: Bill Erickson <berick at esilibrary.com>
Date: Thu Jun 21 14:00:51 2012 -0400
hold CAP/FILL blocks : repair event test in patron permit
Repairs in oversight in the patron permit event testing code that caused
the test to miss events when the checkout was not there to fulfill a
hold.
Signed-off-by: Bill Erickson <berick at esilibrary.com>
Signed-off-by: Jason Stephenson <jstephenson at mvlc.org>
Signed-off-by: Mike Rylander <mrylander at gmail.com>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
index 7a30879..8139155 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
@@ -1104,6 +1104,8 @@ sub run_patron_permit_scripts {
if ($self->is_noncat) {
# no_item result is OK during noncat checkout
@trimmed_results = grep { ($_->{fail_part} || '') ne 'no_item' } @$results;
+ } else {
+ @trimmed_results = @$results;
}
if ($self->checkout_is_for_hold) {
commit 1b36e7a6af73c06417a4cbf19bf0585125b32a36
Author: Bill Erickson <berick at esilibrary.com>
Date: Tue Apr 10 16:24:59 2012 -0400
Avoid CAPTURE-blocked holds in pull list
Otherwise, staff will be pulling items for holds that cannot be
captured.
Signed-off-by: Bill Erickson <berick at esilibrary.com>
Signed-off-by: Jason Stephenson <jstephenson at mvlc.org>
Signed-off-by: Mike Rylander <mrylander at gmail.com>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm
index 78b0596..d80fbaf 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm
@@ -505,10 +505,15 @@ sub hold_pull_list {
FROM $h_table h
JOIN $a_table a ON (h.current_copy = a.id)
LEFT JOIN $ord_table ord ON (a.location = ord.location AND a.circ_lib = ord.org)
+ LEFT JOIN actor.usr_standing_penalty ausp
+ ON ( h.usr = 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%' )
WHERE a.circ_lib = ?
AND h.capture_time IS NULL
AND h.cancel_time IS NULL
AND (h.expire_time IS NULL OR h.expire_time > NOW())
+ AND csp.id IS NULL
$status_filter
ORDER BY CASE WHEN ord.position IS NOT NULL THEN ord.position ELSE 999 END, h.request_time
LIMIT $limit
@@ -520,10 +525,15 @@ sub hold_pull_list {
SELECT count(*)
FROM $h_table h
JOIN $a_table a ON (h.current_copy = a.id)
+ LEFT JOIN actor.usr_standing_penalty ausp
+ ON ( h.usr = 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%' )
WHERE a.circ_lib = ?
AND h.capture_time IS NULL
AND h.cancel_time IS NULL
AND (h.expire_time IS NULL OR h.expire_time > NOW())
+ AND csp.id IS NULL
$status_filter
SQL
}
commit 266fc54ebaab9806af3ee86ba39b778bc192ebf8
Author: Mike Rylander <mrylander at gmail.com>
Date: Tue Apr 10 10:21:02 2012 -0400
Avoid checkin capture for CAPTURE-blocked holds
Teach the nearest_hold sub about CAPTURE-blocking penalties
Signed-off-by: Mike Rylander <mrylander at gmail.com>
Signed-off-by: Bill Erickson <berick at esilibrary.com>
Signed-off-by: Jason Stephenson <jstephenson at mvlc.org>
Signed-off-by: Mike Rylander <mrylander at gmail.com>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm
index ada8dc4..78b0596 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm
@@ -294,8 +294,8 @@ sub nearest_hold {
local $OpenILS::Application::Storage::WRITE = 1;
my $holdsort = isTrue($fifo) ?
- "pgt.hold_priority, CASE WHEN h.cut_in_line IS TRUE THEN 0 ELSE 1 END, h.request_time, h.selection_depth DESC, p.prox " :
- "p.prox, pgt.hold_priority, CASE WHEN h.cut_in_line IS TRUE THEN 0 ELSE 1 END, h.selection_depth DESC, h.request_time ";
+ "pgt.hold_priority, CASE WHEN h.cut_in_line IS TRUE THEN 0 ELSE 1 END, h.request_time, h.selection_depth DESC, p.prox " :
+ "p.prox, pgt.hold_priority, CASE WHEN h.cut_in_line IS TRUE THEN 0 ELSE 1 END, h.selection_depth DESC, h.request_time ";
my $ids = action::hold_request->db_Main->selectcol_arrayref(<<" SQL", {}, $here, $cp, $age);
SELECT h.id
@@ -304,12 +304,17 @@ 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)
+ 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%' )
WHERE hm.target_copy = ?
AND (AGE(NOW(),h.request_time) >= CAST(? AS INTERVAL) OR p.prox = 0)
AND h.capture_time IS NULL
AND h.cancel_time IS NULL
AND (h.expire_time IS NULL OR h.expire_time > NOW())
- AND h.frozen IS FALSE
+ AND h.frozen IS FALSE
+ AND csp.id IS NULL
ORDER BY CASE WHEN h.hold_type IN ('R','F') THEN 0 ELSE 1 END, $holdsort
LIMIT $limit
SQL
commit a8155fc4c4728adbfd3e734a9ede7eca1f067c78
Author: Bill Erickson <berick at esilibrary.com>
Date: Tue Apr 10 15:42:17 2012 -0400
hold CAP/FILL blocks : separate CIRC and FULFILL blocks
This breaks the CIRC standing penalty block out into two separate
blocks. The existing CIRC block now prevents circulations on checkouts
where the checkout is not fulfilling a hold. A new FULFILL block type
is added which, when applied to a user, (only) prevents the user from
checking out items that fulfill a hold.
To always prevents checkouts, use both blocks. Use individual blocks
where one or the other behavior is desired.
Signed-off-by: Bill Erickson <berick at esilibrary.com>
Signed-off-by: Jason Stephenson <jstephenson at mvlc.org>
Signed-off-by: Mike Rylander <mrylander at gmail.com>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
index f5c0f07..7a30879 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
@@ -542,6 +542,7 @@ my @AUTOLOAD_FIELDS = qw/
fake_hold_dest
limit_groups
override_args
+ checkout_is_for_hold
/;
@@ -978,9 +979,9 @@ sub is_group_descendant {
}
sub check_captured_holds {
- my $self = shift;
- my $copy = $self->copy;
- my $patron = $self->patron;
+ my $self = shift;
+ my $copy = $self->copy;
+ my $patron = $self->patron;
return undef unless $copy;
@@ -989,7 +990,7 @@ sub check_captured_holds {
$logger->info("circulator: copy is on holds shelf, searching for the correct hold");
# Item is on the holds shelf, make sure it's going to the right person
- my $holds = $self->editor->search_action_hold_request(
+ my $hold = $self->editor->search_action_hold_request(
[
{
current_copy => $copy->id ,
@@ -999,10 +1000,11 @@ sub check_captured_holds {
},
{ limit => 1 }
]
- );
+ )->[0];
- if( $holds and $$holds[0] ) {
- return undef if $$holds[0]->usr == $patron->id;
+ if ($hold and $hold->usr == $patron->id) {
+ $self->checkout_is_for_hold(1);
+ return undef;
}
$logger->info("circulator: this copy is needed by a different patron to fulfill a hold");
@@ -1097,10 +1099,33 @@ sub run_patron_permit_scripts {
my $results = $self->run_indb_circ_test;
unless($self->circ_test_success) {
- # no_item result is OK during noncat checkout
- unless(@$results == 1 && $results->[0]->{fail_part} eq 'no_item' and $self->is_noncat) {
- push @allevents, $self->matrix_test_result_events;
+ my @trimmed_results;
+
+ if ($self->is_noncat) {
+ # no_item result is OK during noncat checkout
+ @trimmed_results = grep { ($_->{fail_part} || '') ne 'no_item' } @$results;
+ }
+
+ if ($self->checkout_is_for_hold) {
+ # if this checkout will fulfill a hold, ignore CIRC blocks
+ # and rely instead on the (later-checked) FULFILL block
+
+ my @pen_names = grep {$_} map {$_->{fail_part}} @$results;
+ my $fblock_pens = $self->editor->search_config_standing_penalty(
+ {name => [@pen_names], block_list => {like => '%CIRC%'}});
+
+ for my $res (@$results) {
+ my $name = $res->{fail_part} || '';
+ next if grep {$_->name eq $name} @$fblock_pens or
+ ($self->is_noncat and $name eq 'no_item');
+ push(@trimmed_results, $res);
+ }
}
+
+ # update the final set of test results
+ $self->matrix_test_result(\@trimmed_results);
+
+ push @allevents, $self->matrix_test_result_events;
}
} else {
@@ -1120,6 +1145,8 @@ sub run_patron_permit_scripts {
$penalties = $penalties->{fatal_penalties};
for my $pen (@$penalties) {
+ # CIRC blocks are ignored if this is a FULFILL scenario
+ next if $mask eq 'CIRC' and $self->checkout_is_for_hold;
my $event = OpenILS::Event->new($pen->name);
$event->{desc} = $pen->label;
push(@allevents, $event);
@@ -1633,6 +1660,44 @@ sub bail_on_events {
$self->bail_out(1);
}
+# ------------------------------------------------------------------------------
+# A hold FULFILL block is just like a CIRC block, except that FULFILL only
+# affects copies that will fulfill holds and CIRC affects all other copies.
+# If blocks exists, bail, push Events onto the event pile, and return true.
+# ------------------------------------------------------------------------------
+sub check_hold_fulfill_blocks {
+ my $self = shift;
+
+ # See if the user has any penalties applied that prevent hold fulfillment
+ my $pens = $self->editor->json_query({
+ select => {csp => ['name', 'label']},
+ from => {ausp => {csp => {}}},
+ where => {
+ '+ausp' => {
+ usr => $self->patron->id,
+ org_unit => $U->get_org_full_path($self->circ_lib),
+ '-or' => [
+ {stop_date => undef},
+ {stop_date => {'>' => 'now'}}
+ ]
+ },
+ '+csp' => {block_list => {'like' => '%FULFILL%'}}
+ }
+ });
+
+ return 0 unless @$pens;
+
+ for my $pen (@$pens) {
+ $logger->info("circulator: patron has hold FULFILL block " . $pen->{name});
+ my $event = OpenILS::Event->new($pen->{name});
+ $event->{desc} = $pen->{label};
+ $self->push_events($event);
+ }
+
+ $self->override_events;
+ return $self->bail_out;
+}
+
# ------------------------------------------------------------------------------
# When an item is checked out, see if we can fulfill a hold for this patron
@@ -1682,6 +1747,8 @@ sub handle_checkout_holds {
$logger->info("circulator: found related hold to fulfill in checkout");
}
+ return if $self->check_hold_fulfill_blocks;
+
$logger->debug("circulator: checkout fulfilling hold " . $hold->id);
# if the hold was never officially captured, capture it.
commit ae0e26ed0862b3694415806ce2dc05e128868c24
Author: Bill Erickson <berick at esilibrary.com>
Date: Tue Apr 10 15:41:51 2012 -0400
DB seed data for CAPTURE and FULFILL penalty blocks
All occurrences of HOLD in the block list for any existing penalties are
updated to HOLD|CAPTURE|FULFILL for backwards compatibility, minus the
handful of STAFF_* penalties whose codes match their respective
block_lists.
To use these new block types, simply update existing penalties as
desired or add new local pentalty types for staff-managed patron
blocking messages.
Signed-off-by: Bill Erickson <berick at esilibrary.com>
Signed-off-by: Jason Stephenson <jstephenson at mvlc.org>
Signed-off-by: Mike Rylander <mrylander at gmail.com>
diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
index 312a425..0c0744c 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -20,13 +20,13 @@ INSERT INTO config.standing (id, value) VALUES (2, oils_i18n_gettext(2, 'Barred'
SELECT SETVAL('config.standing_id_seq'::TEXT, 100);
INSERT INTO config.standing_penalty (id,name,label,block_list,staff_alert)
- VALUES (1,'PATRON_EXCEEDS_FINES',oils_i18n_gettext(1, 'Patron exceeds fine threshold', 'csp', 'label'),'CIRC|HOLD|RENEW', TRUE);
+ VALUES (1,'PATRON_EXCEEDS_FINES',oils_i18n_gettext(1, 'Patron exceeds fine threshold', 'csp', 'label'),'CIRC|HOLD|CAPTURE|FULFILL|RENEW', TRUE);
INSERT INTO config.standing_penalty (id,name,label,block_list,staff_alert)
- VALUES (2,'PATRON_EXCEEDS_OVERDUE_COUNT',oils_i18n_gettext(2, 'Patron exceeds max overdue item threshold', 'csp', 'label'),'CIRC|HOLD|RENEW', TRUE);
+ VALUES (2,'PATRON_EXCEEDS_OVERDUE_COUNT',oils_i18n_gettext(2, 'Patron exceeds max overdue item threshold', 'csp', 'label'),'CIRC|HOLD|CAPTURE|FULFILL|RENEW', TRUE);
INSERT INTO config.standing_penalty (id,name,label,block_list,staff_alert)
VALUES (3,'PATRON_EXCEEDS_CHECKOUT_COUNT',oils_i18n_gettext(3, 'Patron exceeds max checked out item threshold', 'csp', 'label'),'CIRC', TRUE);
INSERT INTO config.standing_penalty (id,name,label,block_list,staff_alert)
- VALUES (4,'PATRON_EXCEEDS_COLLECTIONS_WARNING',oils_i18n_gettext(4, 'Patron exceeds pre-collections warning fine threshold', 'csp', 'label'),'CIRC|HOLD|RENEW', TRUE);
+ VALUES (4,'PATRON_EXCEEDS_COLLECTIONS_WARNING',oils_i18n_gettext(4, 'Patron exceeds pre-collections warning fine threshold', 'csp', 'label'),'CIRC|HOLD|CAPTURE|FULFILL|RENEW', TRUE);
INSERT INTO config.standing_penalty (id,name,label,staff_alert) VALUES (20,'ALERT_NOTE',oils_i18n_gettext(20, 'Alerting Note, no blocks', 'csp', 'label'),TRUE);
INSERT INTO config.standing_penalty (id,name,label) VALUES (21,'SILENT_NOTE',oils_i18n_gettext(21, 'Note, no blocks', 'csp', 'label'));
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql
new file mode 100644
index 0000000..b2c25c3
--- /dev/null
+++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.hold_cap_fill_penalty_blocks.sql
@@ -0,0 +1,11 @@
+
+
+UPDATE config.standing_penalty
+ SET block_list = REPLACE(block_list, 'HOLD', 'HOLD|CAPTURE|FULFILL')
+ WHERE
+ -- STAFF_ penalties have names that match their block list
+ name NOT LIKE 'STAFF_%'
+ -- belt & suspenders, also good for testing
+ AND block_list NOT LIKE '%CAPTURE%'
+ AND block_list NOT LIKE '%FULFILL%';
+
-----------------------------------------------------------------------
Summary of changes:
Open-ILS/examples/fm_IDL.xml | 13 +++
.../lib/OpenILS/Application/Circ/Circulate.pm | 92 +++++++++++++++++--
.../Application/Storage/Publisher/action.pm | 21 ++++-
Open-ILS/src/sql/Pg/002.schema.config.sql | 2 +-
Open-ILS/src/sql/Pg/110.hold_matrix.sql | 10 ++-
Open-ILS/src/sql/Pg/950.data.seed-values.sql | 8 +-
... => 0721.data.hold_cap_fill_penalty_blocks.sql} | 37 ++++++--
7 files changed, 156 insertions(+), 27 deletions(-)
copy Open-ILS/src/sql/Pg/upgrade/{0668.schema.fix_indb_hold_permit.sql => 0721.data.hold_cap_fill_penalty_blocks.sql} (88%)
hooks/post-receive
--
Evergreen ILS
More information about the open-ils-commits
mailing list