From b1ff6438a28c67fb93c2cb96b0a01ef421b6c404 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Thu, 23 Sep 2021 15:51:06 +0100 Subject: [PATCH] Bug 29099: Add bundle support to inventory tool Test plan: 1. Create an item bundle (see bug 28854 comment 458) containing 2 items with barcodes B1 and B2 2. Go to the inventory tool 3. Enter B1 inside the barcode list 4. Select the item bundle in "Item location filters" fieldset 5. Submit the form In the result table you should see B2 with the problem "Missing (not scanned)" --- C4/Items.pm | 6 +++++ .../prog/en/modules/tools/inventory.tt | 20 +++++++++++++++- t/db_dependent/Items/GetItemsForInventory.t | 23 ++++++++++++++++++- tools/inventory.pl | 17 ++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/C4/Items.pm b/C4/Items.pm index 817e86e940..c6d2c43e17 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -527,6 +527,7 @@ sub GetItemsForInventory { my $minlocation = $parameters->{'minlocation'} // ''; my $maxlocation = $parameters->{'maxlocation'} // ''; my $class_source = $parameters->{'class_source'} // C4::Context->preference('DefaultClassificationSource'); + my $items_bundle = $parameters->{'items_bundle'} // ''; my $location = $parameters->{'location'} // ''; my $itemtype = $parameters->{'itemtype'} // ''; my $ignoreissued = $parameters->{'ignoreissued'} // ''; @@ -580,6 +581,11 @@ sub GetItemsForInventory { push @bind_params, $max_cnsort; } + if ($items_bundle) { + push @where_strings, 'items.itemnumber IN (SELECT item FROM item_bundles WHERE host = ?)'; + push @bind_params, $items_bundle; + } + if ($datelastseen) { push @where_strings, '(datelastseen < ? OR datelastseen IS NULL)'; push @bind_params, $datelastseen; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt index d66d88c63e..3a1b303cc6 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt @@ -150,6 +150,17 @@ [% END %] + [% IF item_bundles.size > 0 %] +
  • + + +
  • + [% END %] @@ -370,7 +381,8 @@ $('#locationloop').val() || $('#minlocation').val() || $('#maxlocation').val() || - $('#statuses input:checked').length + $('#statuses input:checked').length || + $('#items_bundle').val() ) ) { return confirm( _("You have not selected any catalog filters and are about to compare a file of barcodes to your entire catalog.") + "\n\n" + @@ -510,6 +522,12 @@ }); }); + [% INCLUDE 'select2.inc' %] + [% END %] [% INCLUDE 'intranet-bottom.inc' %] diff --git a/t/db_dependent/Items/GetItemsForInventory.t b/t/db_dependent/Items/GetItemsForInventory.t index b5c2b97bd2..88bc521be0 100755 --- a/t/db_dependent/Items/GetItemsForInventory.t +++ b/t/db_dependent/Items/GetItemsForInventory.t @@ -19,7 +19,7 @@ use Modern::Perl; -use Test::More tests => 7; +use Test::More tests => 8; use t::lib::TestBuilder; use List::MoreUtils qw( any none ); @@ -186,3 +186,24 @@ subtest 'Use cn_sort rather than callnumber to determine correct location' => su $schema->storage->txn_rollback; }; + +subtest 'Search by items bundle' => sub { + $schema->storage->txn_begin; + plan tests => 1; + + my $builder = t::lib::TestBuilder->new; + + my $item_bundle = $builder->build_object({ class => 'Koha::Items' }); + my $item1 = $builder->build_object({ class => 'Koha::Items' }); + my $item2 = $builder->build_object({ class => 'Koha::Items' }); + + $item_bundle->_result->add_to_item_bundles_hosts({ item => $item1->itemnumber }); + $item_bundle->_result->add_to_item_bundles_hosts({ item => $item2->itemnumber }); + + my ($items) = C4::Items::GetItemsForInventory({ items_bundle => $item_bundle->itemnumber }); + + my @itemnumbers = sort map { $_->{itemnumber} } @$items; + is_deeply(\@itemnumbers, [$item1->itemnumber, $item2->itemnumber]); + + $schema->storage->txn_rollback; +}; diff --git a/tools/inventory.pl b/tools/inventory.pl index ace4e7cb7b..96b4833ad6 100755 --- a/tools/inventory.pl +++ b/tools/inventory.pl @@ -49,6 +49,7 @@ my $minlocation=$input->param('minlocation') || ''; my $maxlocation=$input->param('maxlocation'); my $class_source=$input->param('class_source'); $maxlocation=$minlocation.'Z' unless ( $maxlocation || ! $minlocation ); +my $items_bundle = $input->param('items_bundle'); my $location=$input->param('location') || ''; my $ignoreissued=$input->param('ignoreissued'); my $ignore_waiting_holds = $input->param('ignore_waiting_holds'); @@ -69,6 +70,19 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( } ); +my $schema = Koha::Database->new()->schema(); +my $item_bundles_rs = Koha::Items->search( + { + 'item_bundles_hosts.item' => { '!=' => undef }, + }, + { + join => 'item_bundles_hosts', + group_by => 'itemnumber', + } +); + +my @item_bundles = $item_bundles_rs->as_list; + my @authorised_value_list; my $authorisedvalue_categories = ''; @@ -140,6 +154,7 @@ foreach my $itemtype ( @itemtypes ) { $template->param( authorised_values => \@authorised_value_list, + item_bundles => \@item_bundles, today => dt_from_string, minlocation => $minlocation, maxlocation => $maxlocation, @@ -259,6 +274,7 @@ if ( $op && ( !$uploadbarcodes || $compareinv2barcd )) { minlocation => $minlocation, maxlocation => $maxlocation, class_source => $class_source, + items_bundle => $items_bundle, location => $location, ignoreissued => $ignoreissued, datelastseen => $datelastseen, @@ -279,6 +295,7 @@ if( @scanned_items ) { maxlocation => $maxlocation, class_source => $class_source, location => $location, + items_bundle => $items_bundle, ignoreissued => undef, datelastseen => undef, branchcode => $branchcode, -- 2.30.2