Bugzilla – Attachment 117132 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 client
Bug-15565-Place-multiple-holds-on-one-record-on-st.patch (text/plain), 14.88 KB, created by
David Cook
on 2021-02-22 06:43:03 UTC
(
hide
)
Description:
Bug 15565: Place multiple holds on one record on staff client
Filename:
MIME Type:
Creator:
David Cook
Created:
2021-02-22 06:43:03 UTC
Size:
14.88 KB
patch
obsolete
>From 4b31edefb0aa7322ca94f2bd479eba5662620db3 Mon Sep 17 00:00:00 2001 >From: Aleisha Amohia <aleishaamohia@hotmail.com> >Date: Mon, 22 Feb 2021 17:55:22 +1300 >Subject: [PATCH] Bug 15565: Place multiple holds on one record on staff client > >Test plan: >1) Apply patch and restart services >2) Set the maxreserves system preference to 3 >3) Set the following circulation rules: >holds allowed (total) = 10 >holds allowed (daily) = 10 >holds per record (count) = 10 >3) Set up a record with 4 items >4) Go to place a hold on this record >5) Notice that the items table under 'Place a hold on a specific item' >now uses checkboxes instead of radio buttons >6) Check all 4 checkboxes. Confirm that when you check the 4th checkbox, > an alert pops up warning the you've reached the maximum. Confirm > that when you close the alert, the checkbox unchecks itself. >7) Try setting different values for the above circulation rules that are >lower than the number of items on this record. Confirm the alert pops up >as expected. >8) Set the circulation rules and syspref all to 4+. Check some items and >confirm the holds. >9) Confirm that item-level holds are placed on all selected items. > >Sponsored-by: Catalyst IT > >Signed-off-by: David Cook <dcook@prosentient.com.au> >--- > .../prog/en/modules/reserve/request.tt | 45 ++++++++++++++++---- > reserve/placerequest.pl | 48 +++++++++++++--------- > reserve/request.pl | 30 ++++++++++++-- > 3 files changed, 91 insertions(+), 32 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 dc85eff568..a7ae84eb90 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >@@ -471,10 +471,10 @@ > <input type="hidden" name="alreadyreserved" value="[% alreadyreserved | html %]" /> > </li> > >- [% IF remaining_holds_for_record > 1 %] >+ [% IF lowest_value > 1 %] > <li> > <label for="holds_to_place_count">Holds to place (count)</label> >- <input type="text" inputmode="numeric" pattern="[0-9]*" id="holds_to_place_count" name="holds_to_place_count" maxlength="[% remaining_holds_for_record | html %]" value="1" /> >+ <input type="text" inputmode="numeric" pattern="[0-9]*" id="holds_to_place_count" name="holds_to_place_count" maxlength="[% lowest_value | html %]" value="1" /> > </li> > [% ELSE %] > <input type="hidden" name="holds_to_place_count" value="1" /> >@@ -559,9 +559,9 @@ > Hold must be record 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"> >@@ -1015,6 +1015,8 @@ > cannotBeTransferred: _("Cannot be transferred to pickup library") > } > columns_settings_borrowers_table = [% TablesSettings.GetColumns( 'circ', 'circulation', 'table_borrowers', 'json' ) | $raw %]; >+ var MSG_EXCEEDED_MAX_HOLDS = __("Patron reached the maximum number of holds."); >+ var max_holds = "[% lowest_value | $raw %]"; > > $(document).ready(function() { > $('#cancellation-reason-fieldset').hide(); >@@ -1273,23 +1275,48 @@ > if(this.checked){ > $("input[name=checkitem]").each(function() { > $(this).prop("checked", false); >+ $("#holds_to_place_count").val('1'); > }); > } > }); > $("input[name=checkitem]").click(function() { >- onechecked = 0; >+ numchecked = 0; > $("input[name=checkitem]").each(function() { > if(this.checked){ >- onechecked = 1; >+ numchecked++; > } > }); >- if(onechecked == 1){ >- $("#requestany").prop("checked", false); >- $("#holds_to_place_count").prop('disabled', true); >+ if(numchecked > 0){ >+ if ( numchecked > max_holds ) { >+ alert(MSG_EXCEEDED_MAX_HOLDS); >+ $(this).prop('checked',false); >+ } else { >+ $("#requestany").prop("checked", false); >+ $("#holds_to_place_count").prop('disabled', true); >+ $("#holds_to_place_count").val(numchecked); >+ } > } else { > $("#requestany").prop("checked",true); > $("#holds_to_place_count").prop('disabled', false); > } >+ if ( remainingHold - numchecked <= 0 ) { >+ alert(MSG_EXCEEDED_HOLDS_PER_RECORD); >+ [% IF !Koha.Preference('AllowHoldPolicyOverride') %] >+ $('input[name=checkitem]:not(:checked)').attr('disabled','disabled'); >+ [% END %] >+ } >+ if ( remainingHoldsToday - numchecked <= 0 ) { >+ alert(MSG_EXCEEDED_HOLDS_PER_DAY); >+ [% IF !Koha.Preference('AllowHoldPolicyOverride') %] >+ $('input[name=checkitem]:not(:checked)').attr('disabled','disabled'); >+ [% END %] >+ } >+ if ( maxreserves - numchecked <= 0 ) { >+ alert(MSG_EXCEEDED_MAXRESERVES_SYSPREF); >+ [% IF !Koha.Preference('AllowHoldPolicyOverride') %] >+ $('input[name=checkitem]:not(:checked)').attr('disabled','disabled'); >+ [% END %] >+ } > }); > var prev_rank_request; > $("select[name=rank-request]").on("focus", function() { >diff --git a/reserve/placerequest.pl b/reserve/placerequest.pl >index ea81592ef0..48f58a5aa6 100755 >--- a/reserve/placerequest.pl >+++ b/reserve/placerequest.pl >@@ -49,7 +49,7 @@ my $startdate = $input->param('reserve_date') || ''; > my @rank = $input->multi_param('rank-request'); > my $type = $input->param('type'); > my $title = $input->param('title'); >-my $checkitem = $input->param('checkitem'); >+my @checkitems = $input->multi_param('checkitem'); > my $expirationdate = $input->param('expiration_date'); > my $itemtype = $input->param('itemtype') || undef; > my $non_priority = $input->param('non_priority'); >@@ -62,6 +62,7 @@ $biblionumbers ||= $biblionumber . '/'; > > my $bad_bibs = $input->param('bad_bibs'); > my $holds_to_place_count = $input->param('holds_to_place_count') || 1; >+$holds_to_place_count = scalar( @checkitems ) if @checkitems; > > my %bibinfos = (); > my @biblionumbers = split '/', $biblionumbers; >@@ -72,7 +73,16 @@ foreach my $bibnum (@biblionumbers) { > $bibinfos{$bibnum} = \%bibinfo; > } > >-my $found; >+my @found; >+unless ( C4::Context->preference('ReservesNeedReturns') ) { >+ foreach my $checkitem ( @checkitems ) { >+ # if we have an item selected, and the pickup branch is the same as >+ # the holdingbranch of the doc, we force the value $rank and $found >+ $rank[0] = '0'; >+ my $item = Koha::Items->find( $checkitem ); >+ push @found, ( $item->holdingbranch eq $branch ? 'W' : undef ); >+ } >+} > > if ( $type eq 'str8' && $borrower ) { > >@@ -91,14 +101,9 @@ if ( $type eq 'str8' && $borrower ) { > } > > my $can_override = C4::Context->preference('AllowHoldPolicyOverride'); >- if ( defined $checkitem && $checkitem ne '' ) { >- >- my $item = Koha::Items->find($checkitem); >- >- if ( $item->biblionumber ne $biblionumber ) { >- $biblionumber = $item->biblionumber; >- } >- >+ if ( @checkitems and @checkitems == 1 ) { >+ # item-level hold >+ my $item = Koha::Items->find( $checkitems[0] ); > my $can_item_be_reserved = CanItemBeReserved($borrower->{'borrowernumber'}, $item->itemnumber, $branch)->{status}; > > if ( $can_item_be_reserved eq 'OK' || ( $can_item_be_reserved ne 'itemAlreadyOnHold' && $can_override ) ) { >@@ -112,8 +117,8 @@ if ( $type eq 'str8' && $borrower ) { > expiration_date => $expirationdate, > notes => $notes, > title => $title, >- itemnumber => $checkitem, >- found => $found, >+ itemnumber => $checkitems[0], >+ found => $found[0], > itemtype => $itemtype, > non_priority => $non_priority, > } >@@ -121,7 +126,8 @@ if ( $type eq 'str8' && $borrower ) { > > } > >- } elsif (@biblionumbers > 1) { >+ } elsif ( @biblionumbers > 1 ) { >+ # hold on multiple titles (multi-hold) > my $bibinfo = $bibinfos{$biblionumber}; > if ( $can_override || CanBookBeReserved($borrower->{'borrowernumber'}, $biblionumber)->{status} eq 'OK' ) { > AddReserve( >@@ -134,8 +140,8 @@ if ( $type eq 'str8' && $borrower ) { > expiration_date => $expirationdate, > notes => $notes, > title => $bibinfo->{title}, >- itemnumber => $checkitem, >- found => $found, >+ itemnumber => undef, >+ found => undef, > itemtype => $itemtype, > non_priority => $non_priority, > } >@@ -144,20 +150,24 @@ if ( $type eq 'str8' && $borrower ) { > } else { > # place a request on 1st available > for ( my $i = 0 ; $i < $holds_to_place_count ; $i++ ) { >+ my $item; >+ if ( $checkitems[$i] ) { >+ $item = Koha::Items->find( $checkitems[$i] ); >+ } > if ( $can_override || CanBookBeReserved($borrower->{'borrowernumber'}, $biblionumber)->{status} eq 'OK' ) { > AddReserve( > { > branchcode => $branch, > borrowernumber => $borrower->{'borrowernumber'}, >- biblionumber => $biblionumber, >+ biblionumber => ( $item ? $item->biblionumber : $biblionumber ), > priority => $rank[0], > reservation_date => $startdate, > expiration_date => $expirationdate, > notes => $notes, > title => $title, >- itemnumber => $checkitem, >- found => $found, >- itemtype => $itemtype, >+ itemnumber => $checkitems[$i], >+ found => $found[$i], >+ itemtype => ( $item ? $item->effective_itemtype : undef ), > non_priority => $non_priority, > } > ); >diff --git a/reserve/request.pl b/reserve/request.pl >index 38d6f56ed2..c25f2f8ad1 100755 >--- a/reserve/request.pl >+++ b/reserve/request.pl >@@ -30,6 +30,7 @@ use Modern::Perl; > > use CGI qw ( -utf8 ); > use List::MoreUtils qw/uniq/; >+use List::Util qw[min max]; > use Date::Calc qw/Date_to_Days/; > use C4::Output; > use C4::Auth; >@@ -343,11 +344,32 @@ foreach my $biblionumber (@biblionumbers) { > # we must find out what the maximum number of holds they can place for the patron is > my $max_holds_for_record = GetMaxPatronHoldsForRecord( $patron->borrowernumber, $biblionumber ); > my $remaining_holds_for_record = $max_holds_for_record - $holds->count(); >- $biblioloopiter{remaining_holds_for_record} = $max_holds_for_record; >- $template->param( max_holds_for_record => $max_holds_for_record ); >- $template->param( remaining_holds_for_record => $remaining_holds_for_record ); >- } > >+ # Determine how many holds the patron can place per day on this biblio record. >+ # Then calculate how many holds the patron can place subtracting holds already placed today >+ my $today_holds = Koha::Holds->search({ >+ borrowernumber => $patron->borrowernumber, >+ reservedate => dt_from_string->date, >+ })->count; >+ >+ my $biblio_obj = Koha::Biblios->find( $biblionumber ); >+ my $holds_allowed_on_record_today = $biblio_obj->allowed_holds( $patron ); >+ my $remaining_holds_allowed_today = $holds_allowed_on_record_today - $today_holds; >+ my $maxreserves = C4::Context->preference('maxreserves'); >+ >+ $biblioloopiter{remaining_holds_for_record} = $remaining_holds_for_record; >+ $biblioloopiter{remaining_holds_allowed_today} = $remaining_holds_allowed_today; >+ >+ # Determine what is the lowest value >+ my $lowestvalue = min( $maxreserves, $remaining_holds_for_record, $remaining_holds_allowed_today ); >+ >+ $template->param( >+ max_holds_for_record => $max_holds_for_record, >+ remaining_holds_for_record => $remaining_holds_for_record, >+ lowest_value => $lowestvalue, >+ remaining_holds_allowed_today => $remaining_holds_allowed_today, >+ ); >+ } > > my $count = Koha::Holds->search( { biblionumber => $biblionumber } )->count(); > my $totalcount = $count; >-- >2.11.0
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