From 753c5fe349cbca24e34e611d218c9bf9fc269a70 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Wed, 15 Apr 2026 17:12:50 +0100 Subject: [PATCH] Bug 41410: Add local_holdgroup_match column and exclusivity period syspref Adds groundwork for a time-bounded local holds exclusivity feature: - Adds a local_holdgroup_match flag (tinyint, default 0) to both hold_fill_targets (consulted by CheckReserves/_Findgroupreserve at checkin) and tmp_holdsqueue (so queue/pull-list reports can display it). The flag will be set by the queue builder when a local-group match is made. - Adds a new system preference LocalHoldsPriorityExclusivityPeriod (Integer, default 0 = disabled) specifying the number of days from hold creation during which only locally-targeted items may fill a hold with a local queue target. - Provides an atomicupdate that guards both ALTERs with column_exists and INSERT IGNOREs the new syspref. Test plan: 1. Apply atomicupdate: perl installer/data/mysql/updatedatabase.pl 2. Verify both columns exist: SHOW COLUMNS FROM hold_fill_targets LIKE 'local%'; SHOW COLUMNS FROM tmp_holdsqueue LIKE 'local%'; 3. Verify syspref row: SELECT variable, value FROM systempreferences WHERE variable = 'LocalHoldsPriorityExclusivityPeriod'; 4. Confirm default value is 0 and type is Integer. Sponsored-by: Main Library Alliance Signed-off-by: Trevor Diamond Signed-off-by: Andrew Fuerste Henry Signed-off-by: Pedro Amorim --- .../data/mysql/atomicupdate/bug_41410.pl | 58 +++++++++++++++++++ installer/data/mysql/kohastructure.sql | 2 + installer/data/mysql/mandatory/sysprefs.sql | 1 + 3 files changed, 61 insertions(+) create mode 100755 installer/data/mysql/atomicupdate/bug_41410.pl diff --git a/installer/data/mysql/atomicupdate/bug_41410.pl b/installer/data/mysql/atomicupdate/bug_41410.pl new file mode 100755 index 0000000000..adf4893f20 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_41410.pl @@ -0,0 +1,58 @@ +use Modern::Perl; +use Koha::Installer::Output qw(say_success say_info say_warning); + +return { + bug_number => "41410", + description => "Add local holds priority exclusivity period", + up => sub { + my ($args) = @_; + my ( $dbh, $out ) = @$args{qw(dbh out)}; + + if ( column_exists( 'hold_fill_targets', 'local_holdgroup_match' ) ) { + say_warning( $out, "Column 'hold_fill_targets.local_holdgroup_match' already exists, skipping." ); + } else { + $dbh->do( + q{ + ALTER TABLE hold_fill_targets + ADD COLUMN `local_holdgroup_match` tinyint(1) NOT NULL DEFAULT 0 + COMMENT 'set when the queue targeted this item as a local hold group match for the reserve' + AFTER reserve_id + } + ); + say_success( $out, "Added column 'hold_fill_targets.local_holdgroup_match'" ); + } + + if ( column_exists( 'tmp_holdsqueue', 'local_holdgroup_match' ) ) { + say_warning( $out, "Column 'tmp_holdsqueue.local_holdgroup_match' already exists, skipping." ); + } else { + $dbh->do( + q{ + ALTER TABLE tmp_holdsqueue + ADD COLUMN `local_holdgroup_match` tinyint(1) NOT NULL DEFAULT 0 + COMMENT 'set when the queue targeted this item as a local hold group match for the reserve' + AFTER item_level_request + } + ); + say_success( $out, "Added column 'tmp_holdsqueue.local_holdgroup_match'" ); + } + + $dbh->do( + q{ + INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type) + VALUES ( + 'LocalHoldsPriorityExclusivityPeriod', + '0', + NULL, + 'When LocalHoldsPriority is set, for this many days after a hold is placed, only items flagged as a local hold group match by the holds queue may fill the hold. Set to 0 to disable.', + 'Integer' + ) + } + ); + say_success( $out, "Added new system preference 'LocalHoldsPriorityExclusivityPeriod'" ); + + say_info( + $out, + "The LocalHoldsPriorityExclusivityPeriod feature only takes effect when LocalHoldsPriority is set to something other than 'None'." + ); + }, +}; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 3777004f0d..79532a8c9f 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -3542,6 +3542,7 @@ CREATE TABLE `hold_fill_targets` ( `source_branchcode` varchar(10) DEFAULT NULL, `item_level_request` tinyint(4) NOT NULL DEFAULT 0, `reserve_id` int(11) DEFAULT NULL, + `local_holdgroup_match` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'set when the queue targeted this item as a local hold group match for the reserve', PRIMARY KEY (`itemnumber`), KEY `bib_branch` (`biblionumber`,`source_branchcode`), KEY `hold_fill_targets_ibfk_1` (`borrowernumber`), @@ -6976,6 +6977,7 @@ CREATE TABLE `tmp_holdsqueue` ( `notes` mediumtext DEFAULT NULL, `hold_group_id` int(10) unsigned DEFAULT NULL, `item_level_request` tinyint(4) NOT NULL DEFAULT 0, + `local_holdgroup_match` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'set when the queue targeted this item as a local hold group match for the reserve', `timestamp` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT 'date and time this entry as added/last updated', PRIMARY KEY (`itemnumber`), KEY `tmp_holdsqueue_ibfk_1` (`itemnumber`), diff --git a/installer/data/mysql/mandatory/sysprefs.sql b/installer/data/mysql/mandatory/sysprefs.sql index 89adefe86f..0e546d9434 100644 --- a/installer/data/mysql/mandatory/sysprefs.sql +++ b/installer/data/mysql/mandatory/sysprefs.sql @@ -421,6 +421,7 @@ INSERT INTO systempreferences ( `variable`, `value` ) VALUES ('LoadSearchHistoryToTheFirstLoggedUser', '1'), ('LocalCoverImages','0'), ('LocalHoldsPriority', 'None'), +('LocalHoldsPriorityExclusivityPeriod', '0'), ('LocalHoldsPriorityItemControl', 'holdingbranch'), ('LocalHoldsPriorityPatronControl', 'PickupLibrary'), ('LockExpiredDelay',''),