From 66affe782274b2d0c89f22a32b6d61c0e2e35860 Mon Sep 17 00:00:00 2001 From: Magnus Enger Date: Wed, 11 Dec 2019 12:36:06 +0100 Subject: [PATCH] Bug 22833 - Block suspend and cancel on holds Swedish ILL uses a hold as part of the ILL workflow. It is problematic if patrons suspend or cancel those holds before the ILL request is received. This patch makes it possible to configure, on the itemtype level, if it should be possible to suspend or cancel holds. Since a record can have items with different itemtypes, the record level itemtype is used to determine if holds connected to a record can be suspended and/or cancelled. If suspension is blocked for an itemtype, holds connected to records with that itemtype can not be - individually suspended by patrons in the OPAC (The "Suspend" button is not shown in the table of active holds in the "Holds" tab in "My summary".) - suspended as part of a "suspend all" operation in the OPAC - suspended as part of a "suspend all" operation in the staff client (but individual holds can still be suspended by staff) If cancellation is blocked for an itemtype, holds connected to records with that itemtype can not be - individually cancelled by patrons in the OPAC (The "Cancel" button is not shown in the table of active holds in the "Holds" tab in "My summary".) To test: - Apply the patch and make sure the atomic database update is run - Make sure you have two different itemtypes and records with those itemtypes at the record level (field 942$c in MARC 21). - Toggle the two new settings on the itemtypes, and make sure the behaviour is in line with the behaviour described above. --- C4/Reserves.pm | 14 ++++++--- Koha/Template/Plugin/ItemTypes.pm | 20 ++++++++++++ admin/itemtypes.pl | 6 ++++ ..._22833-block_suspend_and_cancel_holds.perl | 31 +++++++++++++++++++ installer/data/mysql/kohastructure.sql | 2 ++ .../prog/en/modules/admin/itemtypes.tt | 18 +++++++++++ .../bootstrap/en/includes/holds-table.inc | 4 +-- 7 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_22833-block_suspend_and_cancel_holds.perl diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 73d39895f3..1d149ad29c 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -1369,11 +1369,15 @@ sub SuspendAll { my @holds = Koha::Holds->search($params); - if ($suspend) { - map { $_->suspend_hold($suspend_until) } @holds; - } - else { - map { $_->resume() } @holds; + HOLD: foreach my $hold ( @holds ) { + if ($suspend) { + if ( $hold->biblio->itemtype ) { + next HOLD if Koha::ItemTypes->find({ itemtype => $hold->biblio->itemtype })->can_suspend_hold == 0; + } + $hold->suspend_hold($suspend_until); + } else { + $hold->resume(); + } } } diff --git a/Koha/Template/Plugin/ItemTypes.pm b/Koha/Template/Plugin/ItemTypes.pm index 20910562b0..027d28d78b 100644 --- a/Koha/Template/Plugin/ItemTypes.pm +++ b/Koha/Template/Plugin/ItemTypes.pm @@ -30,6 +30,26 @@ sub GetDescription { return $itemtype ? $itemtype->translated_description : q{}; } +sub CanSuspendHold { + my ( $self, $itemtypecode ) = @_; + my $itemtype = Koha::ItemTypes->find( $itemtypecode ); + if ( $itemtype ) { + return $itemtype->can_suspend_hold; + } else { + return 1; # Default should be "yes" + } +} + +sub CanCancelHold { + my ( $self, $itemtypecode ) = @_; + my $itemtype = Koha::ItemTypes->find( $itemtypecode ); + if ( $itemtype ) { + return $itemtype->can_cancel_hold; + } else { + return 1; # Default should be "yes" + } +} + sub Get { return Koha::ItemTypes->search_with_localization->unblessed; } diff --git a/admin/itemtypes.pl b/admin/itemtypes.pl index 8a341b6e11..8a05bc801a 100755 --- a/admin/itemtypes.pl +++ b/admin/itemtypes.pl @@ -105,6 +105,8 @@ if ( $op eq 'add_form' ) { my $checkinmsgtype = $input->param('checkinmsgtype'); my $hideinopac = $input->param('hideinopac') // 0; my $searchcategory = $input->param('searchcategory'); + my $can_suspend_hold = $input->param('can_suspend_hold'); + my $can_cancel_hold = $input->param('can_cancel_hold'); if ( $itemtype and $is_a_modif ) { # it's a modification $itemtype->description($description); @@ -121,6 +123,8 @@ if ( $op eq 'add_form' ) { $itemtype->sip_media_type($sip_media_type); $itemtype->hideinopac($hideinopac); $itemtype->searchcategory($searchcategory); + $itemtype->can_suspend_hold($can_suspend_hold); + $itemtype->can_cancel_hold($can_cancel_hold); eval { $itemtype->store; @@ -150,6 +154,8 @@ if ( $op eq 'add_form' ) { sip_media_type => $sip_media_type, hideinopac => $hideinopac, searchcategory => $searchcategory, + can_suspend_hold => $can_suspend_hold, + can_cancel_hold => $can_cancel_hold, } ); eval { diff --git a/installer/data/mysql/atomicupdate/bug_22833-block_suspend_and_cancel_holds.perl b/installer/data/mysql/atomicupdate/bug_22833-block_suspend_and_cancel_holds.perl new file mode 100644 index 0000000000..167da54c3e --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_22833-block_suspend_and_cancel_holds.perl @@ -0,0 +1,31 @@ +$DBversion = 'XXX'; # will be replaced by the RM +if( CheckVersion( $DBversion ) ) { + + unless ( column_exists('itemtypes', 'can_suspend_holds') ) { + $dbh->do( + qq{ + ALTER TABLE itemtypes + ADD + can_suspend_hold TINYINT(1) DEFAULT 1 NOT NULL + AFTER + searchcategory + } + ); + } + + unless ( column_exists('itemtypes', 'can_cancel_holds') ) { + $dbh->do( + qq{ + ALTER TABLE itemtypes + ADD + can_cancel_hold TINYINT(1) DEFAULT 1 NOT NULL + AFTER + can_suspend_holds + } + ); + } + + # Always end with this (adjust the bug info) + SetVersion( $DBversion ); + print "Upgrade to $DBversion done (Bug 22833 - Block suspend and cancel on holds)\n"; +} diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 67495ab962..e517a4ddd9 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -934,6 +934,8 @@ CREATE TABLE `itemtypes` ( -- defines the item types sip_media_type VARCHAR(3) DEFAULT NULL, -- SIP2 protocol media type for this itemtype hideinopac tinyint(1) NOT NULL DEFAULT 0, -- Hide the item type from the search options in OPAC searchcategory varchar(80) default NULL, -- Group this item type with others with the same value on OPAC search options + can_suspend_hold TINYINT(1) DEFAULT 1 NOT NULL, -- Should patrons be able to suspend holds on records with this record level itemtype in the OPAC + can_cancel_hold TINYINT(1) DEFAULT 1 NOT NULL, -- Should patrons be able to cancel holds on records with this record level itemtype in the OPAC PRIMARY KEY (`itemtype`), UNIQUE KEY `itemtype` (`itemtype`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt index 71dbe498f6..1326c09e01 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt @@ -286,6 +286,24 @@ Item types administration [% END %] +
  • + + [% IF ( itemtype.can_suspend_hold ) %] + + [% ELSE %] + + [% END %] + If not checked, holds on records of this type can not be suspended in the OPAC or in bulk in the staff client. +
  • +
  • + + [% IF ( itemtype.can_cancel_hold ) %] + + [% ELSE %] + + [% END %] + If not checked, holds on records of this type can not be cancelled in the OPAC. +
  • @@ -183,7 +183,7 @@ [% END # / IF SuspendHoldsOpac %] [% IF ! onlyinfo %] - [% IF ( HOLD.is_cancelable_from_opac ) %] + [% IF ( HOLD.is_cancelable_from_opac && ItemTypes.CanCancelHold( HOLD.biblio.biblioitem.itemtype ) ) %]
    -- 2.17.1