@@ -, +, @@ - filter_out_lost handle that). $ kshell k$ prove t/db_dependent/Koha/Items.t --- Koha/Items.pm | 65 ++++++++++++---- t/db_dependent/Koha/Items.t | 147 +++++++++++++++++++++++++++++++++++- 2 files changed, 195 insertions(+), 17 deletions(-) --- a/Koha/Items.pm +++ a/Koha/Items.pm @@ -52,9 +52,15 @@ sub filter_by_for_loan { =head3 filter_by_visible_in_opac - my $filered_items = $items->filter_by_visible_in_opac; + my $filered_items = $items->filter_by_visible_in_opac( + { + [ patron => $patron ] + } + ); + +Returns a new resultset, containing those items that are not expected to be hidden in OPAC +for the passed I object that is passed. -Returns a new resultset, containing those items that are not expected to be hidden in OPAC. The I and I system preferences are honoured. =cut @@ -62,6 +68,33 @@ The I and I system preferences are honoured. sub filter_by_visible_in_opac { my ($self, $params) = @_; + my $patron = $params->{patron}; + + my $result = $self; + + unless ( $patron and $patron->category->override_hidden_items ) { + $result = $result->filter_out_opachiddenitems; + } + + if (C4::Context->preference('hidelostitems')) { + $result = $result->filter_out_lost; + } + + return $result; +} + +=head3 filter_out_opachiddenitems + + my $filered_items = $items->filter_out_opachiddenitems; + +Returns a new resultset, containing those items that are not expected to be hidden in OPAC. +The I system preference is honoured. + +=cut + +sub filter_out_opachiddenitems { + my ($self) = @_; + my $rules = C4::Context->yaml_preference('OpacHiddenItems') // {}; my $rules_params; @@ -69,21 +102,23 @@ sub filter_by_visible_in_opac { $rules_params->{$field}->{'-not_in'} = $rules->{$field}; } - my $itemlost_params; - $itemlost_params = { itemlost => 0 } - if C4::Context->preference('hidelostitems'); + return $self->search( $rules_params ); +} - my $search_params; - if ( $rules_params and $itemlost_params ) { - $search_params = { - '-and' => [ $rules_params, $itemlost_params ] - }; - } - else { - $search_params = $rules_params // $itemlost_params; - } +=head3 filter_out_lost + + my $filered_items = $items->filter_out_lost; + +Returns a new resultset, containing those items that are not marked as lost. + +=cut + +sub filter_out_lost { + my ($self) = @_; + + my $params = { itemlost => 0 }; - return $self->search( $search_params ); + return $self->search( $params ); } =head2 Internal methods --- a/t/db_dependent/Koha/Items.t +++ a/t/db_dependent/Koha/Items.t @@ -19,7 +19,9 @@ use Modern::Perl; -use Test::More tests => 13; +use Test::More tests => 15; + +use Test::MockModule; use Test::Exception; use Time::Fake; @@ -1321,10 +1323,17 @@ $schema->storage->txn_rollback; subtest 'filter_by_visible_in_opac() tests' => sub { - plan tests => 8; + plan tests => 11; $schema->storage->txn_begin; + my $patron = $builder->build_object({ class => 'Koha::Patrons' }); + my $mocked_category = Test::MockModule->new('Koha::Patron::Category'); + my $exception = 1; + $mocked_category->mock( 'override_hidden_items', sub { + return $exception; + }); + # have a fresh biblio my $biblio = $builder->build_sample_biblio; # have two itemtypes @@ -1391,6 +1400,9 @@ subtest 'filter_by_visible_in_opac() tests' => sub { is( $biblio->items->filter_by_visible_in_opac->count, 6, 'No rules passed, hidelostitems unset' ); + is( $biblio->items->filter_by_visible_in_opac({ patron => $patron })->count, + 6, 'No rules passed, hidelostitems unset, patron exception changes nothing' ); + $rules = {}; t::lib::Mocks::mock_preference( 'hidelostitems', 1 ); @@ -1400,6 +1412,12 @@ subtest 'filter_by_visible_in_opac() tests' => sub { 'No rules passed, hidelostitems set' ); + is( + $biblio->items->filter_by_visible_in_opac({ patron => $patron })->count, + 3, + 'No rules passed, hidelostitems set, patron exception changes nothing' + ); + $rules = { withdrawn => [ 1, 2 ] }; is( $biblio->items->filter_by_visible_in_opac->count, @@ -1407,6 +1425,12 @@ subtest 'filter_by_visible_in_opac() tests' => sub { 'Rules on withdrawn, hidelostitems set' ); + is( + $biblio->items->filter_by_visible_in_opac({ patron => $patron })->count, + 3, + 'hidelostitems set, rules on withdrawn but patron override passed' + ); + $rules = { itype => [ $itype_1->itemtype ] }; is( $biblio->items->filter_by_visible_in_opac->count, @@ -1442,3 +1466,122 @@ subtest 'filter_by_visible_in_opac() tests' => sub { $schema->storage->txn_rollback; }; + +subtest 'filter_out_lost() tests' => sub { + + plan tests => 2; + + $schema->storage->txn_begin; + + # have a fresh biblio + my $biblio = $builder->build_sample_biblio; + # have 3 items on that biblio + my $item_1 = $builder->build_sample_item( + { + biblionumber => $biblio->biblionumber, + itemlost => -1, + } + ); + my $item_2 = $builder->build_sample_item( + { + biblionumber => $biblio->biblionumber, + itemlost => 0, + } + ); + my $item_3 = $builder->build_sample_item( + { + biblionumber => $biblio->biblionumber, + itemlost => 1, + } + ); + + is( $biblio->items->filter_out_lost->next->itemnumber, $item_2->itemnumber, 'Right item returned' ); + is( $biblio->items->filter_out_lost->count, 1, 'Only one item is not lost' ); + + $schema->storage->txn_rollback; +}; + +subtest 'filter_out_opachiddenitems() tests' => sub { + + plan tests => 6; + + $schema->storage->txn_begin; + + # have a fresh biblio + my $biblio = $builder->build_sample_biblio; + # have two itemtypes + my $itype_1 = $builder->build_object({ class => 'Koha::ItemTypes' }); + my $itype_2 = $builder->build_object({ class => 'Koha::ItemTypes' }); + # have 5 items on that biblio + my $item_1 = $builder->build_sample_item( + { + biblionumber => $biblio->biblionumber, + itype => $itype_1->itemtype, + withdrawn => 1 + } + ); + my $item_2 = $builder->build_sample_item( + { + biblionumber => $biblio->biblionumber, + itype => $itype_2->itemtype, + withdrawn => 2 + } + ); + my $item_3 = $builder->build_sample_item( + { + biblionumber => $biblio->biblionumber, + itype => $itype_1->itemtype, + withdrawn => 3 + } + ); + my $item_4 = $builder->build_sample_item( + { + biblionumber => $biblio->biblionumber, + itype => $itype_2->itemtype, + withdrawn => 4 + } + ); + my $item_5 = $builder->build_sample_item( + { + biblionumber => $biblio->biblionumber, + itype => $itype_1->itemtype, + withdrawn => 5 + } + ); + my $item_6 = $builder->build_sample_item( + { + biblionumber => $biblio->biblionumber, + itype => $itype_1->itemtype, + withdrawn => 5 + } + ); + + my $rules = undef; + + my $mocked_context = Test::MockModule->new('C4::Context'); + $mocked_context->mock( 'yaml_preference', sub { + return $rules; + }); + + is( $biblio->items->filter_out_opachiddenitems->count, 6, 'No rules passed' ); + + $rules = {}; + + $rules = { withdrawn => [ 1, 2 ] }; + is( $biblio->items->filter_out_opachiddenitems->count, 4, 'Rules on withdrawn' ); + + $rules = { itype => [ $itype_1->itemtype ] }; + is( $biblio->items->filter_out_opachiddenitems->count, 2, 'Rules on itype' ); + + $rules = { withdrawn => [ 1, 2 ], itype => [ $itype_1->itemtype ] }; + is( $biblio->items->filter_out_opachiddenitems->count, 1, 'Rules on itype and withdrawn' ); + is( $biblio->items->filter_out_opachiddenitems->next->itemnumber, + $item_4->itemnumber, + 'The right item is returned' + ); + + $rules = { withdrawn => [ 1, 2 ], itype => [ $itype_2->itemtype ] }; + is( $biblio->items->filter_out_opachiddenitems->count, 3, 'Rules on itype and withdrawn' ); + + $schema->storage->txn_rollback; +}; --