@@ -, +, @@
---
Koha/Hold.pm | 16 +++++
Koha/Holds.pm | 3 +
.../intranet-tmpl/prog/en/includes/holds_table.inc | 2 +
.../prog/en/modules/reserve/request.tt | 78 ++++++++++++++++++++--
reserve/placerequest.pl | 2 +
reserve/request.pl | 7 ++
t/db_dependent/Koha/Holds.t | 28 +++++++-
7 files changed, 128 insertions(+), 8 deletions(-)
--- a/Koha/Hold.pm
+++ a/Koha/Hold.pm
@@ -282,6 +282,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
--- a/Koha/Holds.pm
+++ a/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;
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc
+++ a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc
@@ -163,6 +163,8 @@
[% ELSE %]
[% IF hold.itemtype %]
Next available [% ItemTypes.GetDescription( hold.itemtype ) | html %] item
+ [% ELSIF hold.object.volume_id %]
+ Next available item from volume [% hold.object.volume.description | html %]
[% ELSE %]
Next available
[% END %]
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt
@@ -463,7 +463,7 @@
[% UNLESS ( multi_hold ) %]
- [% IF force_hold_level == 'item' %]
+ [% IF force_hold_level == 'item' || force_hold_level == 'volume' %]
[% ELSIF force_hold_level == 'record' %]
@@ -483,6 +483,41 @@
[% ELSE %]
[% END %]
+
+
+ [% FOREACH bibitemloo IN bibitemloop %]
+ [% IF Koha.Preference('EnableVolumeHolds') && bibitemloo.volumes.count %]
+
+
+ [% IF bibitemloo.force_hold_level == 'record' # Patron has placed a record level hold previously for this record %]
+
+
+ Hold must be record level
+
+ [% ELSIF bibitemloo.force_hold_level == 'item' # Patron has placed an item level hold previously for this record %]
+
+
+ Hold must be item level
+
+ [% ELSE %]
+ [% FOREACH v IN bibitemloo.volumes %]
+ [% IF v.items %]
+
+
+
+
+ [% END %]
+ [% END %]
+ [% END %]
+ [% END %]
+ [% END %]
+
+
[% END # /UNLESS multi_hold %]
@@ -531,6 +566,9 @@
Item type
[% END %]
Barcode
+ [% IF Koha.Preference('EnableVolumeHolds') && bibitemloo.volumes.count %]
+
Volume
+ [% END %]
Home library
Last location
[% IF itemdata_ccode %]
@@ -556,6 +594,11 @@
Hold must be record level
+ [% ELSIF itemloo.force_hold_level == 'volume' # Patron has placed a volume level hold previously for this record %]
+
+
+ Hold must be volume level
+
[% ELSIF ( itemloo.available ) %]
[% ELSIF ( itemloo.override ) %]
@@ -603,6 +646,11 @@
[% itemloo.barcode | html %]
+ [% IF Koha.Preference('EnableVolumeHolds') && bibitemloo.volumes.count %]
+
+ [% itemloo.object.volume.description | html %]
+
+ [% END %]
[% Branches.GetName( itemloo.homebranch ) | html %]
@@ -1041,6 +1089,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)
@@ -1060,12 +1110,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) {
@@ -1090,8 +1142,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(){
@@ -1101,7 +1153,7 @@
});
- function check() {
+ function check(e) {
var msg = "";
var count_reserv = 0;
@@ -1120,6 +1172,8 @@
}
}
+ count_reserv += $("input[name='volume_id']:checked").length;
+
if (document.form.requestany.checked == true){
count_reserv++ ;
}
@@ -1132,6 +1186,7 @@
$('#hold-request-form').preventDoubleFormSubmit();
return(true);
} else {
+ e.preventDefault();
alert(msg);
return(false);
}
@@ -1184,14 +1239,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;
}
@@ -1263,6 +1318,15 @@
[% END %]
[% END %]
+ [% 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 %]
+
});
[% END %]
--- a/reserve/placerequest.pl
+++ a/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;
@@ -154,6 +155,7 @@ if ( $type eq 'str8' && $borrower ) {
itemnumber => $checkitem,
found => $found,
itemtype => $itemtype,
+ volume_id => $volume_id,
}
);
}
--- a/reserve/request.pl
+++ a/reserve/request.pl
@@ -499,6 +499,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 );
@@ -628,6 +629,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;
}
--- a/t/db_dependent/Koha/Holds.t
+++ a/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' });
--