Bugzilla – Attachment 108461 Details for
Bug 24860
Add ability to place item group level holds
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 24860: Add ability to select a volume when placing a hold
Bug-24860-Add-ability-to-select-a-volume-when-plac.patch (text/plain), 16.57 KB, created by
Kyle M Hall (khall)
on 2020-08-18 11:12:58 UTC
(
hide
)
Description:
Bug 24860: Add ability to select a volume when placing a hold
Filename:
MIME Type:
Creator:
Kyle M Hall (khall)
Created:
2020-08-18 11:12:58 UTC
Size:
16.57 KB
patch
obsolete
>From becfbcc52d8f4ad8083fc88d2892b86cc8bbeeee Mon Sep 17 00:00:00 2001 >From: Kyle M Hall <kyle@bywatersolutions.com> >Date: Fri, 28 Feb 2020 11:32:01 -0500 >Subject: [PATCH] Bug 24860: Add ability to select a volume when placing a hold > >Signed-off-by: Andrew Fuerste-Henry <andrew@bywatersolutions.com> > >Signed-off-by: Rebecca Coert <rcoert@arlingtonva.us> >--- > Koha/Hold.pm | 16 ++++ > Koha/Holds.pm | 3 + > .../prog/en/includes/holds_table.inc | 2 + > .../prog/en/modules/reserve/request.tt | 80 +++++++++++++++++-- > reserve/placerequest.pl | 2 + > reserve/request.pl | 7 ++ > t/db_dependent/Koha/Holds.t | 28 ++++++- > 7 files changed, 130 insertions(+), 8 deletions(-) > >diff --git a/Koha/Hold.pm b/Koha/Hold.pm >index 8969e32839..a285c83a60 100644 >--- a/Koha/Hold.pm >+++ b/Koha/Hold.pm >@@ -291,6 +291,22 @@ sub biblio { > return $self->{_biblio}; > } > >+=head3 volume >+ >+Returns the related Koha::Biblio::Volume object for this hold >+ >+=cut >+ >+sub volume { >+ my ($self) = @_; >+ >+ my $volume_rs = $self->_result->volume; >+ >+ return unless $volume_rs; >+ >+ return Koha::Biblio::Volume->_new_from_dbic($volume_rs); >+} >+ > =head3 item > > Returns the related Koha::Item object for this Hold >diff --git a/Koha/Holds.pm b/Koha/Holds.pm >index 604953d4c9..e34921bcb4 100644 >--- a/Koha/Holds.pm >+++ b/Koha/Holds.pm >@@ -86,6 +86,9 @@ sub forced_hold_level { > my $item_level_count = $self->search( { itemnumber => { '!=' => undef } } )->count(); > return 'item' if $item_level_count > 0; > >+ my $volume_level_count = $self->search( { volume_id => { '!=' => undef } } )->count(); >+ return 'volume' if $volume_level_count > 0; >+ > my $record_level_count = $self->search( { itemnumber => undef } )->count(); > return 'record' if $record_level_count > 0; > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc >index 600977a054..42843652e4 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc >@@ -163,6 +163,8 @@ > [% ELSE %] > [% IF hold.itemtype %] > <i>Next available [% ItemTypes.GetDescription( hold.itemtype ) | html %] item</i> >+ [% ELSIF hold.object.volume_id %] >+ <i>Next available item from volume <strong>[% hold.object.volume.description | html %]</strong></i> > [% ELSE %] > <i>Next available</i> > [% END %] >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 e15d468fcc..3f55728616 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >@@ -455,7 +455,7 @@ > [% UNLESS ( multi_hold ) %] > <li> > <label for="requestany">Hold next available item </label> >- [% IF force_hold_level == 'item' %] >+ [% IF force_hold_level == 'item' || force_hold_level == 'volume' %] > <input type="checkbox" id="requestany" name="request" disabled="true" /> > [% ELSIF force_hold_level == 'record' %] > <input type="checkbox" id="requestany" checked="checked" value="Any" disabled="true"/> >@@ -475,6 +475,41 @@ > [% ELSE %] > <input type="hidden" name="holds_to_place_count" value="1" /> > [% END %] >+ >+ <!-- Volume level holds --> >+ [% FOREACH bibitemloo IN bibitemloop %] >+ [% IF Koha.Preference('EnableVolumeHolds') && bibitemloo.volumes.count %] >+ <label> >+ Hold next available item from a volume >+ [% IF bibitemloo.force_hold_level == 'volume' %] >+ <span class="error"><i>(Required)</i></span> >+ [% END %] >+ </label> >+ >+ [% IF bibitemloo.force_hold_level == 'record' # Patron has placed a record level hold previously for this record %] >+ <span class="error"> >+ <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i> >+ Hold must be record level >+ </span> >+ [% ELSIF bibitemloo.force_hold_level == 'item' # Patron has placed an item level hold previously for this record %] >+ <span class="error"> >+ <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i> >+ Hold must be item level >+ </span> >+ [% ELSE %] >+ [% FOREACH v IN bibitemloo.volumes %] >+ [% IF v.items %] >+ <li> >+ <label for="volume_id">[% v.description | html %]</label> >+ <input type="radio" name="volume_id" value="[% v.id | html %]" /> >+ </li> >+ [% END %] >+ [% END %] >+ [% END %] >+ [% END %] >+ [% END %] >+ <!-- /Volume level holds --> >+ > [% END # /UNLESS multi_hold %] > </ol> > >@@ -523,6 +558,9 @@ > <th>Item type</th> > [% END %] > <th>Barcode</th> >+ [% IF Koha.Preference('EnableVolumeHolds') && bibitemloo.volumes.count %] >+ <th>Volume</th> >+ [% END %] > <th>Home library</th> > <th>Last location</th> > [% IF itemdata_ccode %] >@@ -548,6 +586,11 @@ > <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i> > Hold must be record level > </span> >+ [% ELSIF itemloo.force_hold_level == 'volume' # Patron has placed a volume level hold previously for this record %] >+ <span class="error"> >+ <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i> >+ Hold must be volume level >+ </span> > [% ELSIF ( itemloo.available ) %] > <input type="radio" name="checkitem" value="[% itemloo.itemnumber | html %]" /> > [% ELSIF ( itemloo.override ) %] >@@ -595,6 +638,11 @@ > <td> > [% itemloo.barcode | html %] > </td> >+ [% IF Koha.Preference('EnableVolumeHolds') && bibitemloo.volumes.count %] >+ <td> >+ [% itemloo.object.volume.description | html %] >+ </td> >+ [% END %] > <td> > [% Branches.GetName( itemloo.homebranch ) | html %] > </td> >@@ -1029,6 +1077,8 @@ > }; > if($('input[name="checkitem"]:checked').length) > data.item_id = $('input[name="checkitem"]:checked').val(); >+ if($('input[name="volume_id"]:checked').length) >+ data.volume_id = $('input[name="volume_id"]:checked').val(); > if($('input[name="borrowernumber"]').length) > data.patron_id = $('input[name="borrowernumber"]').val(); > if($('textarea[name="notes"]').length) >@@ -1051,12 +1101,14 @@ > const count = $('input[name="holds_to_place_count"]').length?$('input[name="holds_to_place_count"]').val():1; > biblionumbers.forEach(function(biblionumber) { > data.biblio_id = biblionumber; >+ console.log(data); > let options = { > url: $t.attr('action'), > method: $t.attr('method').toUpperCase(), > contentType: 'application/json', > data: JSON.stringify(data) > }; >+ console.log(options); > for(let i = 0; i < count; i++) { > $.ajax(options) > .then(function(result) { >@@ -1081,8 +1133,8 @@ > }); > > [% UNLESS ( multi_hold ) %] >- $("#hold-request-form").on("submit", function(){ >- return check(); >+ $("#hold-request-form [type='submit']").on("click", function(e){ >+ return check(e); > }); > [% ELSE %] > $("#hold-request-form").on("submit", function(){ >@@ -1092,7 +1144,7 @@ > > }); > >- function check() { >+ function check(e) { > var msg = ""; > var count_reserv = 0; > >@@ -1111,6 +1163,8 @@ > } > } > >+ count_reserv += $("input[name='volume_id']:checked").length; >+ > if (document.form.requestany.checked == true){ > count_reserv++ ; > } >@@ -1123,6 +1177,7 @@ > $('#hold-request-form').preventDoubleFormSubmit(); > return(true); > } else { >+ e.preventDefault(); > alert(msg); > return(false); > } >@@ -1175,14 +1230,14 @@ > }); > $("#requestany").click(function() { > if(this.checked){ >- $("input[name=checkitem]").each(function() { >+ $("input[name=checkitem], input[name='volume_id']").each(function() { > $(this).prop("checked", false); > }); > } > }); >- $("input[name=checkitem]").click(function() { >+ $("input[name=checkitem], input[name='volume_id']").click(function() { > onechecked = 0; >- $("input[name=checkitem]").each(function() { >+ $("input[name=checkitem], input[name='volume_id']").each(function() { > if(this.checked){ > onechecked = 1; > } >@@ -1253,11 +1308,22 @@ > }; > [% END %] > [% END %] >+ > Sticky = $("#toolbar"); > Sticky.hcSticky({ > stickTo: "#existing_holds", > stickyClass: "floating" > }); >+ >+ [% IF Koha.Preference('EnableVolumeHolds') %] >+ $(':radio[name="volume_id"]').change(function(){ >+ $(':radio[name="checkitem"]').attr('checked', false); >+ }); >+ $(':radio[name="checkitem"]').change(function(){ >+ $(':radio[name="volume_id"]').attr('checked', false); >+ }); >+ [% END %] >+ > }); > </script> > [% END %] >diff --git a/reserve/placerequest.pl b/reserve/placerequest.pl >index 0b4a12c206..2381bd7854 100755 >--- a/reserve/placerequest.pl >+++ b/reserve/placerequest.pl >@@ -50,6 +50,7 @@ my @rank = $input->multi_param('rank-request'); > my $type = $input->param('type'); > my $title = $input->param('title'); > my $checkitem = $input->param('checkitem'); >+my $volume_id = $input->param('volume_id'); > my $expirationdate = $input->param('expiration_date'); > my $itemtype = $input->param('itemtype') || undef; > >@@ -155,6 +156,7 @@ if ( $type eq 'str8' && $borrower ) { > itemnumber => $checkitem, > found => $found, > itemtype => $itemtype, >+ volume_id => $volume_id, > } > ); > } >diff --git a/reserve/request.pl b/reserve/request.pl >index 26e40dd685..9f09106099 100755 >--- a/reserve/request.pl >+++ b/reserve/request.pl >@@ -498,6 +498,7 @@ foreach my $biblionumber (@biblionumbers) { > > # checking reserve > my $item_object = Koha::Items->find( $itemnumber ); >+ $item->{object} = $item_object; > my $holds = $item_object->current_holds; > if ( my $first_hold = $holds->next ) { > my $p = Koha::Patrons->find( $first_hold->borrowernumber ); >@@ -626,6 +627,12 @@ foreach my $biblionumber (@biblionumbers) { > } > $template->param( hiddencount => $hiddencount); > >+ if ( C4::Context->preference('EnableVolumeHolds') ) { >+ my $volumes = Koha::Biblio::Volumes->search( >+ { biblionumber => $biblionumber } ); >+ $biblioitem->{volumes} = $volumes; >+ } >+ > push @bibitemloop, $biblioitem; > } > >diff --git a/t/db_dependent/Koha/Holds.t b/t/db_dependent/Koha/Holds.t >index 055dd18d11..a9b4e341dc 100644 >--- a/t/db_dependent/Koha/Holds.t >+++ b/t/db_dependent/Koha/Holds.t >@@ -25,6 +25,7 @@ use Test::Warn; > use C4::Reserves; > use Koha::Holds; > use Koha::Database; >+use Koha::Biblio::Volumes; > > use t::lib::Mocks; > use t::lib::TestBuilder; >@@ -59,7 +60,7 @@ subtest 'DB constraints' => sub { > }; > > subtest 'cancel' => sub { >- plan tests => 12; >+ plan tests => 13; > my $biblioitem = $builder->build_object( { class => 'Koha::Biblioitems' } ); > my $library = $builder->build_object( { class => 'Koha::Libraries' } ); > my $itemtype = $builder->build_object( { class => 'Koha::ItemTypes', value => { rentalcharge => 0 } } ); >@@ -182,6 +183,31 @@ subtest 'cancel' => sub { > is( $hold_old->found, 'W', 'The found column should have been kept and a hold is cancelled' ); > }; > >+ subtest 'Test Koha::Hold::volume' => sub { >+ plan tests => 1; >+ my $patron = $builder->build_object( { class => 'Koha::Patrons' } ); >+ my $volume = $builder->build_object( >+ { >+ class => 'Koha::Biblio::Volumes', >+ value => { biblionumber => $item->biblionumber } >+ } >+ ); >+ my $reserve_id = C4::Reserves::AddReserve( >+ $library->branchcode, $patron->borrowernumber, >+ $item->biblionumber, '', >+ 1, undef, >+ undef, '', >+ "title for fee", $item->itemnumber, >+ 'W', undef, >+ $volume->id >+ ); >+ >+ my $hold = Koha::Holds->find($reserve_id); >+ is( $hold->volume_id, $volume->id, >+ 'Koha::Hold::volume returns the correct volume' ); >+ }; >+ >+ > subtest 'HoldsLog' => sub { > plan tests => 2; > my $patron = $builder->build_object({ class => 'Koha::Patrons' }); >-- >2.24.1 (Apple Git-126)
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 24860
:
100644
|
100645
|
100646
|
100647
|
100648
|
100649
|
100650
|
100651
|
101744
|
101745
|
101746
|
101747
|
101748
|
101749
|
101750
|
101751
|
101827
|
101828
|
101829
|
101830
|
101831
|
101832
|
101833
|
101834
|
101835
|
102230
|
102231
|
102232
|
102233
|
102234
|
102235
|
102236
|
102237
|
102238
|
102239
|
102240
|
102241
|
102242
|
102243
|
102244
|
102245
|
102246
|
102247
|
106589
|
106590
|
106591
|
106592
|
106593
|
106594
|
106595
|
106596
|
106597
|
106682
|
106683
|
106684
|
106685
|
106686
|
106687
|
106688
|
106689
|
106690
|
106742
|
106743
|
106744
|
106745
|
106746
|
106747
|
106748
|
106749
|
106750
|
108458
|
108459
|
108460
|
108461
|
108462
|
108463
|
108464
|
108465
|
108466
|
109097
|
109098
|
109099
|
109100
|
109101
|
109102
|
109103
|
109104
|
109105
|
109171
|
109172
|
109173
|
109174
|
109175
|
109176
|
109177
|
109178
|
109179
|
113616
|
113617
|
113618
|
113619
|
113620
|
113621
|
113622
|
113623
|
113624
|
135922
|
135923
|
135924
|
135925
|
135926
|
135927
|
135928
|
135929
|
135930
|
138221
|
138222
|
138224
|
138225
|
138226
|
138227
|
138228
|
138229
|
138230
|
141214
|
141215
|
141735
|
141736
|
141737
|
141738
|
141739
|
141740
|
141741
|
141742
|
141743
|
141744
|
141745
|
141746
|
141747
|
141748
|
141749
|
141750
|
142413
|
142414
|
142415
|
142416
|
142417
|
142418
|
142419
|
142420
|
142421
|
142422
|
142423
|
142424
|
142425
|
142426
|
142427
|
142428
|
142429
|
142430
|
142827
|
142955
|
142956
|
142957
|
142958
|
142959
|
142960
|
142961
|
142962
|
142963
|
142964
|
142965
|
142966
|
142967
|
142968
|
142969
|
142970
|
142971
|
142972
|
142973
|
142974
|
142975
|
142992
|
142993
|
142994
|
142995
|
142996
|
142997
|
142998
|
142999
|
143000
|
143001
|
143002
|
143003
|
143004
|
143005
|
143006
|
143007
|
143008
|
143009
|
143010
|
143011