[open-ils-commits] [GIT] Evergreen ILS branch master updated. 40e20683c5d2aa78a128ed019be163349545a4d7

Evergreen Git git at git.evergreen-ils.org
Wed Aug 24 12:19:41 EDT 2016


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  40e20683c5d2aa78a128ed019be163349545a4d7 (commit)
       via  d60ea525afa3e4318f474f481e9c8b911ff39e99 (commit)
       via  f0aa5d587467a42e61669f1d3e417489e57813d3 (commit)
       via  fed65df3c669e1337f187d533e9033a697d6b263 (commit)
       via  2c40b84273316525de7ef65ca6ceca9f939c7052 (commit)
       via  3c37c14663fbf9eea99e2bcd82773a229d02bf1c (commit)
       via  31480730b2458e8915660f4fb78893418ccdf9cb (commit)
      from  51759b283ca19b15a252faa830c2e4b4a3199695 (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 40e20683c5d2aa78a128ed019be163349545a4d7
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Aug 24 12:17:11 2016 -0400

    Stamping upgrade of is_available branch
    
    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 08aefa9..0c8e9ad 100644
--- a/Open-ILS/src/sql/Pg/002.schema.config.sql
+++ b/Open-ILS/src/sql/Pg/002.schema.config.sql
@@ -91,7 +91,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 ('0991', :eg_version); -- dbwells/miker
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0992', :eg_version); -- berick/miker
 
 CREATE TABLE config.bib_source (
 	id		SERIAL	PRIMARY KEY,
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql b/Open-ILS/src/sql/Pg/upgrade/0992.schema.copy_status_co_allowed.sql
similarity index 99%
rename from Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql
rename to Open-ILS/src/sql/Pg/upgrade/0992.schema.copy_status_co_allowed.sql
index 1777681..129e3c4 100644
--- a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/0992.schema.copy_status_co_allowed.sql
@@ -1,5 +1,7 @@
 BEGIN;
 
+SELECT evergreen.upgrade_deps_block_check('0992', :eg_version);
+
 ALTER TABLE config.copy_status
     ADD COLUMN is_available BOOL NOT NULL DEFAULT FALSE;
 

commit d60ea525afa3e4318f474f481e9c8b911ff39e99
Author: Bill Erickson <berickxx at gmail.com>
Date:   Wed Aug 24 10:26:28 2016 -0400

    LP#1464709 Copy status is_available release notes
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>

diff --git a/docs/RELEASE_NOTES_NEXT/Circulation/copy-status-is-avail.adoc b/docs/RELEASE_NOTES_NEXT/Circulation/copy-status-is-avail.adoc
new file mode 100644
index 0000000..7b5df08
--- /dev/null
+++ b/docs/RELEASE_NOTES_NEXT/Circulation/copy-status-is-avail.adoc
@@ -0,0 +1,17 @@
+Copy Status "Is Available" Flag
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Adds a new boolean field for copy statuses to indicate when copies having
+a given status should be considered available.  The field has 2 main effects:
+
+1. Checking out an "available" copy will no longer result in an override-able
+   "COPY_NOT_AVAILABLE" alert for staff.  The copy will checkout without 
+   status warnings.
+
+2. "Available" copies will appear in catalog searches where "limit to
+   available" is selected as a search filter.
+
+By default, the "Available" and "Reshelving" statuses have the "Is Available" 
+flag set.  The flag may be applied to local/custom statues via the copy
+status admin interface.
+

commit f0aa5d587467a42e61669f1d3e417489e57813d3
Author: Mike Rylander <mrylander at gmail.com>
Date:   Tue Aug 23 16:59:33 2016 -0400

    LP#1464709: Disentangle on-holds-shelf from is_available
    
    Avoid treating On-Holds-Shelf items as is_available so they do not
    appear in the catalog as #available.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/sql/Pg/100.circ_matrix.sql b/Open-ILS/src/sql/Pg/100.circ_matrix.sql
index 566588b..53b207a 100644
--- a/Open-ILS/src/sql/Pg/100.circ_matrix.sql
+++ b/Open-ILS/src/sql/Pg/100.circ_matrix.sql
@@ -499,7 +499,7 @@ BEGIN
     END IF;
 
     -- Fail if the item isn't in a circulateable status on a non-renewal
-    IF NOT renewal AND item_object.status NOT IN ( 
+    IF NOT renewal AND item_object.status <> 8 AND item_object.status NOT IN (
         (SELECT id FROM config.copy_status WHERE is_available) ) THEN 
         result.fail_part := 'asset.copy.status';
         result.success := FALSE;
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 c198d35..e8228c8 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -314,7 +314,7 @@ INSERT INTO config.copy_status (id,name) VALUES (4,oils_i18n_gettext(4, 'Missing
 INSERT INTO config.copy_status (id,name,holdable,opac_visible) VALUES (5,oils_i18n_gettext(5, 'In process', 'ccs', 'name'),'t','t');
 INSERT INTO config.copy_status (id,name,holdable,opac_visible,restrict_copy_delete) VALUES (6,oils_i18n_gettext(6, 'In transit', 'ccs', 'name'),'t','t','t');
 INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,is_available) VALUES (7,oils_i18n_gettext(7, 'Reshelving', 'ccs', 'name'),'t','t','t','t');
-INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,restrict_copy_delete,is_available) VALUES (8,oils_i18n_gettext(8, 'On holds shelf', 'ccs', 'name'),'t','t','t','t','t');
+INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,restrict_copy_delete) VALUES (8,oils_i18n_gettext(8, 'On holds shelf', 'ccs', 'name'),'t','t','t','t');
 INSERT INTO config.copy_status (id,name,holdable,opac_visible) VALUES (9,oils_i18n_gettext(9, 'On order', 'ccs', 'name'),'t','t');
 INSERT INTO config.copy_status (id,name,copy_active) VALUES (10,oils_i18n_gettext(10, 'ILL', 'ccs', 'name'),'t');
 INSERT INTO config.copy_status (id,name) VALUES (11,oils_i18n_gettext(11, 'Cataloging', 'ccs', 'name'));
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql
index b787c1a..1777681 100644
--- a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql
@@ -4,7 +4,7 @@ ALTER TABLE config.copy_status
     ADD COLUMN is_available BOOL NOT NULL DEFAULT FALSE;
 
 UPDATE config.copy_status SET is_available = TRUE
-    WHERE id IN (0, 7, 8); -- available, reshelving, holds shelf.
+    WHERE id IN (0, 7); -- available, reshelving.
 
 CREATE OR REPLACE FUNCTION action.item_user_circ_test( circ_ou INT, match_item BIGINT, match_user INT, renewal BOOL ) RETURNS SETOF action.circ_matrix_test_result AS $func$
 DECLARE
@@ -92,7 +92,7 @@ BEGIN
     END IF;
 
     -- Fail if the item isn't in a circulateable status on a non-renewal
-    IF NOT renewal AND item_object.status NOT IN ( 
+    IF NOT renewal AND item_object.status <> 8 AND item_object.status NOT IN (
         (SELECT id FROM config.copy_status WHERE is_available) ) THEN 
         result.fail_part := 'asset.copy.status';
         result.success := FALSE;

commit fed65df3c669e1337f187d533e9033a697d6b263
Author: Mike Rylander <mrylander at gmail.com>
Date:   Thu Aug 18 09:52:20 2016 -0400

    LP#1464709: teach QP about is_available statuses
    
    We look them up, cache them, and use them for the #available modifier.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/metabib.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/metabib.pm
index debc865..5fea5c7 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/metabib.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/metabib.pm
@@ -2818,6 +2818,14 @@ __PACKAGE__->register_method(
     }
 );
 
+my @available_statuses_cache;
+sub available_statuses {
+    if (!scalar(@available_statuses_cache)) {
+       @available_statuses_cache = map { $_->id } config::copy_status->search_where({is_available => 't'});
+    }
+    return @available_statuses_cache;
+}
+
 sub query_parser_fts {
     my $self = shift;
     my $client = shift;
@@ -2992,10 +3000,11 @@ sub query_parser_fts {
 
     # gather statuses, and then forget those if we have an #available modifier
     my @statuses;
-    if (my ($filter) = $query->parse_tree->find_filter('statuses')) {
+    if ($query->parse_tree->find_modifier('available')) {
+        @statuses = available_statuses();
+    } elsif (my ($filter) = $query->parse_tree->find_filter('statuses')) {
         @statuses = @{$filter->args} if (@{$filter->args});
     }
-    @statuses = (0,7,12) if ($query->parse_tree->find_modifier('available'));
 
 
     # gather locations

commit 2c40b84273316525de7ef65ca6ceca9f939c7052
Author: Bill Erickson <berickxx at gmail.com>
Date:   Thu Aug 27 17:24:38 2015 -0400

    LP#1464709 Rename checkout_ok to is_available
    
    And update pgptap to check for only 2 is_available statuses (not
    on-holds shelf).
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    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 d0cfb00..65dc4db 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -3894,7 +3894,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 			<field name="opac_visible" reporter:datatype="bool"/>
             <field name="copy_active" reporter:datatype="bool"/>
             <field name="restrict_copy_delete" reporter:datatype="bool"/>
-            <field name="checkout_ok" reporter:datatype="bool"/>
+            <field name="is_available" reporter:datatype="bool"/>
 		</fields>
 		<links/>
         <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
diff --git a/Open-ILS/src/sql/Pg/002.schema.config.sql b/Open-ILS/src/sql/Pg/002.schema.config.sql
index 1c32efe..08aefa9 100644
--- a/Open-ILS/src/sql/Pg/002.schema.config.sql
+++ b/Open-ILS/src/sql/Pg/002.schema.config.sql
@@ -396,7 +396,7 @@ CREATE TABLE config.copy_status (
 	opac_visible	BOOL	NOT NULL DEFAULT FALSE,
     copy_active  BOOL    NOT NULL DEFAULT FALSE,
 	restrict_copy_delete BOOL	  NOT NULL DEFAULT FALSE,
-    checkout_ok  BOOL    NOT NULL DEFAULT FALSE
+    is_available  BOOL    NOT NULL DEFAULT FALSE
 );
 COMMENT ON TABLE config.copy_status IS $$
 Copy Statuses
diff --git a/Open-ILS/src/sql/Pg/100.circ_matrix.sql b/Open-ILS/src/sql/Pg/100.circ_matrix.sql
index c53e7ee..566588b 100644
--- a/Open-ILS/src/sql/Pg/100.circ_matrix.sql
+++ b/Open-ILS/src/sql/Pg/100.circ_matrix.sql
@@ -500,7 +500,7 @@ BEGIN
 
     -- Fail if the item isn't in a circulateable status on a non-renewal
     IF NOT renewal AND item_object.status NOT IN ( 
-        (SELECT id FROM config.copy_status WHERE checkout_ok) ) THEN 
+        (SELECT id FROM config.copy_status WHERE is_available) ) THEN 
         result.fail_part := 'asset.copy.status';
         result.success := FALSE;
         done := TRUE;
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 1209408..c198d35 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -306,15 +306,15 @@ INSERT INTO config.rule_age_hold_protect VALUES
 	(2, oils_i18n_gettext(2, '6month', 'crahp', 'name'), '6 months', 2);
 SELECT SETVAL('config.rule_age_hold_protect_id_seq'::TEXT, 100);
 
-INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,checkout_ok) VALUES (0,oils_i18n_gettext(0, 'Available', 'ccs', 'name'),'t','t','t','t');
+INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,is_available) VALUES (0,oils_i18n_gettext(0, 'Available', 'ccs', 'name'),'t','t','t','t');
 INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,restrict_copy_delete) VALUES (1,oils_i18n_gettext(1, 'Checked out', 'ccs', 'name'),'t','t','t','t');
 INSERT INTO config.copy_status (id,name) VALUES (2,oils_i18n_gettext(2, 'Bindery', 'ccs', 'name'));
 INSERT INTO config.copy_status (id,name,restrict_copy_delete) VALUES (3,oils_i18n_gettext(3, 'Lost', 'ccs', 'name'),'t');
 INSERT INTO config.copy_status (id,name) VALUES (4,oils_i18n_gettext(4, 'Missing', 'ccs', 'name'));
 INSERT INTO config.copy_status (id,name,holdable,opac_visible) VALUES (5,oils_i18n_gettext(5, 'In process', 'ccs', 'name'),'t','t');
 INSERT INTO config.copy_status (id,name,holdable,opac_visible,restrict_copy_delete) VALUES (6,oils_i18n_gettext(6, 'In transit', 'ccs', 'name'),'t','t','t');
-INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,checkout_ok) VALUES (7,oils_i18n_gettext(7, 'Reshelving', 'ccs', 'name'),'t','t','t','t');
-INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,restrict_copy_delete,checkout_ok) VALUES (8,oils_i18n_gettext(8, 'On holds shelf', 'ccs', 'name'),'t','t','t','t','t');
+INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,is_available) VALUES (7,oils_i18n_gettext(7, 'Reshelving', 'ccs', 'name'),'t','t','t','t');
+INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,restrict_copy_delete,is_available) VALUES (8,oils_i18n_gettext(8, 'On holds shelf', 'ccs', 'name'),'t','t','t','t','t');
 INSERT INTO config.copy_status (id,name,holdable,opac_visible) VALUES (9,oils_i18n_gettext(9, 'On order', 'ccs', 'name'),'t','t');
 INSERT INTO config.copy_status (id,name,copy_active) VALUES (10,oils_i18n_gettext(10, 'ILL', 'ccs', 'name'),'t');
 INSERT INTO config.copy_status (id,name) VALUES (11,oils_i18n_gettext(11, 'Cataloging', 'ccs', 'name'));
diff --git a/Open-ILS/src/sql/Pg/live_t/lp1464709-copy-stat-co-ok.live.pg b/Open-ILS/src/sql/Pg/live_t/lp1464709-copy-stat-co-ok.live.pg
index 2874298..21b68a0 100644
--- a/Open-ILS/src/sql/Pg/live_t/lp1464709-copy-stat-co-ok.live.pg
+++ b/Open-ILS/src/sql/Pg/live_t/lp1464709-copy-stat-co-ok.live.pg
@@ -24,22 +24,22 @@ SELECT is(
     'Checkout test Available succeeds'
 ) FROM action.item_user_circ_test(4, 1, 1);
 
--- checkout_ok defaults to false
+-- is_available defaults to false
 INSERT into config.copy_status (id, name) VALUES (101, 'lp1464709');
 UPDATE asset.copy SET status = 101 WHERE id = 1;
 
 SELECT is(
     fail_part,
     'asset.copy.status',
-    'Checkout test checkout_ok=false fails'
+    'Checkout test is_available=false fails'
 ) FROM action.item_user_circ_test(4, 1, 1);
 
-UPDATE config.copy_status SET checkout_ok = TRUE WHERE name = 'lp1464709';
+UPDATE config.copy_status SET is_available = TRUE WHERE name = 'lp1464709';
 
 SELECT is(
     fail_part,
     NULL,
-    'Checkout test checkout_ok=true succeeds'
+    'Checkout test is_available=true succeeds'
 ) FROM action.item_user_circ_test(4, 1, 1);
 
 
diff --git a/Open-ILS/src/sql/Pg/t/lp1464709-copy-stat-co-ok.pg b/Open-ILS/src/sql/Pg/t/lp1464709-copy-stat-co-ok.pg
index dfe9a99..070eb88 100644
--- a/Open-ILS/src/sql/Pg/t/lp1464709-copy-stat-co-ok.pg
+++ b/Open-ILS/src/sql/Pg/t/lp1464709-copy-stat-co-ok.pg
@@ -20,9 +20,9 @@ SELECT plan(1);
 
 -- ensures the column exists and seed data has been updated.
 SELECT cmp_ok(
-    COUNT(*)::int, '>=', 3, 
-    'At least 3 copy status should be configured as "checkout_ok"') 
-    FROM config.copy_status WHERE checkout_ok;
+    COUNT(*)::int, '>=', 2, 
+    'At least 2 copy status should be configured as "is_available"') 
+    FROM config.copy_status WHERE is_available;
 
 -- Finish the tests and clean up.
 SELECT * FROM finish();
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql
index e1e3509..b787c1a 100644
--- a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql
@@ -1,9 +1,9 @@
 BEGIN;
 
 ALTER TABLE config.copy_status
-    ADD COLUMN checkout_ok BOOL NOT NULL DEFAULT FALSE;
+    ADD COLUMN is_available BOOL NOT NULL DEFAULT FALSE;
 
-UPDATE config.copy_status SET checkout_ok = TRUE
+UPDATE config.copy_status SET is_available = TRUE
     WHERE id IN (0, 7, 8); -- available, reshelving, holds shelf.
 
 CREATE OR REPLACE FUNCTION action.item_user_circ_test( circ_ou INT, match_item BIGINT, match_user INT, renewal BOOL ) RETURNS SETOF action.circ_matrix_test_result AS $func$
@@ -93,7 +93,7 @@ BEGIN
 
     -- Fail if the item isn't in a circulateable status on a non-renewal
     IF NOT renewal AND item_object.status NOT IN ( 
-        (SELECT id FROM config.copy_status WHERE checkout_ok) ) THEN 
+        (SELECT id FROM config.copy_status WHERE is_available) ) THEN 
         result.fail_part := 'asset.copy.status';
         result.success := FALSE;
         done := TRUE;
diff --git a/Open-ILS/web/conify/global/config/copy_status.html b/Open-ILS/web/conify/global/config/copy_status.html
index c9a3699..af3c67b 100644
--- a/Open-ILS/web/conify/global/config/copy_status.html
+++ b/Open-ILS/web/conify/global/config/copy_status.html
@@ -227,13 +227,13 @@
 											}
 										  }
 										},
-										{ name : ccs_strings.CHECKOUT_OK,
-										  field : "checkout_ok",
+										{ name : ccs_strings.IS_AVAILABLE,
+										  field : "is_available",
 										  editor : dojox.grid.editors.bool,
 										  get : function (row) {
 											var r = window.status_data_model.getRow(row);
 											if (r) {
-												var h = r.checkout_ok;
+												var h = r.is_available;
 												if (h == 't' || h === true) return true;
 												return false;
 											}
diff --git a/Open-ILS/web/js/dojo/openils/conify/nls/conify.js b/Open-ILS/web/js/dojo/openils/conify/nls/conify.js
index 1dfc1d3..ef9a7ad 100644
--- a/Open-ILS/web/js/dojo/openils/conify/nls/conify.js
+++ b/Open-ILS/web/js/dojo/openils/conify/nls/conify.js
@@ -7,7 +7,7 @@
 	"CONFIRM_EXIT_PPL": "There are unsaved modified permissions. Click OK to save these changes, or Cancel to abandon them.",
 	"CONFIRM_UNSAVED_CHANGES": "There are unsaved changes to one or more organization types. Click OK to save these changes, or Cancel to abandon them.",
 	"COPY_ACTIVE": "Sets copy active",
-	"CHECKOUT_OK": "Checkout OK",
+	"IS_AVAILABLE": "Is Available",
 	"ERROR_CALLING_METHOD_AOUT": "Problem calling method to create child organization type",
 	"ERROR_CALLING_METHOD_CAM": "Problem calling method to create new ${0}",
 	"ERROR_CALLING_METHOD_CCS": "Problem calling method to create new copy status",

commit 3c37c14663fbf9eea99e2bcd82773a229d02bf1c
Author: Bill Erickson <berickxx at gmail.com>
Date:   Mon Jun 15 18:09:01 2015 -0400

    LP#1464709 Non-standard copy status pgtap tests
    
    Includes unit test plus a set of live tests.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>

diff --git a/Open-ILS/src/sql/Pg/live_t/lp1464709-copy-stat-co-ok.live.pg b/Open-ILS/src/sql/Pg/live_t/lp1464709-copy-stat-co-ok.live.pg
new file mode 100644
index 0000000..2874298
--- /dev/null
+++ b/Open-ILS/src/sql/Pg/live_t/lp1464709-copy-stat-co-ok.live.pg
@@ -0,0 +1,48 @@
+\set ECHO none
+\set QUIET 1
+-- Turn off echo and keep things quiet.
+
+-- Format the output for nice TAP.
+\pset format unaligned
+\pset tuples_only true
+\pset pager
+
+-- Revert all changes on failure.
+\set ON_ERROR_ROLLBACK 1
+\set ON_ERROR_STOP true
+\set QUIET 1
+
+-- Load the TAP functions.
+BEGIN;
+
+-- Plan the tests.
+SELECT plan(3);
+
+SELECT is(
+    fail_part,
+    NULL,
+    'Checkout test Available succeeds'
+) FROM action.item_user_circ_test(4, 1, 1);
+
+-- checkout_ok defaults to false
+INSERT into config.copy_status (id, name) VALUES (101, 'lp1464709');
+UPDATE asset.copy SET status = 101 WHERE id = 1;
+
+SELECT is(
+    fail_part,
+    'asset.copy.status',
+    'Checkout test checkout_ok=false fails'
+) FROM action.item_user_circ_test(4, 1, 1);
+
+UPDATE config.copy_status SET checkout_ok = TRUE WHERE name = 'lp1464709';
+
+SELECT is(
+    fail_part,
+    NULL,
+    'Checkout test checkout_ok=true succeeds'
+) FROM action.item_user_circ_test(4, 1, 1);
+
+
+-- Finish the tests and clean up.
+SELECT * FROM finish();
+ROLLBACK;
diff --git a/Open-ILS/src/sql/Pg/t/lp1464709-copy-stat-co-ok.pg b/Open-ILS/src/sql/Pg/t/lp1464709-copy-stat-co-ok.pg
new file mode 100644
index 0000000..dfe9a99
--- /dev/null
+++ b/Open-ILS/src/sql/Pg/t/lp1464709-copy-stat-co-ok.pg
@@ -0,0 +1,29 @@
+\set ECHO none
+\set QUIET 1
+-- Turn off echo and keep things quiet.
+
+-- Format the output for nice TAP.
+\pset format unaligned
+\pset tuples_only true
+\pset pager
+
+-- Revert all changes on failure.
+\set ON_ERROR_ROLLBACK 1
+\set ON_ERROR_STOP true
+\set QUIET 1
+
+-- Load the TAP functions.
+BEGIN;
+
+-- Plan the tests.
+SELECT plan(1);
+
+-- ensures the column exists and seed data has been updated.
+SELECT cmp_ok(
+    COUNT(*)::int, '>=', 3, 
+    'At least 3 copy status should be configured as "checkout_ok"') 
+    FROM config.copy_status WHERE checkout_ok;
+
+-- Finish the tests and clean up.
+SELECT * FROM finish();
+ROLLBACK;

commit 31480730b2458e8915660f4fb78893418ccdf9cb
Author: Bill Erickson <berickxx at gmail.com>
Date:   Wed Jun 3 19:30:40 2015 -0400

    LP#1464709 Seamless non-standard copy status checkout
    
    Add a new boolean configuration option to copy statuses which allow such
    copies to be checked out without requiring an alert or override.
    
    New column is config.copy_status.checkout_ok.  Any status with this
    boolean enabled will be treated the same as Available, Reshelving, and
    Holds Shelf status copies in that the status will be considered
    checkout-able.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    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 b21f7b3..d0cfb00 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -3893,7 +3893,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 			<field name="name"  reporter:datatype="text" oils_persist:i18n="true"/>
 			<field name="opac_visible" reporter:datatype="bool"/>
             <field name="copy_active" reporter:datatype="bool"/>
-	    <field name="restrict_copy_delete" reporter:datatype="bool"/>
+            <field name="restrict_copy_delete" reporter:datatype="bool"/>
+            <field name="checkout_ok" reporter:datatype="bool"/>
 		</fields>
 		<links/>
         <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
diff --git a/Open-ILS/src/sql/Pg/002.schema.config.sql b/Open-ILS/src/sql/Pg/002.schema.config.sql
index 6b4b998..1c32efe 100644
--- a/Open-ILS/src/sql/Pg/002.schema.config.sql
+++ b/Open-ILS/src/sql/Pg/002.schema.config.sql
@@ -395,7 +395,8 @@ CREATE TABLE config.copy_status (
 	holdable	BOOL	NOT NULL DEFAULT FALSE,
 	opac_visible	BOOL	NOT NULL DEFAULT FALSE,
     copy_active  BOOL    NOT NULL DEFAULT FALSE,
-	restrict_copy_delete BOOL	  NOT NULL DEFAULT FALSE
+	restrict_copy_delete BOOL	  NOT NULL DEFAULT FALSE,
+    checkout_ok  BOOL    NOT NULL DEFAULT FALSE
 );
 COMMENT ON TABLE config.copy_status IS $$
 Copy Statuses
diff --git a/Open-ILS/src/sql/Pg/100.circ_matrix.sql b/Open-ILS/src/sql/Pg/100.circ_matrix.sql
index 4226a27..c53e7ee 100644
--- a/Open-ILS/src/sql/Pg/100.circ_matrix.sql
+++ b/Open-ILS/src/sql/Pg/100.circ_matrix.sql
@@ -499,7 +499,8 @@ BEGIN
     END IF;
 
     -- Fail if the item isn't in a circulateable status on a non-renewal
-    IF NOT renewal AND item_object.status NOT IN ( 0, 7, 8 ) THEN 
+    IF NOT renewal AND item_object.status NOT IN ( 
+        (SELECT id FROM config.copy_status WHERE checkout_ok) ) THEN 
         result.fail_part := 'asset.copy.status';
         result.success := FALSE;
         done := TRUE;
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 0b5aab9..1209408 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -306,15 +306,15 @@ INSERT INTO config.rule_age_hold_protect VALUES
 	(2, oils_i18n_gettext(2, '6month', 'crahp', 'name'), '6 months', 2);
 SELECT SETVAL('config.rule_age_hold_protect_id_seq'::TEXT, 100);
 
-INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active) VALUES (0,oils_i18n_gettext(0, 'Available', 'ccs', 'name'),'t','t','t');
+INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,checkout_ok) VALUES (0,oils_i18n_gettext(0, 'Available', 'ccs', 'name'),'t','t','t','t');
 INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,restrict_copy_delete) VALUES (1,oils_i18n_gettext(1, 'Checked out', 'ccs', 'name'),'t','t','t','t');
 INSERT INTO config.copy_status (id,name) VALUES (2,oils_i18n_gettext(2, 'Bindery', 'ccs', 'name'));
 INSERT INTO config.copy_status (id,name,restrict_copy_delete) VALUES (3,oils_i18n_gettext(3, 'Lost', 'ccs', 'name'),'t');
 INSERT INTO config.copy_status (id,name) VALUES (4,oils_i18n_gettext(4, 'Missing', 'ccs', 'name'));
 INSERT INTO config.copy_status (id,name,holdable,opac_visible) VALUES (5,oils_i18n_gettext(5, 'In process', 'ccs', 'name'),'t','t');
 INSERT INTO config.copy_status (id,name,holdable,opac_visible,restrict_copy_delete) VALUES (6,oils_i18n_gettext(6, 'In transit', 'ccs', 'name'),'t','t','t');
-INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active) VALUES (7,oils_i18n_gettext(7, 'Reshelving', 'ccs', 'name'),'t','t','t');
-INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,restrict_copy_delete) VALUES (8,oils_i18n_gettext(8, 'On holds shelf', 'ccs', 'name'),'t','t','t','t');
+INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,checkout_ok) VALUES (7,oils_i18n_gettext(7, 'Reshelving', 'ccs', 'name'),'t','t','t','t');
+INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active,restrict_copy_delete,checkout_ok) VALUES (8,oils_i18n_gettext(8, 'On holds shelf', 'ccs', 'name'),'t','t','t','t','t');
 INSERT INTO config.copy_status (id,name,holdable,opac_visible) VALUES (9,oils_i18n_gettext(9, 'On order', 'ccs', 'name'),'t','t');
 INSERT INTO config.copy_status (id,name,copy_active) VALUES (10,oils_i18n_gettext(10, 'ILL', 'ccs', 'name'),'t');
 INSERT INTO config.copy_status (id,name) VALUES (11,oils_i18n_gettext(11, 'Cataloging', 'ccs', 'name'));
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql
new file mode 100644
index 0000000..e1e3509
--- /dev/null
+++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_status_co_allowed.sql
@@ -0,0 +1,229 @@
+BEGIN;
+
+ALTER TABLE config.copy_status
+    ADD COLUMN checkout_ok BOOL NOT NULL DEFAULT FALSE;
+
+UPDATE config.copy_status SET checkout_ok = TRUE
+    WHERE id IN (0, 7, 8); -- available, reshelving, holds shelf.
+
+CREATE OR REPLACE FUNCTION action.item_user_circ_test( circ_ou INT, match_item BIGINT, match_user INT, renewal BOOL ) RETURNS SETOF action.circ_matrix_test_result AS $func$
+DECLARE
+    user_object             actor.usr%ROWTYPE;
+    standing_penalty        config.standing_penalty%ROWTYPE;
+    item_object             asset.copy%ROWTYPE;
+    item_status_object      config.copy_status%ROWTYPE;
+    item_location_object    asset.copy_location%ROWTYPE;
+    result                  action.circ_matrix_test_result;
+    circ_test               action.found_circ_matrix_matchpoint;
+    circ_matchpoint         config.circ_matrix_matchpoint%ROWTYPE;
+    circ_limit_set          config.circ_limit_set%ROWTYPE;
+    hold_ratio              action.hold_stats%ROWTYPE;
+    penalty_type            TEXT;
+    items_out               INT;
+    context_org_list        INT[];
+    done                    BOOL := FALSE;
+BEGIN
+    -- Assume success unless we hit a failure condition
+    result.success := TRUE;
+
+    -- Need user info to look up matchpoints
+    SELECT INTO user_object * FROM actor.usr WHERE id = match_user AND NOT deleted;
+
+    -- (Insta)Fail if we couldn't find the user
+    IF user_object.id IS NULL THEN
+        result.fail_part := 'no_user';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+        RETURN;
+    END IF;
+
+    -- Need item info to look up matchpoints
+    SELECT INTO item_object * FROM asset.copy WHERE id = match_item AND NOT deleted;
+
+    -- (Insta)Fail if we couldn't find the item 
+    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 circ_test * FROM action.find_circ_matrix_matchpoint(circ_ou, item_object, user_object, renewal);
+
+    circ_matchpoint             := circ_test.matchpoint;
+    result.matchpoint           := circ_matchpoint.id;
+    result.circulate            := circ_matchpoint.circulate;
+    result.duration_rule        := circ_matchpoint.duration_rule;
+    result.recurring_fine_rule  := circ_matchpoint.recurring_fine_rule;
+    result.max_fine_rule        := circ_matchpoint.max_fine_rule;
+    result.hard_due_date        := circ_matchpoint.hard_due_date;
+    result.renewals             := circ_matchpoint.renewals;
+    result.grace_period         := circ_matchpoint.grace_period;
+    result.buildrows            := circ_test.buildrows;
+
+    -- (Insta)Fail if we couldn't find a matchpoint
+    IF circ_test.success = false THEN
+        result.fail_part := 'no_matchpoint';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+        RETURN;
+    END IF;
+
+    -- All failures before this point are non-recoverable
+    -- Below this point are possibly overridable failures
+
+    -- Fail if the user is barred
+    IF user_object.barred IS TRUE THEN
+        result.fail_part := 'actor.usr.barred';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    -- Fail if the item can't circulate
+    IF item_object.circulate IS FALSE THEN
+        result.fail_part := 'asset.copy.circulate';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    -- Fail if the item isn't in a circulateable status on a non-renewal
+    IF NOT renewal AND item_object.status NOT IN ( 
+        (SELECT id FROM config.copy_status WHERE checkout_ok) ) THEN 
+        result.fail_part := 'asset.copy.status';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    -- Alternately, fail if the item isn't checked out on a renewal
+    ELSIF renewal AND item_object.status <> 1 THEN
+        result.fail_part := 'asset.copy.status';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    -- Fail if the item can't circulate because of the shelving location
+    SELECT INTO item_location_object * FROM asset.copy_location WHERE id = item_object.location;
+    IF item_location_object.circulate IS FALSE THEN
+        result.fail_part := 'asset.copy_location.circulate';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    -- Use Circ OU for penalties and such
+    SELECT INTO context_org_list ARRAY_AGG(id) FROM actor.org_unit_full_path( circ_ou );
+
+    IF renewal THEN
+        penalty_type = '%RENEW%';
+    ELSE
+        penalty_type = '%CIRC%';
+    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 penalty_type LOOP
+
+        result.fail_part := standing_penalty.name;
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END LOOP;
+
+    -- Fail if the test is set to hard non-circulating
+    IF circ_matchpoint.circulate IS FALSE THEN
+        result.fail_part := 'config.circ_matrix_test.circulate';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    -- Fail if the total copy-hold ratio is too low
+    IF circ_matchpoint.total_copy_hold_ratio IS NOT NULL THEN
+        SELECT INTO hold_ratio * FROM action.copy_related_hold_stats(match_item);
+        IF hold_ratio.total_copy_ratio IS NOT NULL AND hold_ratio.total_copy_ratio < circ_matchpoint.total_copy_hold_ratio THEN
+            result.fail_part := 'config.circ_matrix_test.total_copy_hold_ratio';
+            result.success := FALSE;
+            done := TRUE;
+            RETURN NEXT result;
+        END IF;
+    END IF;
+
+    -- Fail if the available copy-hold ratio is too low
+    IF circ_matchpoint.available_copy_hold_ratio IS NOT NULL THEN
+        IF hold_ratio.hold_count IS NULL THEN
+            SELECT INTO hold_ratio * FROM action.copy_related_hold_stats(match_item);
+        END IF;
+        IF hold_ratio.available_copy_ratio IS NOT NULL AND hold_ratio.available_copy_ratio < circ_matchpoint.available_copy_hold_ratio THEN
+            result.fail_part := 'config.circ_matrix_test.available_copy_hold_ratio';
+            result.success := FALSE;
+            done := TRUE;
+            RETURN NEXT result;
+        END IF;
+    END IF;
+
+    -- Fail if the user has too many items out by defined limit sets
+    FOR circ_limit_set IN SELECT ccls.* FROM config.circ_limit_set ccls
+      JOIN config.circ_matrix_limit_set_map ccmlsm ON ccmlsm.limit_set = ccls.id
+      WHERE ccmlsm.active AND ( ccmlsm.matchpoint = circ_matchpoint.id OR
+        ( ccmlsm.matchpoint IN (SELECT * FROM unnest(result.buildrows)) AND ccmlsm.fallthrough )
+        ) LOOP
+            IF circ_limit_set.items_out > 0 AND NOT renewal THEN
+                SELECT INTO context_org_list ARRAY_AGG(aou.id)
+                  FROM actor.org_unit_full_path( circ_ou ) aou
+                    JOIN actor.org_unit_type aout ON aou.ou_type = aout.id
+                  WHERE aout.depth >= circ_limit_set.depth;
+                IF circ_limit_set.global THEN
+                    WITH RECURSIVE descendant_depth AS (
+                        SELECT  ou.id,
+                            ou.parent_ou
+                        FROM  actor.org_unit ou
+                        WHERE ou.id IN (SELECT * FROM unnest(context_org_list))
+                            UNION
+                        SELECT  ou.id,
+                            ou.parent_ou
+                        FROM  actor.org_unit ou
+                            JOIN descendant_depth ot ON (ot.id = ou.parent_ou)
+                    ) SELECT INTO context_org_list ARRAY_AGG(ou.id) FROM actor.org_unit ou JOIN descendant_depth USING (id);
+                END IF;
+                SELECT INTO items_out COUNT(DISTINCT circ.id)
+                  FROM action.circulation circ
+                    JOIN asset.copy copy ON (copy.id = circ.target_copy)
+                    LEFT JOIN action.circulation_limit_group_map aclgm ON (circ.id = aclgm.circ)
+                  WHERE circ.usr = match_user
+                    AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
+                    AND circ.checkin_time IS NULL
+                    AND (circ.stop_fines IN ('MAXFINES','LONGOVERDUE') OR circ.stop_fines IS NULL)
+                    AND (copy.circ_modifier IN (SELECT circ_mod FROM config.circ_limit_set_circ_mod_map WHERE limit_set = circ_limit_set.id)
+                        OR copy.location IN (SELECT copy_loc FROM config.circ_limit_set_copy_loc_map WHERE limit_set = circ_limit_set.id)
+                        OR aclgm.limit_group IN (SELECT limit_group FROM config.circ_limit_set_group_map WHERE limit_set = circ_limit_set.id)
+                    );
+                IF items_out >= circ_limit_set.items_out THEN
+                    result.fail_part := 'config.circ_matrix_circ_mod_test';
+                    result.success := FALSE;
+                    done := TRUE;
+                    RETURN NEXT result;
+                END IF;
+            END IF;
+            SELECT INTO result.limit_groups result.limit_groups || ARRAY_AGG(limit_group) FROM config.circ_limit_set_group_map WHERE limit_set = circ_limit_set.id AND NOT check_only;
+    END LOOP;
+
+    -- If we passed everything, return the successful matchpoint
+    IF NOT done THEN
+        RETURN NEXT result;
+    END IF;
+
+    RETURN;
+END;
+$func$ LANGUAGE plpgsql;
+
+COMMIT;
diff --git a/Open-ILS/web/conify/global/config/copy_status.html b/Open-ILS/web/conify/global/config/copy_status.html
index 262eaf2..c9a3699 100644
--- a/Open-ILS/web/conify/global/config/copy_status.html
+++ b/Open-ILS/web/conify/global/config/copy_status.html
@@ -226,6 +226,18 @@
 												return false;
 											}
 										  }
+										},
+										{ name : ccs_strings.CHECKOUT_OK,
+										  field : "checkout_ok",
+										  editor : dojox.grid.editors.bool,
+										  get : function (row) {
+											var r = window.status_data_model.getRow(row);
+											if (r) {
+												var h = r.checkout_ok;
+												if (h == 't' || h === true) return true;
+												return false;
+											}
+										  }
 										}
 									]
 								]
diff --git a/Open-ILS/web/js/dojo/openils/conify/nls/conify.js b/Open-ILS/web/js/dojo/openils/conify/nls/conify.js
index 961f9ef..1dfc1d3 100644
--- a/Open-ILS/web/js/dojo/openils/conify/nls/conify.js
+++ b/Open-ILS/web/js/dojo/openils/conify/nls/conify.js
@@ -7,6 +7,7 @@
 	"CONFIRM_EXIT_PPL": "There are unsaved modified permissions. Click OK to save these changes, or Cancel to abandon them.",
 	"CONFIRM_UNSAVED_CHANGES": "There are unsaved changes to one or more organization types. Click OK to save these changes, or Cancel to abandon them.",
 	"COPY_ACTIVE": "Sets copy active",
+	"CHECKOUT_OK": "Checkout OK",
 	"ERROR_CALLING_METHOD_AOUT": "Problem calling method to create child organization type",
 	"ERROR_CALLING_METHOD_CAM": "Problem calling method to create new ${0}",
 	"ERROR_CALLING_METHOD_CCS": "Problem calling method to create new copy status",

-----------------------------------------------------------------------

Summary of changes:
 Open-ILS/examples/fm_IDL.xml                       |    3 +-
 .../Application/Storage/Publisher/metabib.pm       |   13 +++-
 Open-ILS/src/sql/Pg/002.schema.config.sql          |    5 +-
 Open-ILS/src/sql/Pg/100.circ_matrix.sql            |    3 +-
 Open-ILS/src/sql/Pg/950.data.seed-values.sql       |    4 +-
 .../Pg/live_t/lp1464709-copy-stat-co-ok.live.pg    |   48 ++++++++++++
 ...-in-setting.pg => lp1464709-copy-stat-co-ok.pg} |   13 ++--
 ....sql => 0992.schema.copy_status_co_allowed.sql} |   80 +++++++++++++------
 Open-ILS/web/conify/global/config/copy_status.html |   12 +++
 Open-ILS/web/js/dojo/openils/conify/nls/conify.js  |    1 +
 .../Circulation/copy-status-is-avail.adoc          |   17 ++++
 11 files changed, 159 insertions(+), 40 deletions(-)
 create mode 100644 Open-ILS/src/sql/Pg/live_t/lp1464709-copy-stat-co-ok.live.pg
 copy Open-ILS/src/sql/Pg/t/{lp1533329-restrict-opt-in-setting.pg => lp1464709-copy-stat-co-ok.pg} (61%)
 copy Open-ILS/src/sql/Pg/upgrade/{0637.schema.renewal_checkout_counting.sql => 0992.schema.copy_status_co_allowed.sql} (64%)
 create mode 100644 docs/RELEASE_NOTES_NEXT/Circulation/copy-status-is-avail.adoc


hooks/post-receive
-- 
Evergreen ILS




More information about the open-ils-commits mailing list