Bugzilla – Attachment 163093 Details for
Bug 15565
Place multiple item-level holds at once for the same record
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 15565: Place multiple holds on one record on staff interface
Bug-15565-Place-multiple-holds-on-one-record-on-st.patch (text/plain), 13.83 KB, created by
Lisette Scheer
on 2024-03-12 15:27:40 UTC
(
hide
)
Description:
Bug 15565: Place multiple holds on one record on staff interface
Filename:
MIME Type:
Creator:
Lisette Scheer
Created:
2024-03-12 15:27:40 UTC
Size:
13.83 KB
patch
obsolete
>From d53a943f79a3b698ea6ce0a56449f0d4a907bb7a Mon Sep 17 00:00:00 2001 >From: David Cook <dcook@prosentient.com.au> >Date: Mon, 12 Feb 2024 23:17:05 +0000 >Subject: [PATCH] Bug 15565: Place multiple holds on one record on staff > interface > >Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com> >--- > .../prog/en/modules/reserve/request.tt | 70 ++++++++++++++--- > reserve/placerequest.pl | 78 +++++++++++-------- > reserve/request.pl | 3 + > 3 files changed, 108 insertions(+), 43 deletions(-) > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >index c6a8bba700..8653094915 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >@@ -168,6 +168,56 @@ > </div> > [% END %] > >+ [% IF ( failed_holds ) %] >+ <div class="dialog alert"> >+ <strong>One or more holds were not placed due to following errors:</strong> >+ <ul> >+ [% FOREACH fail IN failed_holds %] >+ <li> >+ [% SWITCH fail %] >+ [% CASE 'damaged' %] >+ <span>Item is damaged</span> >+ [% CASE 'ageRestricted' %] >+ <span>The record and its items are age restricted</span> >+ [% CASE 'tooManyHoldsForThisRecord' %] >+ <span>Patron exceeded the number of concurrent holds for this record</span> >+ [% CASE 'tooManyReservesToday' %] >+ <span>Patron reached daily holds limit</span> >+ [% CASE 'tooManyReserves' %] >+ <span>Too many holds already</span> >+ [% CASE 'notReservable' %] >+ <span>Not holdable</span> >+ [% CASE 'cannotReserveFromOtherBranches' %] >+ <span>Patron from a different library</span> >+ [% CASE 'branchNotInHoldGroup' %] >+ <span>Holds are not allowed from patron's library</span> >+ [% CASE 'itemAlreadyOnHold' %] >+ <span>Patron already has a hold for failed item(s)</span> >+ [% CASE 'cannotBeTransferred' %] >+ <span>Cannot be transferred to pickup library</span> >+ [% CASE 'pickupNotInHoldGroup' %] >+ <span>The chosen pickup location is not allowed</span> >+ [% CASE 'noReservesAllowed' %] >+ <span>No holds are allowed on failed item(s)</span> >+ [% CASE 'libraryNotPickupLocation' %] >+ <span>Library is not a valid pickup location</span> >+ [% CASE 'no_valid_pickup_location' %] >+ <span>No valid pickup location</span> >+ [% CASE 'notforloan' %] >+ <span>Not for loan</span> >+ [% CASE 'items_available' %] >+ <span>There are items available in the library</span> >+ [% CASE 'not_placed' %] >+ <span>Error when placing hold</span> >+ [% CASE %] >+ <span>Error: [% fail | html %]</span> >+ [% END %] >+ </li> >+ [% END %] >+ </ul> >+ </div> >+ [% END %] >+ > [% UNLESS ( multi_hold ) %] > <h2>Place a hold on [% INCLUDE 'biblio-title.inc' link = 1 %] [% IF biblio.author %] by [% biblio.author | html %][% END %]</h2> > [% ELSE %] >@@ -736,9 +786,9 @@ > Hold must be item group level > </span> > [% ELSIF ( itemloo.available ) %] >- <input type="radio" name="checkitem" value="[% itemloo.itemnumber | html %]" /> >+ <input type="checkbox" name="checkitem" value="[% itemloo.itemnumber | html %]" /> > [% ELSIF ( itemloo.override ) %] >- <input type="radio" name="checkitem" class="needsoverride" value="[% itemloo.itemnumber | html %]" /> >+ <input type="checkbox" name="checkitem" class="needsoverride" value="[% itemloo.itemnumber | html %]" /> > <i class="fa fa-exclamation-triangle fa-lg" style="color:gold" title="Requires override of hold policy"/></i> > [% ELSE %] > <span class="error"> >@@ -1507,11 +1557,11 @@ > > if ( ! $("#requestany").is(":checked") ) { > // requestany not selected, go through the item-specific cases >- if ( $('input[type="radio"]:checked').length > 0 ) { >+ if ( $('input[name="checkitem"]:checked').length > 0 ) { > // got item-specific hold requests in the form! > // verify they have a pickup location selected > >- if (table.find('input[type="radio"]:checked') >+ if (table.find('input[name="checkitem"]:checked') > .closest('tr') > .find(".pickup_locations").val() === null) { > >@@ -1602,15 +1652,17 @@ > } > }); > $("input[name=checkitem]").click(function() { >- onechecked = 0; >+ let onechecked = 0; > $("input[name=checkitem]").each(function() { > if(this.checked){ >- onechecked = 1; >+ onechecked++; > } > }); >- if(onechecked == 1){ >+ if(onechecked > 0){ > $("#requestany").prop("checked", false); > $("#holds_to_place_count").prop('disabled', true); >+ >+ $("#holds_to_place_count").val(onechecked); > } else { > $("#requestany").prop("checked",true); > $("#holds_to_place_count").prop('disabled', false); >@@ -1676,10 +1728,10 @@ > > [% IF Koha.Preference('EnableItemGroupHolds') %] > $(':radio[name="item_group_id"]').change(function(){ >- $(':radio[name="checkitem"]').prop('checked', false); >+ $('input[name="checkitem"]').prop('checked', false); > }); > >- $(':radio[name="checkitem"]').change(function(){ >+ $('input[name="checkitem"]').change(function(){ > $(':radio[name="item_group_id"]').prop('checked', false); > }); > [% END %] >diff --git a/reserve/placerequest.pl b/reserve/placerequest.pl >index d2fec975dd..48dd0636c5 100755 >--- a/reserve/placerequest.pl >+++ b/reserve/placerequest.pl >@@ -44,7 +44,7 @@ my $branch = $input->param('pickup'); > my $startdate = $input->param('reserve_date') || ''; > my @rank = $input->multi_param('rank-request'); > my $title = $input->param('title'); >-my $checkitem = $input->param('checkitem'); >+my @checkitems = $input->multi_param('checkitem'); > my $item_group_id = $input->param('item_group_id'); > my $expirationdate = $input->param('expiration_date'); > my $itemtype = $input->param('itemtype') || undef; >@@ -64,43 +64,48 @@ foreach my $bibnum ( @holdable_bibs ) { > $bibinfos{$bibnum} = \%bibinfo; > } > >-my $found; > >-if ( $op eq 'cud-placerequest' && $patron ) { > >+if ( $op eq 'cud-placerequest' && $patron ) { >+ my %failed_holds; > foreach my $biblionumber ( keys %bibinfos ) { > > my $can_override = C4::Context->preference('AllowHoldPolicyOverride'); >- if ( defined $checkitem && $checkitem ne '' ) { >- >- if ( my $item_pickup_location = $input->param("item_pickup_$checkitem") ) { >+ if ( @checkitems ) { >+ for ( my $i = 0; $i < scalar @checkitems; $i++ ){ >+ my $checkitem = $checkitems[$i]; >+ if ( my $item_pickup_location = $input->param("item_pickup_$checkitem") ) { > >- my $item = Koha::Items->find($checkitem); >+ my $item = Koha::Items->find($checkitem); > >- if ( $item->biblionumber ne $biblionumber ) { >- $biblionumber = $item->biblionumber; >- } >- >- my $can_item_be_reserved = CanItemBeReserved($patron, $item, $item_pickup_location)->{status}; >+ if ( $item->biblionumber ne $biblionumber ) { >+ $biblionumber = $item->biblionumber; >+ } > >- if ( $can_item_be_reserved eq 'OK' || ( $can_item_be_reserved ne 'itemAlreadyOnHold' && $can_override ) ) { >- AddReserve( >- { >- branchcode => $item_pickup_location, >- borrowernumber => $patron->borrowernumber, >- biblionumber => $biblionumber, >- priority => $rank[0], >- reservation_date => $startdate, >- expiration_date => $expirationdate, >- notes => $notes, >- title => $title, >- itemnumber => $checkitem, >- found => $found, >- itemtype => $itemtype, >- non_priority => $non_priority, >- } >- ); >+ my $can_item_be_reserved = CanItemBeReserved($patron, $item, $item_pickup_location)->{status}; >+ >+ if ( $can_item_be_reserved eq 'OK' || ( $can_item_be_reserved ne 'itemAlreadyOnHold' && $can_override ) ) { >+ AddReserve( >+ { >+ branchcode => $item_pickup_location, >+ borrowernumber => $patron->borrowernumber, >+ biblionumber => $biblionumber, >+ priority => $rank[$i], >+ reservation_date => $startdate, >+ expiration_date => $expirationdate, >+ notes => $notes, >+ title => $title, >+ itemnumber => $checkitem, >+ found => undef, >+ itemtype => $itemtype, >+ non_priority => $non_priority, >+ } >+ ); > >+ } >+ else { >+ $failed_holds{$can_item_be_reserved} = 1; >+ } > } > } > >@@ -117,8 +122,8 @@ if ( $op eq 'cud-placerequest' && $patron ) { > expiration_date => $expirationdate, > notes => $notes, > title => $bibinfo->{title}, >- itemnumber => $checkitem, >- found => $found, >+ itemnumber => undef, >+ found => undef, > itemtype => $itemtype, > non_priority => $non_priority, > } >@@ -138,8 +143,8 @@ if ( $op eq 'cud-placerequest' && $patron ) { > expiration_date => $expirationdate, > notes => $notes, > title => $title, >- itemnumber => $checkitem, >- found => $found, >+ itemnumber => undef, >+ found => undef, > itemtype => $itemtype, > non_priority => $non_priority, > item_group_id => $item_group_id, >@@ -151,7 +156,12 @@ if ( $op eq 'cud-placerequest' && $patron ) { > } > > my $redirect_url = URI->new("request.pl"); >- $redirect_url->query_form( biblionumber => [@biblionumbers]); >+ my @failed_hold_msgs = (); >+ #NOTE: Deduplicate failed hold reason statuses/codes >+ foreach my $msg (keys %failed_holds){ >+ push(@failed_hold_msgs,$msg); >+ } >+ $redirect_url->query_form( biblionumber => [@biblionumbers], failed_holds => \@failed_hold_msgs); > print $input->redirect($redirect_url); > } > elsif ( $borrowernumber eq '' ) { >diff --git a/reserve/request.pl b/reserve/request.pl >index 36e8eb2aad..023d7de424 100755 >--- a/reserve/request.pl >+++ b/reserve/request.pl >@@ -88,6 +88,7 @@ my $warnings; > my $messages; > my $exceeded_maxreserves; > my $exceeded_holds_per_record; >+my @failed_holds = $input->multi_param('failed_holds'); > > my $op = $input->param('op') || q{}; > >@@ -709,6 +710,8 @@ $template->param( pickup => $pickup || C4::Context->userenv->{branch} ); > > $template->param(borrowernumber => $borrowernumber_hold); > >+$template->param( failed_holds => \@failed_holds ); >+ > # printout the page > output_html_with_http_headers $input, $cookie, $template->output; > >-- >2.30.2
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 15565
:
47527
|
47551
|
47552
|
50068
|
50069
|
50392
|
50393
|
56229
|
56230
|
56231
|
56232
|
56458
|
56510
|
56511
|
56512
|
56513
|
56514
|
56515
|
56517
|
56518
|
56519
|
56520
|
56521
|
56522
|
56523
|
56524
|
61244
|
61245
|
61246
|
61247
|
61248
|
61576
|
61577
|
61578
|
61579
|
61580
|
64590
|
64591
|
64592
|
64593
|
64594
|
66594
|
66595
|
66596
|
66597
|
66598
|
68759
|
68760
|
68761
|
68762
|
68763
|
71643
|
71644
|
71645
|
71646
|
71647
|
71648
|
72644
|
72645
|
72646
|
72647
|
72648
|
72649
|
78242
|
78243
|
78244
|
78245
|
78246
|
78247
|
78248
|
78266
|
78305
|
78417
|
78418
|
78419
|
78420
|
78421
|
78422
|
78423
|
78424
|
78425
|
78426
|
78712
|
78713
|
78714
|
78715
|
78716
|
78717
|
78718
|
78719
|
78720
|
78815
|
78816
|
78817
|
78818
|
78819
|
78820
|
78821
|
78822
|
78823
|
81419
|
81420
|
81421
|
81422
|
81423
|
81424
|
81425
|
81426
|
81427
|
81431
|
81449
|
81570
|
81571
|
81572
|
81573
|
81574
|
81575
|
81576
|
81577
|
81578
|
81579
|
81580
|
81581
|
82205
|
82206
|
82207
|
82208
|
82209
|
82210
|
82211
|
82212
|
82213
|
82214
|
82215
|
82216
|
82220
|
82221
|
83331
|
83332
|
83333
|
83334
|
83335
|
83336
|
83337
|
83338
|
83339
|
83340
|
83341
|
83342
|
83378
|
83380
|
83381
|
84541
|
84542
|
84543
|
84544
|
84545
|
84546
|
84547
|
84548
|
84549
|
84550
|
84551
|
84552
|
84553
|
87979
|
87980
|
87981
|
87982
|
87983
|
87984
|
87985
|
87986
|
87987
|
87988
|
87989
|
87990
|
87991
|
117128
|
117129
|
117130
|
117131
|
117132
|
117133
|
120365
|
120366
|
120367
|
120639
|
120640
|
120641
|
121941
|
122098
|
162071
|
162072
|
162073
|
162074
|
163052
|
163053
|
163054
|
163055
|
163092
|
163093
|
166005
|
166006
|
166007
|
166008
|
166009