From e25fffd88d0577f6a35acbfb18498f515a34b5cb Mon Sep 17 00:00:00 2001 From: Kyle Hall Date: Wed, 31 Aug 2022 12:52:53 -0400 Subject: [PATCH] Bug 31500 - Add ability to specify MaxReservesPickupDelay at the patron category level Some libraries would like to be able to override MaxReservesPickupDelay on a per category basis. A good use case for this is that some libraries have a special patron category for patrons that are from "out of town" on vacation. In this case, the library may want to specify a shorter pickup period before the item expires than they would for a patron that lives in the area. Test Plan: 1) Apply this patch, restart all the things! 2) Set MaxReservesPickupDelay to 5 days 3) Choose a patron category, go to the categories editor, near the bottom of the form is the new "Max holds pickup delay" field. Set this field to 10 days 4) Place a hold for an item using a patron of that category 5) Trap the hold so it is waiting 6) Note the expiration date is 10 days from now 7) Repeat steps 4-6 for a patron of a different category 8) Note the expiration date is 5 days out --- Koha/Hold.pm | 2 +- admin/categories.pl | 3 ++ .../data/mysql/atomicupdate/bug_31500.pl | 13 ++++++++ installer/data/mysql/kohastructure.sql | 1 + .../prog/en/modules/admin/categories.tt | 5 +++ .../prog/en/modules/circ/waitingreserves.tt | 2 +- t/db_dependent/Koha/Holds.t | 31 ++++++++++++++++++- t/lib/TestBuilder.pm | 1 + 8 files changed, 55 insertions(+), 3 deletions(-) create mode 100755 installer/data/mysql/atomicupdate/bug_31500.pl diff --git a/Koha/Hold.pm b/Koha/Hold.pm index ca261086c7..8e075943a7 100644 --- a/Koha/Hold.pm +++ b/Koha/Hold.pm @@ -220,7 +220,7 @@ sub set_waiting { desk_id => $desk_id, }; - my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay"); + my $max_pickup_delay = $self->patron->category->reserves_max_pickup_delay || C4::Context->preference("ReservesMaxPickUpDelay"); my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays'); my $new_expiration_date = $today->clone->add(days => $max_pickup_delay); diff --git a/admin/categories.pl b/admin/categories.pl index 53c4182b47..4753d3bf22 100755 --- a/admin/categories.pl +++ b/admin/categories.pl @@ -64,6 +64,7 @@ elsif ( $op eq 'add_validate' ) { my $enrolmentperioddate = $input->param('enrolmentperioddate') || undef; my $password_expiry_days = $input->param('password_expiry_days') || undef; my $upperagelimit = $input->param('upperagelimit'); + my $reserves_max_pickup_delay = $input->param('reserves_max_pickup_delay') || undef; my $dateofbirthrequired = $input->param('dateofbirthrequired'); my $enrolmentfee = $input->param('enrolmentfee'); my $reservefee = $input->param('reservefee'); @@ -96,6 +97,7 @@ elsif ( $op eq 'add_validate' ) { $category->enrolmentperioddate($enrolmentperioddate); $category->password_expiry_days($password_expiry_days); $category->upperagelimit($upperagelimit); + $category->reserves_max_pickup_delay($reserves_max_pickup_delay); $category->dateofbirthrequired($dateofbirthrequired); $category->enrolmentfee($enrolmentfee); $category->reservefee($reservefee); @@ -129,6 +131,7 @@ elsif ( $op eq 'add_validate' ) { enrolmentperioddate => $enrolmentperioddate, password_expiry_days => $password_expiry_days, upperagelimit => $upperagelimit, + reserves_max_pickup_delay => $reserves_max_pickup_delay, dateofbirthrequired => $dateofbirthrequired, enrolmentfee => $enrolmentfee, reservefee => $reservefee, diff --git a/installer/data/mysql/atomicupdate/bug_31500.pl b/installer/data/mysql/atomicupdate/bug_31500.pl new file mode 100755 index 0000000000..bd39d44b09 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_31500.pl @@ -0,0 +1,13 @@ +use Modern::Perl; + +return { + bug_number => "31500", + description => "Add column categories.reserves_max_pickup_delay", + up => sub { + my ($args) = @_; + my ($dbh, $out) = @$args{qw(dbh out)}; + if( !column_exists( 'categories', 'reserves_max_pickup_delay' ) ) { + $dbh->do(q{ALTER TABLE categories ADD COLUMN `reserves_max_pickup_delay` smallint(6) DEFAULT NULL COMMENT 'override ReservesMaxPickUpDelay for this patron category' AFTER exclude_from_local_holds_priority}); + } + }, +}; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index affa80e9c2..215643e45b 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -1676,6 +1676,7 @@ CREATE TABLE `categories` ( `min_password_length` smallint(6) DEFAULT NULL COMMENT 'set minimum password length for patrons in this category', `require_strong_password` tinyint(1) DEFAULT NULL COMMENT 'set required password strength for patrons in this category', `exclude_from_local_holds_priority` tinyint(1) DEFAULT NULL COMMENT 'Exclude patrons of this category from local holds priority', + `reserves_max_pickup_delay` smallint(6) DEFAULT NULL COMMENT 'override ReservesMaxPickUpDelay for this patron category', PRIMARY KEY (`categorycode`), UNIQUE KEY `categorycode` (`categorycode`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt index 1982459a7e..d4e35f221b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt @@ -437,6 +437,11 @@
If Yes, holds placed by patrons of this category will not be given priority
+
  • + + days +
    Mark a hold as problematic if it has been waiting for more than this number of days. Overrides the default value in ReservesMaxPickUpDelay
    +
  • diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt index d0178bad40..fee11f56da 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt @@ -94,7 +94,7 @@
  • - Holds waiting over [% Koha.Preference('ReservesMaxPickUpDelay') | html %] days: [% overcount | html %] + Holds waiting over passed pickup date: [% overcount | html %]
  • diff --git a/t/db_dependent/Koha/Holds.t b/t/db_dependent/Koha/Holds.t index aec261dd1f..6b0553ea35 100755 --- a/t/db_dependent/Koha/Holds.t +++ b/t/db_dependent/Koha/Holds.t @@ -539,7 +539,7 @@ subtest 'get_items_that_can_fill' => sub { }; subtest 'set_waiting+patron_expiration_date' => sub { - plan tests => 2; + plan tests => 3; my $library = $builder->build_object( { class => 'Koha::Libraries' } ); my $item = @@ -639,6 +639,35 @@ subtest 'set_waiting+patron_expiration_date' => sub { is( $hold->expirationdate, $patron_expiration_date ); is( $hold->patron_expiration_date, $patron_expiration_date ); }; + + subtest 'Test patron category level reserves_max_pickup_delay' => sub { + plan tests => 1; + + t::lib::Mocks::mock_preference( 'ReservesMaxPickUpDelay', 5 ); + + my $category = $patron->category; + $category->reserves_max_pickup_delay(6)->store(); + + my $expiration_date = dt_from_string->add( days => 6 )->ymd; + + my $reserve_id = C4::Reserves::AddReserve( + { + branchcode => $library->branchcode, + borrowernumber => $patron->borrowernumber, + biblionumber => $item->biblionumber, + priority => 1, + itemnumber => $item->itemnumber, + } + ); + + my $hold = Koha::Holds->find($reserve_id); + + $hold->set_waiting; + + $hold = $hold->get_from_storage; + + is( $hold->expirationdate, $expiration_date ); + }; }; diff --git a/t/lib/TestBuilder.pm b/t/lib/TestBuilder.pm index 59ba592da0..a64cf967ae 100644 --- a/t/lib/TestBuilder.pm +++ b/t/lib/TestBuilder.pm @@ -583,6 +583,7 @@ sub _gen_default_values { category_type => sub { return [ qw( A C S I P ) ]->[int(rand(5))] }, min_password_length => undef, require_strong_password => undef, + reserves_max_pickup_delay => undef, }, Branch => { pickup_location => 0, -- 2.30.2