From 49f2960eddeaa56e8e53912b710b6535c0ea89f7 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)" Signed-off-by: Martin Renvoize --- 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 de776d5dfe5..3455b84b128 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -533,6 +533,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'} // ''; @@ -586,6 +587,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 1571f6a3ee7..813ee21873d 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt @@ -153,6 +153,17 @@ [% END %] + [% IF item_bundles.size > 0 %] +
  • + + +
  • + [% END %] @@ -372,7 +383,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" + @@ -512,6 +524,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 b5c2b97bd26..88bc521be06 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 ace4e7cb7bb..96b4833ad60 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.39.1