Bugzilla – Attachment 60154 Details for
Bug 17712
Move availability calculation to the Koha namespace
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 17712: Item and biblio availability in search context
Bug-17712-Item-and-biblio-availability-in-search-c.patch (text/plain), 29.89 KB, created by
Lari Taskula
on 2017-02-13 12:19:21 UTC
(
hide
)
Description:
Bug 17712: Item and biblio availability in search context
Filename:
MIME Type:
Creator:
Lari Taskula
Created:
2017-02-13 12:19:21 UTC
Size:
29.89 KB
patch
obsolete
>From d86fcf115ab914088b602cf2f08491b579cedecb Mon Sep 17 00:00:00 2001 >From: Lari Taskula <lari.taskula@jns.fi> >Date: Tue, 13 Dec 2016 16:06:26 +0200 >Subject: [PATCH] Bug 17712: Item and biblio availability in search context > >Usage: >my $availability = Koha::Availability::Search->item({ > item => $item, >})->in_opac; >if ($availability->available) { > # yes >} >--- > Koha/Availability/Search.pm | 47 ++++ > Koha/Biblio/Availability/Search.pm | 177 +++++++++++++++ > Koha/Item/Availability/Search.pm | 74 +++++++ > t/db_dependent/Koha/Biblio/Availability/Search.t | 164 ++++++++++++++ > t/db_dependent/Koha/Item/Availability/Search.t | 266 +++++++++++++++++++++++ > 5 files changed, 728 insertions(+) > create mode 100644 Koha/Availability/Search.pm > create mode 100644 Koha/Biblio/Availability/Search.pm > create mode 100644 Koha/Item/Availability/Search.pm > create mode 100644 t/db_dependent/Koha/Biblio/Availability/Search.t > create mode 100644 t/db_dependent/Koha/Item/Availability/Search.t > >diff --git a/Koha/Availability/Search.pm b/Koha/Availability/Search.pm >new file mode 100644 >index 0000000..90b100e >--- /dev/null >+++ b/Koha/Availability/Search.pm >@@ -0,0 +1,47 @@ >+package Koha::Availability::Search; >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# 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 <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Koha::Biblio::Availability::Search; >+use Koha::Item::Availability::Search; >+ >+use Koha::Exceptions; >+ >+sub new { >+ my ($class, $params) = @_; >+ >+ my $self = {}; >+ >+ bless $self, $class; >+} >+ >+sub biblio { >+ my ($self, $params) = @_; >+ >+ return Koha::Biblio::Availability::Search->new($params); >+} >+ >+sub item { >+ my ($self, $params) = @_; >+ >+ return Koha::Item::Availability::Search->new($params); >+} >+ >+1; >diff --git a/Koha/Biblio/Availability/Search.pm b/Koha/Biblio/Availability/Search.pm >new file mode 100644 >index 0000000..9c07450 >--- /dev/null >+++ b/Koha/Biblio/Availability/Search.pm >@@ -0,0 +1,177 @@ >+package Koha::Biblio::Availability::Search; >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# 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 <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use base qw(Koha::Biblio::Availability); >+ >+use Koha::Item::Availability::Search; >+ >+=head1 NAME >+ >+Koha::Biblio::Availability::Search - Koha Biblio Availability Search object class >+ >+=head1 SYNOPSIS >+ >+my $searchability = Koha::Biblio::Availability::Search->new({ >+ biblio => $biblio, # which biblio this availability is for >+}) >+ >+=head1 DESCRIPTION >+ >+Class for checking biblio search availability. >+ >+This class contains subroutines to determine biblio's availability for search >+result in different contexts. >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 new >+ >+Constructs an biblio search availability object. Biblio is always required. >+ >+MANDATORY PARAMETERS >+ >+ biblio (or biblionumber) >+ >+Biblio is a Koha::Biblio -object. >+ >+OPTIONAL PARAMETERS >+ >+Returns a Koha::Biblio::Availability::Search -object. >+ >+=cut >+ >+sub new { >+ my ($class, $params) = @_; >+ >+ my $self = $class->SUPER::new($params); >+ >+ return $self; >+} >+ >+sub in_intranet { >+ my ($self, $params) = @_; >+ >+ $self->reset; >+ >+ # Item looper >+ $self->_item_looper($params); >+ >+ return $self; >+} >+ >+sub in_opac { >+ my ($self, $params) = @_; >+ >+ $self->reset; >+ >+ $params->{'opac'} = 1; >+ >+ # Item looper >+ $self->_item_looper($params); >+ >+ return $self; >+} >+ >+sub _item_looper { >+ my ($self, $params) = @_; >+ >+ my @items = $self->biblio->items; >+ my @hostitemnumbers = C4::Items::get_hostitemnumbers_of($self->biblio->biblionumber); >+ if (@hostitemnumbers) { >+ my @hostitems = Koha::Items->search({ >+ itemnumber => { 'in' => @hostitemnumbers } >+ }); >+ push @items, @hostitems; >+ } >+ >+ if (scalar(@items) == 0) { >+ $self->unavailable(Koha::Exceptions::Biblio::NoAvailableItems->new); >+ return; >+ } >+ >+ my $opac = $params->{'opac'} ? 1:0; >+ my $hidelostitems = 0; >+ if (!$opac) { >+ $hidelostitems = C4::Context->preference('hidelostitems'); >+ } >+ >+ # Stop calculating item availabilities after $limit available items are found. >+ # E.g. parameter 'limit' with value 1 will find only one available item and >+ # return biblio as available if no other unavailabilities are found. If you >+ # want to calculate availability of every item in this biblio, do not give this >+ # parameter. >+ my $limit = $params->{'limit'}; >+ my $avoid_queries_after = >+ C4::Context->preference('MaxSearchResultsItemsPerRecordStatusCheck'); >+ my $count = 0; >+ foreach my $item (@items) { >+ # Break out of loop after $limit items are found available >+ if (defined $limit && @{$self->{'item_availabilities'}} >= $limit) { >+ last; >+ } >+ >+ my $item_availability = Koha::Item::Availability::Search->new({ >+ item => $item, >+ }); >+ if ($count >= $avoid_queries_after) { >+ # A couple heuristics to limit how many times >+ # we query the database for item transfer information, sacrificing >+ # accuracy in some cases for speed; >+ # >+ # 1. don't query if item has one of the other statuses (done inside >+ # item availability calculation) >+ # 2. don't check holds status if ignore_holds parameter is given >+ # 3. don't check transfer status if ignore_transfer parameter is given >+ $params->{'ignore_holds'} = 1; >+ $params->{'ignore_transfer'} = 1; >+ } >+ if ($opac) { >+ $item_availability = $item_availability->in_opac($params); >+ my $unavails = $item_availability->unavailabilities; >+ # Hide item in OPAC context if system preference hidelostitems is >+ # enabled. >+ my $lost = exists $unavails->{'Koha::Exceptions::Item::Lost'}; >+ if ($hidelostitems && $lost) { >+ next; >+ } >+ } else { >+ $item_availability = $item_availability->in_intranet($params); >+ } >+ if ($item_availability->available) { >+ push $self->{'item_availabilities'}, $item_availability; >+ } else { >+ push $self->{'item_unavailabilities'}, $item_availability; >+ } >+ $count++; >+ } >+ >+ # After going through items, if none are found available, set the biblio >+ # unavailable >+ if (@{$self->{'item_availabilities'}} == 0) { >+ $self->unavailable(Koha::Exceptions::Biblio::NoAvailableItems->new); >+ } >+ >+ return $self; >+} >+ >+1; >diff --git a/Koha/Item/Availability/Search.pm b/Koha/Item/Availability/Search.pm >new file mode 100644 >index 0000000..abb0767 >--- /dev/null >+++ b/Koha/Item/Availability/Search.pm >@@ -0,0 +1,74 @@ >+package Koha::Item::Availability::Search; >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# 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 <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use base qw(Koha::Item::Availability); >+ >+use Koha::Availability::Checks::Item; >+ >+sub new { >+ my ($class, $params) = @_; >+ >+ my $self = $class->SUPER::new($params); >+ >+ return $self; >+} >+ >+sub in_opac { >+ my ($self, $params) = @_; >+ my $reason; >+ >+ $self->reset; >+ >+ my $item = $self->item; >+ >+ my $itemcalc = Koha::Availability::Checks::Item->new($item); >+ $self->unavailable($reason) if $reason = $itemcalc->lost; >+ $self->unavailable($reason) if $reason = $itemcalc->damaged; >+ $self->unavailable($reason) if $reason = $itemcalc->from_another_library; >+ $self->unavailable($reason) if $reason = $itemcalc->notforloan; >+ $self->unavailable($reason) if $reason = $itemcalc->restricted; >+ $self->unavailable($reason) if $reason = $itemcalc->unknown_barcode; >+ $self->unavailable($reason) if $reason = $itemcalc->withdrawn; >+ $self->unavailable($reason) if $reason = $itemcalc->onloan; >+ >+ if (!$params->{'ignore_holds'} && $self->available) { >+ $self->unavailable($reason) if $reason = $itemcalc->held; >+ } >+ if (!$params->{'ignore_transfer'} && $self->available) { >+ $self->unavailable($reason) if $reason = $itemcalc->transfer; >+ } >+ >+ return $self; >+} >+ >+sub in_intranet { >+ my ($self, $params) = @_; >+ >+ # TODO: >+ # Do we want to show some additional information in intranet context? >+ # Perhaps make some additional checks, or override some unavailabilities >+ # found in OPAC. >+ # >+ # For now, just run the same checks as OPAC context. >+ return $self->in_opac($params); >+} >+ >+1; >diff --git a/t/db_dependent/Koha/Biblio/Availability/Search.t b/t/db_dependent/Koha/Biblio/Availability/Search.t >new file mode 100644 >index 0000000..9d876e1 >--- /dev/null >+++ b/t/db_dependent/Koha/Biblio/Availability/Search.t >@@ -0,0 +1,164 @@ >+#!/usr/bin/perl >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# 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 <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use Test::More tests => 4; >+use t::lib::Mocks; >+use t::lib::TestBuilder; >+require t::db_dependent::Koha::Availability::Helpers; >+use Benchmark; >+ >+use Koha::Database; >+use Koha::IssuingRules; >+use Koha::Items; >+use Koha::ItemTypes; >+ >+use Koha::Availability::Search; >+use Koha::Biblio::Availability::Search; >+ >+my $schema = Koha::Database->new->schema; >+$schema->storage->txn_begin; >+ >+my $builder = t::lib::TestBuilder->new; >+ >+set_default_system_preferences(); >+set_default_circulation_rules(); >+ >+subtest 'Biblio with zero available items' => \&t_no_available_items; >+sub t_no_available_items { >+ plan tests => 6; >+ >+ my $item1 = build_a_test_item(); >+ my $biblio = Koha::Biblios->find($item1->biblionumber); >+ my $item2 = build_a_test_item(); >+ $item2->biblionumber($biblio->biblionumber)->store; >+ $item2->biblioitemnumber($item1->biblioitemnumber)->store; >+ $item1->withdrawn('1')->store; >+ $item2->notforloan('1')->store; >+ my $patron = build_a_test_patron(); >+ >+ my $availability = Koha::Biblio::Availability::Search->new({ >+ biblio => $biblio, >+ })->in_opac; >+ my $expecting = 'Koha::Exceptions::Biblio::NoAvailableItems'; >+ >+ ok(!Koha::Item::Availability::Search->new({ >+ item => $item1, >+ })->in_opac->available, >+ 'When I look at the first item of two in this biblio, it is not available.'); >+ ok(!Koha::Item::Availability::Search->new({ >+ item => $item2 >+ })->in_opac->available, >+ 'When I look at the second item of two in this biblio, it is not available.'); >+ ok(!$availability->available, 'Then, the biblio is not available.'); >+ is($availability->unavailable, 1, 'Then, there is exactly one reason for unavailability.'); >+ is(ref($availability->unavailabilities->{$expecting}), $expecting, 'The reason says there are no' >+ .' available items in this biblio.'); >+ is(@{$availability->item_unavailabilities}, 2, 'There seems to be two items that are unavailable.'); >+}; >+ >+subtest 'Biblio with one available items out of two' => \&t_one_out_of_two_items_available; >+sub t_one_out_of_two_items_available { >+ plan tests => 5; >+ >+ my $item1 = build_a_test_item(); >+ my $biblio = Koha::Biblios->find($item1->biblionumber); >+ my $item2 = build_a_test_item(); >+ $item2->biblionumber($biblio->biblionumber)->store; >+ $item2->biblioitemnumber($item1->biblioitemnumber)->store; >+ >+ my $patron = build_a_test_patron(); >+ $item1->withdrawn('1')->store; >+ >+ my $availability = Koha::Biblio::Availability::Search->new({biblio => $biblio})->in_opac; >+ my $item_availabilities = $availability->item_availabilities; >+ ok(!Koha::Item::Availability::Search->new({ item => $item1,})->in_opac->available, >+ 'When I look at the first item of two in this biblio, it is not available.'); >+ ok(Koha::Item::Availability::Search->new({ item => $item2,})->in_opac->available, >+ 'When I look at the second item of two in this biblio, it seems to be available.'); >+ ok($availability->available, 'Then, the biblio is available.'); >+ is(@{$item_availabilities}, 1, 'There seems to be one available item in this biblio.'); >+ is($item_availabilities->[0]->item->itemnumber, $item2->itemnumber, 'Then the only available item' >+ .' is the second item of this biblio.'); >+}; >+ >+subtest 'Biblio with two items out of two available' => \&t_all_items_available; >+sub t_all_items_available { >+ plan tests => 4; >+ >+ my $item1 = build_a_test_item(); >+ my $biblio = Koha::Biblios->find($item1->biblionumber); >+ my $item2 = build_a_test_item(); >+ $item2->biblionumber($biblio->biblionumber)->store; >+ $item2->biblioitemnumber($item1->biblioitemnumber)->store; >+ >+ my $patron = build_a_test_patron(); >+ >+ my $availability = Koha::Biblio::Availability::Search->new({biblio => $biblio})->in_opac; >+ my $item_availabilities = $availability->item_availabilities; >+ ok(Koha::Item::Availability::Search->new({ item => $item1,})->in_opac->available, >+ 'When I look at the first item of two in this biblio, it seems to be available.'); >+ ok(Koha::Item::Availability::Search->new({ item => $item2,})->in_opac->available, >+ 'When I look at the second item of two in this biblio, it seems to be available.'); >+ ok($availability->available, 'Then, the biblio is available.'); >+ is(@{$item_availabilities}, 2, 'There seems to be two available items in this biblio.'); >+}; >+ >+subtest 'Prove that lower MaxSearchResultsItemsPerRecordStatusCheck boosts performance' => \&t_performance_proof; >+sub t_performance_proof { >+ plan tests => 6; >+ >+ my $item = build_a_test_item(); >+ my $biblio = Koha::Biblios->find($item->biblionumber); >+ my $biblioitem = Koha::Biblioitems->find($item->biblioitemnumber); >+ >+ # add some items to biblio >+ my $count1 = 20; >+ my $count2 = 200; >+ for my $i (1..($count2-1)) { # one already built earlier >+ build_a_test_item($biblio, $biblioitem); >+ } >+ >+ my $availability_iterations = 10; >+ my @items = $biblio->items; >+ is(@items, $count2, "We will get availability for $count2 items."); >+ t::lib::Mocks::mock_preference('MaxSearchResultsItemsPerRecordStatusCheck', >+ $count1); >+ is(C4::Context->preference('MaxSearchResultsItemsPerRecordStatusCheck'), >+ $count1, "First test will be done with" >+ ." MaxSearchResultsItemsPerRecordStatusCheck = $count1"); >+ my $res1 = timethis($availability_iterations, sub { >+ Koha::Availability::Search->new->biblio({ biblio => $biblio })->in_opac; >+ }); >+ ok($res1, "Calculated search availability $availability_iterations times."); >+ t::lib::Mocks::mock_preference('MaxSearchResultsItemsPerRecordStatusCheck', >+ $count2); >+ is(C4::Context->preference('MaxSearchResultsItemsPerRecordStatusCheck'), >+ $count2, "Second test will be done with" >+ ." MaxSearchResultsItemsPerRecordStatusCheck = $count2"); >+ my $res2 = timethis($availability_iterations, sub { >+ Koha::Availability::Search->new->biblio({ biblio => $biblio })->in_opac; >+ }); >+ ok($res2, "Calculated search availability $availability_iterations times."); >+ ok($res1->cpu_a < $res2->cpu_a, 'First test was faster than second.'); >+}; >+ >+$schema->storage->txn_rollback; >+ >+1; >diff --git a/t/db_dependent/Koha/Item/Availability/Search.t b/t/db_dependent/Koha/Item/Availability/Search.t >new file mode 100644 >index 0000000..0f63446 >--- /dev/null >+++ b/t/db_dependent/Koha/Item/Availability/Search.t >@@ -0,0 +1,266 @@ >+#!/usr/bin/perl >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# 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 t1hat 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 <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use Test::More tests => 10; >+use t::lib::Mocks; >+use t::lib::TestBuilder; >+require t::db_dependent::Koha::Availability::Helpers; >+ >+use Koha::Database; >+use Koha::IssuingRules; >+use Koha::Items; >+use Koha::ItemTypes; >+ >+use Koha::Item::Availability::Search; >+ >+my $schema = Koha::Database->new->schema; >+$schema->storage->txn_begin; >+ >+my $builder = t::lib::TestBuilder->new; >+ >+set_default_system_preferences(); >+set_default_circulation_rules(); >+ >+subtest 'Given item is in a good state for availability' => \&t_ok_availability; >+sub t_ok_availability { >+ plan tests => 3; >+ >+ my $patron = build_a_test_patron(); >+ my $item = build_a_test_item(); >+ my $availability = Koha::Item::Availability::Search->new({item => $item})->in_opac; >+ >+ ok($availability->available, 'When I request availability, then the item is available.'); >+ ok(!$availability->confirm, 'Then nothing needs to be confirmed.'); >+ ok(!$availability->unavailable, 'Then there are no reasons to be unavailable.'); >+} >+ >+subtest 'Given item is damaged' => sub { >+ plan tests => 2; >+ >+ subtest 'Given AllowHoldsOnDamagedItems is disabled' => \&t_damaged_item_allow_disabled; >+ subtest 'Given AllowHoldsOnDamagedItems is enabled' => \&t_damaged_item_allow_enabled; >+ sub t_damaged_item_allow_disabled { >+ plan tests => 4; >+ >+ t::lib::Mocks::mock_preference('AllowHoldsOnDamagedItems', 0); >+ >+ my $patron = build_a_test_patron(); >+ my $item = build_a_test_item()->set({damaged=>1})->store; >+ my $availability = Koha::Item::Availability::Search->new({item => $item})->in_opac; >+ my $expecting = 'Koha::Exceptions::Item::Damaged'; >+ >+ is($item->damaged, 1, 'When I look at the item, I see that it is damaged.'); >+ ok(!$availability->available, 'When I request availability, then the item is not available.'); >+ is($availability->unavailable, 1, 'Then there is only one unavailability reason.'); >+ is(ref($availability->unavailabilities->{$expecting}), $expecting, >+ 'Then there is an unavailability status indicating damaged item.'); >+ }; >+ sub t_damaged_item_allow_enabled { >+ plan tests => 4; >+ >+ t::lib::Mocks::mock_preference('AllowHoldsOnDamagedItems', 1); >+ >+ my $patron = build_a_test_patron(); >+ my $item = build_a_test_item()->set({damaged=>1})->store; >+ my $availability = Koha::Item::Availability::Search->new({item => $item})->in_opac; >+ >+ is($item->damaged, 1, 'When I look at the item, I see that it is damaged.'); >+ ok($availability->available, 'When I request availability, then the item is available.'); >+ ok(!$availability->unavailable, 'Then there are no statuses for unavailability.'); >+ ok(!$availability->confirm, 'Then there is no reason to have availability confirmed.'); >+ }; >+}; >+ >+subtest 'Given item is lost' => \&t_lost; >+sub t_lost { >+ plan tests => 4; >+ >+ my $patron = build_a_test_patron(); >+ my $item = build_a_test_item()->set({itemlost=>1})->store; >+ my $availability = Koha::Item::Availability::Search->new({item => $item})->in_opac; >+ my $expecting = 'Koha::Exceptions::Item::Lost'; >+ >+ is($item->itemlost, 1, 'When I try to look at the item, I find out that it is lost.'); >+ ok(!$availability->available, 'When I request availability, then the item is not available.'); >+ is($availability->unavailable, 1, 'Then there is only one unavailability reason.'); >+ is(ref($availability->unavailabilities->{$expecting}), $expecting, >+ 'Then there is an unavailability status indicating lost item.'); >+}; >+ >+subtest 'Given item is not for loan' => \&t_notforloan; >+sub t_notforloan { >+ plan tests => 4; >+ >+ my $patron = build_a_test_patron(); >+ my $item = build_a_test_item()->set({notforloan=>1})->store; >+ my $availability = Koha::Item::Availability::Search->new({item => $item})->in_opac; >+ my $expecting = 'Koha::Exceptions::Item::NotForLoan'; >+ >+ is($item->notforloan, 1, 'When I look at the item, I see that it is not for loan.'); >+ ok(!$availability->available, 'When I request availability, then the item is not available.'); >+ is($availability->unavailable, 1, 'Then there is only one unavailability reason.'); >+ is(ref($availability->unavailabilities->{$expecting}), $expecting, >+ 'Then there is an unavailability status indicating the item is not for loan.'); >+}; >+ >+subtest 'Given item type is not for loan' => sub { >+ >+ subtest 'Given item-level_itypes is on (item-itemtype)' => \&t_itemlevel_itemtype_notforloan_item_level_itypes_on; >+ subtest 'Given item-level_itypes is off (biblioitem-itemtype)' => \&t_itemlevel_itemtype_notforloan_item_level_itypes_off; >+ sub t_itemlevel_itemtype_notforloan_item_level_itypes_on { >+ plan tests => 5; >+ >+ t::lib::Mocks::mock_preference('item-level_itypes', 1); >+ >+ my $patron = build_a_test_patron(); >+ my $item = build_a_test_item(); >+ my $biblioitem = Koha::Biblioitems->find($item->biblioitemnumber); >+ my $itemtype = Koha::ItemTypes->find($item->itype); >+ $itemtype->set({notforloan=>1})->store; >+ my $availability = Koha::Item::Availability::Search->new({item => $item})->in_opac; >+ my $expecting = 'Koha::Exceptions::ItemType::NotForLoan'; >+ >+ is(Koha::ItemTypes->find($biblioitem->itemtype)->notforloan, 0, 'Biblioitem itemtype is for loan.'); >+ is(Koha::ItemTypes->find($item->itype)->notforloan, 1, 'Item itemtype is not for loan.'); >+ ok(!$availability->available, 'When I request availability, then the item is not available.'); >+ is($availability->unavailable, 1, 'Then there is only one unavailability reason.'); >+ is(ref($availability->unavailabilities->{$expecting}), $expecting, >+ "Then there is an unavailability status indicating the itemtype is not forloan."); >+ }; >+ sub t_itemlevel_itemtype_notforloan_item_level_itypes_off { >+ plan tests => 5; >+ >+ t::lib::Mocks::mock_preference('item-level_itypes', 0); >+ >+ my $patron = build_a_test_patron(); >+ my $item = build_a_test_item(); >+ my $biblioitem = Koha::Biblioitems->find($item->biblioitemnumber); >+ my $itemtype = Koha::ItemTypes->find($biblioitem->itemtype); >+ $itemtype->set({notforloan=>1})->store; >+ my $availability = Koha::Item::Availability::Search->new({item => $item})->in_opac; >+ my $expecting = 'Koha::Exceptions::ItemType::NotForLoan'; >+ >+ is(Koha::ItemTypes->find($biblioitem->itemtype)->notforloan, 1, 'Biblioitem itemtype is not for loan.'); >+ is(Koha::ItemTypes->find($item->itype)->notforloan, 0, 'Item itemtype is for loan.'); >+ ok(!$availability->available, 'When I request availability, then the item is not available.'); >+ is($availability->unavailable, 1, 'Then there is only one unavailability reason.'); >+ is(ref($availability->unavailabilities->{$expecting}), $expecting, >+ "Then there is an unavailability status indicating the itemtype is not forloan."); >+ }; >+}; >+ >+subtest 'Given item is ordered' => \&t_ordered; >+sub t_ordered { >+ plan tests => 4; >+ >+ my $patron = build_a_test_patron(); >+ my $item = build_a_test_item()->set({notforloan=>-1})->store; >+ my $availability = Koha::Item::Availability::Search->new({item => $item})->in_opac; >+ my $expecting = 'Koha::Exceptions::Item::NotForLoan'; >+ >+ ok(!$availability->available, 'When I request availability, then the item is not available.'); >+ ok($availability->unavailable, 'Then there is one reason for unavailability.'); >+ is(ref($availability->unavailabilities->{$expecting}), $expecting, >+ 'Then the unavailability status is indicating not for loan status.'); >+ is($availability->unavailabilities->{$expecting}->code, 'Ordered', 'Not for loan code says the item is ordered.') >+}; >+ >+subtest 'Given item is restricted' => \&t_restricted; >+sub t_restricted { >+ plan tests => 4; >+ >+ my $patron = build_a_test_patron(); >+ my $item = build_a_test_item()->set({restricted=>1})->store; >+ my $availability = Koha::Item::Availability::Search->new({item => $item})->in_opac; >+ my $expecting = 'Koha::Exceptions::Item::Restricted'; >+ >+ is($item->restricted, 1, 'When I look at the item, I see that it is restricted.'); >+ ok(!$availability->available, 'When I request availability, then the item is not available.'); >+ is($availability->unavailable, 1, 'Then there is only one unavailability reason.'); >+ is(ref($availability->unavailabilities->{$expecting}), $expecting, >+ 'Then there is an unavailability status indicating restricted item.'); >+}; >+ >+subtest 'Given item has no barcode' => \&t_unknown_barcode; >+sub t_unknown_barcode { >+ plan tests => 4; >+ >+ my $patron = build_a_test_patron(); >+ my $item = build_a_test_item()->set({barcode=>undef})->store; >+ my $expecting = 'Koha::Exceptions::Item::UnknownBarcode'; >+ my $availability = Koha::Item::Availability::Search->new({item => $item})->in_opac; >+ >+ is($item->barcode, undef, 'When I look at the item, we see that it has undefined barcode.'); >+ ok($availability->unavailable, 'When I request availability, then the item is not available.'); >+ is($availability->unavailable, 1, 'Then there is only one unavailability reason.'); >+ is(ref($availability->unavailabilities->{$expecting}), $expecting, >+ 'Then there is an unavailability status indicating unknown barcode.'); >+}; >+ >+subtest 'Given item is withdrawn' => \&t_withdrawn; >+sub t_withdrawn { >+ plan tests => 4; >+ >+ my $patron = build_a_test_patron(); >+ my $item = build_a_test_item()->set({restricted=>1})->store; >+ my $availability = Koha::Item::Availability::Search->new({item => $item})->in_opac; >+ my $expecting = 'Koha::Exceptions::Item::Restricted'; >+ >+ is($item->restricted, 1, 'When I look at the item, I see that it is restricted.'); >+ ok(!$availability->available, 'When I request availability, then the item is not available.'); >+ is($availability->unavailable, 1, 'Then there is only one unavailability reason.'); >+ is(ref($availability->unavailabilities->{$expecting}), $expecting, >+ 'Then there is an unavailability status indicating restricted item.'); >+}; >+ >+subtest 'Held' => \&t_held; >+sub t_held { >+ plan tests => 8; >+ >+ my $patron = build_a_test_patron(); >+ my $item = build_a_test_item(); >+ my $reserve_id = add_item_level_hold($item, $patron, $item->homebranch); >+ my $hold = Koha::Holds->find({ borrowernumber => $patron->borrowernumber }); >+ Koha::IssuingRules->search->delete; >+ my $rule = Koha::IssuingRule->new({ >+ branchcode => $item->homebranch, >+ itemtype => $item->effective_itemtype, >+ categorycode => $patron->categorycode, >+ holds_per_record => 9001, >+ reservesallowed => 9001, >+ opacitemholds => 'Y', >+ })->store; >+ my $availability = Koha::Item::Availability::Search->new({item => $item})->in_opac; >+ my $expecting = 'Koha::Exceptions::Item::Held'; >+ >+ is($rule->reservesallowed, 9001, 'As I look at circulation rules, I can see that many reserves are allowed.'); >+ ok($reserve_id, 'I have placed a hold on an item.'); >+ is($hold->itemnumber, $item->itemnumber, 'The item I have hold for is the same item I will check availability for.'); >+ ok(!$availability->available, 'When I request availability, then the item is not available.'); >+ ok(!$availability->confirm, 'Then there is nothing to be confirmed.'); >+ ok(!$availability->note, 'Then there are no additional notes.'); >+ is($availability->unavailable, 1, 'Then there is only one reason for unavailability.'); >+ is(ref($availability->unavailabilities->{$expecting}), $expecting, >+ 'Then there is an unavailability status indicating that I have already held this.'); >+}; >+ >+$schema->storage->txn_rollback; >+ >+1; >-- >1.9.1
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 17712
:
57921
|
57923
|
58446
|
58447
|
58449
|
58450
|
58451
|
58452
|
58453
|
58454
|
60147
|
60148
|
60149
|
60150
|
60151
|
60152
|
60153
|
60154
|
60261
|
60262
|
60263
|
60264
|
60265
|
62719
|
62720
|
62721
|
62722
|
62723
|
62724
|
62725
|
62726
|
63343
|
63344
|
63345
|
63346
|
63347
|
63348
|
63349
|
63350
|
84830
|
84831
|
84832
|
84833
|
84834
|
84835
|
84836
|
84837
|
84838
|
84839