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 <https://www.mainlib.org/>

Signed-off-by: Trevor Diamond <trevor.diamond@mainlib.org>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
Martin Renvoize 2026-04-15 17:12:50 +01:00 committed by Pedro Amorim
parent 2fe11906a7
commit 753c5fe349
No known key found for this signature in database
GPG Key ID: 06B75BA7F3894D55
3 changed files with 61 additions and 0 deletions

View File

@ -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'."
);
},
};

View File

@ -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`),

View File

@ -421,6 +421,7 @@ INSERT INTO systempreferences ( `variable`, `value` ) VALUES
('LoadSearchHistoryToTheFirstLoggedUser', '1'),
('LocalCoverImages','0'),
('LocalHoldsPriority', 'None'),
('LocalHoldsPriorityExclusivityPeriod', '0'),
('LocalHoldsPriorityItemControl', 'holdingbranch'),
('LocalHoldsPriorityPatronControl', 'PickupLibrary'),
('LockExpiredDelay',''),