From 42c5f15b9ffb48cb2be96081861fc2e2c5f7f36d Mon Sep 17 00:00:00 2001 From: Aleisha Amohia Date: Mon, 1 Mar 2021 15:25:52 +1300 Subject: [PATCH] Bug 15516: Relevant controller changes and tests Signed-off-by: Michal Denar --- C4/Reserves.pm | 14 +++++++ Koha/Hold.pm | 21 ++++++++++- Koha/HoldGroup.pm | 63 ++++++++++++++++++++++++++++++++ Koha/HoldGroups.pm | 60 ++++++++++++++++++++++++++++++ Koha/Holds.pm | 15 ++++++++ t/db_dependent/Koha/Holds.t | 73 ++++++++++++++++++++++++++++++++++++- t/db_dependent/Reserves/HoldGroup.t | 53 +++++++++++++++++++++++++++ 7 files changed, 297 insertions(+), 2 deletions(-) create mode 100644 Koha/HoldGroup.pm create mode 100644 Koha/HoldGroups.pm create mode 100644 t/db_dependent/Reserves/HoldGroup.t diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 8941d4f72c..17fc17c6ca 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -189,6 +189,7 @@ sub AddReserve { my $found = $params->{found}; my $itemtype = $params->{itemtype}; my $non_priority = $params->{non_priority}; + my $hold_group_id = $params->{hold_group_id}; $resdate = output_pref( { str => dt_from_string( $resdate ), dateonly => 1, dateformat => 'iso' }) or output_pref({ dt => dt_from_string, dateonly => 1, dateformat => 'iso' }); @@ -253,6 +254,7 @@ sub AddReserve { itemtype => $itemtype, item_level_hold => $checkitem ? 1 : 0, non_priority => $non_priority ? 1 : 0, + hold_group_id => $hold_group_id, } )->store(); $hold->set_waiting() if $found && $found eq 'W'; @@ -1111,6 +1113,12 @@ sub ModReserveFill { logaction( 'HOLDS', 'MODIFY', $hold->reserve_id, Dumper($hold->unblessed) ) if C4::Context->preference('HoldsLog'); + # if this hold was part of a group, cancel other holds in the group + my @holds = Koha::Holds->search({ hold_group_id => $hold->hold_group_id }); + foreach my $h ( @holds ) { + $h->cancel unless $h->reserve_id == $hold->reserve_id; + } + # FIXME Must call Koha::Hold->cancel ? => No, should call ->filled and add the correct log Koha::Old::Hold->new( $hold->unblessed() )->store(); @@ -1214,6 +1222,12 @@ sub ModReserveAffect { # Complete transfer if one exists my $transfer = $hold->item->get_transfer; $transfer->receive if $transfer; + + # if this hold was part of a group, cancel other holds in the group + my @holds = Koha::Holds->search({ hold_group_id => $hold->hold_group_id }); + foreach my $h ( @holds ) { + $h->cancel unless $h->reserve_id == $hold->reserve_id; + } } _FixPriority( { biblionumber => $biblionumber } ); diff --git a/Koha/Hold.pm b/Koha/Hold.pm index 56671f19a8..ae8655bdc7 100644 --- a/Koha/Hold.pm +++ b/Koha/Hold.pm @@ -36,7 +36,7 @@ use Koha::Items; use Koha::Libraries; use Koha::Old::Holds; use Koha::Calendar; - +use Koha::HoldGroups; use Koha::Exceptions::Hold; use base qw(Koha::Object); @@ -623,6 +623,25 @@ sub _set_default_expirationdate { dt_from_string( $self->reservedate )->add( $timeunit => $period ) ); } +=head3 hold_group + + my $hold_group = $hold->hold_group; + my $hold_group_id = $hold_group->id if $hold_group; + +Return the Koha::HoldGroup object of a hold if part of a hold group + +=cut + +sub hold_group { + my ( $self ) = @_; + + if ( $self->hold_group_id ) { + return Koha::HoldGroups->find( $self->hold_group_id ); + } + + return undef; +} + =head3 _move_to_old my $is_moved = $hold->_move_to_old; diff --git a/Koha/HoldGroup.pm b/Koha/HoldGroup.pm new file mode 100644 index 0000000000..08675c48eb --- /dev/null +++ b/Koha/HoldGroup.pm @@ -0,0 +1,63 @@ +package Koha::HoldGroup; + +# Copyright 2020 Koha Development team +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use base qw(Koha::Object); + +=head1 NAME + +Koha::HoldGroup - Koha Hold Group object class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 holds + + $holds = $hold_group->holds + +Return all holds associated with this group + +=cut + +sub holds { + my ($self) = @_; + + my $holds_rs = $self->_result->reserves->search; + return Koha::Holds->_new_from_dbic($holds_rs); +} + +=head3 _type + +=cut + +sub _type { + return 'HoldGroup'; +} + +=head1 AUTHORS + +Josef Moravec + +=cut + +1; diff --git a/Koha/HoldGroups.pm b/Koha/HoldGroups.pm new file mode 100644 index 0000000000..ad96b60704 --- /dev/null +++ b/Koha/HoldGroups.pm @@ -0,0 +1,60 @@ +package Koha::HoldGroups; + +# Copyright Koha Development team 2020 +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Koha::Database; + +use Koha::HoldGroup; + +use base qw(Koha::Objects); + +=head1 NAME + +Koha::HoldGroups - Koha Hold Group object set class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 _type + +=cut + +sub _type { + return 'HoldGroup'; +} + +=head3 object_class + +=cut + +sub object_class { + return 'Koha::HoldGroup'; +} + +=head1 AUTHOR + +Josef Moravec + +=cut + +1; diff --git a/Koha/Holds.pm b/Koha/Holds.pm index 296f99cb0a..ca5b76312f 100644 --- a/Koha/Holds.pm +++ b/Koha/Holds.pm @@ -153,6 +153,21 @@ sub get_items_that_can_fill { ); } +=head3 count_grouped + + $holds->count_grouped(); + +Return number of hold, where hold group is counted as one hold + +=cut + +sub count_grouped { + my ($self) = @_; + my $holds_without_group_count = $self->search({ hold_group_id => undef })->count(); + my $hold_groups_count = $self->search({ hold_group_id => { '!=' => undef }}, { group_by => 'me.hold_group_id' })->count(); + return $holds_without_group_count + $hold_groups_count; +} + =head3 type =cut diff --git a/t/db_dependent/Koha/Holds.t b/t/db_dependent/Koha/Holds.t index 7d19a132f1..07a4015fec 100755 --- a/t/db_dependent/Koha/Holds.t +++ b/t/db_dependent/Koha/Holds.t @@ -19,7 +19,7 @@ use Modern::Perl; -use Test::More tests => 6; +use Test::More tests => 7; use Test::Warn; use C4::Circulation; @@ -500,6 +500,77 @@ subtest 'get_items_that_can_fill' => sub { }; +subtest 'count_grouped' => sub { + plan tests => 3; + $schema->storage->txn_begin; + + my $patron = $builder->build_object({ + class => 'Koha::Patrons', + }); + my $patron_id = $patron->borrowernumber; + + my $hold1 = $builder->build_object({ + class => 'Koha::Holds', + value => { + borrowernumber => $patron_id, + hold_group_id => undef, + }, + }); + + is($patron->holds->count_grouped, 1, 'Test patron has 1 hold.'); + + my $hold_group = $builder->build_object({ + class => 'Koha::HoldGroups', + }); + + my $hold2 = $builder->build_object({ + class => 'Koha::Holds', + value => { + borrowernumber => $patron_id, + hold_group_id => $hold_group->hold_group_id, + } + }); + my $hold3 = $builder->build_object({ + class => 'Koha::Holds', + value => { + borrowernumber => $patron_id, + hold_group_id => $hold_group->hold_group_id, + } + }); + + is($patron->holds->count_grouped, 2, 'Test patron has 2 holds.'); + + my $hold_group2 = $builder->build_object({ + class => 'Koha::HoldGroups', + }); + + my $hold4 = $builder->build_object({ + class => 'Koha::Holds', + value => { + borrowernumber => $patron_id, + hold_group_id => $hold_group2->hold_group_id, + } + }); + my $hold5 = $builder->build_object({ + class => 'Koha::Holds', + value => { + borrowernumber => $patron_id, + hold_group_id => $hold_group2->hold_group_id, + } + }); + my $hold6 = $builder->build_object({ + class => 'Koha::Holds', + value => { + borrowernumber => $patron_id, + hold_group_id => $hold_group2->hold_group_id, + } + }); + + is($patron->holds->count_grouped, 3, 'Test patron has 3 holds.'); + + $schema->storage->txn_rollback; +}; + $schema->storage->txn_rollback; 1; diff --git a/t/db_dependent/Reserves/HoldGroup.t b/t/db_dependent/Reserves/HoldGroup.t new file mode 100644 index 0000000000..4bc4687c79 --- /dev/null +++ b/t/db_dependent/Reserves/HoldGroup.t @@ -0,0 +1,53 @@ +#!/usr/bin/perl + +# Copyright 2020 Koha Development team +# +# This file is part of Koha +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Test::More tests => 1; + +use t::lib::TestBuilder; + +my $schema = Koha::Database->new->schema; +my $builder = t::lib::TestBuilder->new; + +subtest 'holds tests' => sub { + + plan tests => 2; + + $schema->storage->txn_begin; + + my $patron = $builder->build_object({ class => 'Koha::Patrons' }); + my $hold_group = $builder->build_object({ class => 'Koha::HoldGroups' }); + my $hold = $builder->build_object( + { + class => 'Koha::Holds', + value => { + borrowernumber => $patron->borrowernumber, + hold_group_id => $hold_group->hold_group_id, + } + } + ); + + my $holds = $hold_group->holds; + is( ref($holds), 'Koha::Holds', 'Right type' ); + my $hold_from_group = $holds->next; + is( $hold_from_group->id, $hold->id, 'Right object' ); + + $schema->storage->txn_rollback; +}; -- 2.11.0