From 682729cbcd8a93246d482d1c269dd7c5e4d667e5 Mon Sep 17 00:00:00 2001 From: Julian Maurice Date: Fri, 14 Apr 2017 15:45:04 +0200 Subject: [PATCH] Bug 18433: Allow to select results to export in item search MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a column of checkboxes in the results table to be able to select the items to be exported Test plan: 1. Go to item search and click 'Search' 2. Without checking any checkbox, verify that the export still works (it should export all results) 3. Tick some checkboxes and re-export, verify that only selected items are exported Followed test plan, works as expected. Signed-off-by: Marc VĂ©ron --- catalogue/item-export.pl | 64 +++++++++++ catalogue/itemsearch.pl | 66 +---------- .../catalogue/itemsearch_item.csv.inc | 4 +- .../catalogue/itemsearch_item.json.inc | 9 +- .../prog/en/modules/catalogue/itemsearch.tt | 104 +++++++++++++++--- 5 files changed, 163 insertions(+), 84 deletions(-) create mode 100755 catalogue/item-export.pl diff --git a/catalogue/item-export.pl b/catalogue/item-export.pl new file mode 100755 index 0000000000..ef6aaa4b9f --- /dev/null +++ b/catalogue/item-export.pl @@ -0,0 +1,64 @@ +#!/usr/bin/perl + +# Copyright 2017 BibLibre +# +# 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, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use CGI; + +use C4::Auth; +use C4::Output; + +my $cgi = new CGI; + +my ($template, $borrowernumber, $cookie) = get_template_and_user({ + template_name => 'catalogue/itemsearch_csv.tt', + query => $cgi, + type => 'intranet', + authnotrequired => 0, + flagsrequired => { catalogue => 1 }, +}); + +my @itemnumbers = $cgi->multi_param('itemnumber'); +my $format = $cgi->param('format') // 'csv'; + +my @items = Koha::Items->search({ itemnumber => { -in => \@itemnumbers } }); + +if ($format eq 'barcodes') { + print $cgi->header({ + type => 'text/plain', + attachment => 'barcodes.txt', + }); + + foreach my $item (@items) { + print $item->barcode . "\n"; + } + exit; +} + +$template->param( + results => \@items, +); + +print $cgi->header({ + type => 'text/csv', + attachment => 'items.csv', +}); +for my $line ( split '\n', $template->output ) { + print "$line\n" unless $line =~ m|^\s*$|; +} diff --git a/catalogue/itemsearch.pl b/catalogue/itemsearch.pl index 090192e231..b88fab1b96 100755 --- a/catalogue/itemsearch.pl +++ b/catalogue/itemsearch.pl @@ -97,13 +97,7 @@ my ($template, $borrowernumber, $cookie) = get_template_and_user({ flagsrequired => { catalogue => 1 }, }); -my $mss = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.notforloan', authorised_value => [ -and => {'!=' => undef }, {'!=' => ''}] }); -my $notforloan_values = $mss->count ? GetAuthorisedValues($mss->next->authorised_value) : []; - -$mss = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.location', authorised_value => [ -and => {'!=' => undef }, {'!=' => ''}] }); -my $location_values = $mss->count ? GetAuthorisedValues($mss->next->authorised_value) : []; - -$mss = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.itemlost', authorised_value => [ -and => {'!=' => undef }, {'!=' => ''}] }); +my $mss = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.itemlost', authorised_value => [ -and => {'!=' => undef }, {'!=' => ''}] }); my $itemlost_values = $mss->count ? GetAuthorisedValues($mss->next->authorised_value) : []; $mss = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.withdrawn', authorised_value => [ -and => {'!=' => undef }, {'!=' => ''}] }); @@ -226,38 +220,10 @@ if (scalar keys %params > 0) { } if ($results) { - # Get notforloan labels - my $notforloan_map = {}; - foreach my $nfl_value (@$notforloan_values) { - $notforloan_map->{$nfl_value->{authorised_value}} = $nfl_value->{lib}; - } - - # Get location labels - my $location_map = {}; - foreach my $loc_value (@$location_values) { - $location_map->{$loc_value->{authorised_value}} = $loc_value->{lib}; - } - - # Get itemlost labels - my $itemlost_map = {}; - foreach my $il_value (@$itemlost_values) { - $itemlost_map->{$il_value->{authorised_value}} = $il_value->{lib}; - } - - # Get withdrawn labels - my $withdrawn_map = {}; - foreach my $wd_value (@$withdrawn_values) { - $withdrawn_map->{$wd_value->{authorised_value}} = $wd_value->{lib}; - } - foreach my $item (@$results) { my $biblio = Koha::Biblios->find( $item->{biblionumber} ); $item->{biblio} = $biblio; $item->{biblioitem} = $biblio->biblioitem->unblessed; - $item->{status} = $notforloan_map->{$item->{notforloan}}; - if (defined $item->{location}) { - $item->{location} = $location_map->{$item->{location}}; - } } } @@ -288,13 +254,6 @@ if (scalar keys %params > 0) { # Display the search form my @branches = map { value => $_->branchcode, label => $_->branchname }, Koha::Libraries->search( {}, { order_by => 'branchname' } ); -my @locations; -foreach my $location (@$location_values) { - push @locations, { - value => $location->{authorised_value}, - label => $location->{lib} // $location->{authorised_value}, - }; -} my @itemtypes; foreach my $itemtype ( Koha::ItemTypes->search ) { push @itemtypes, { @@ -303,23 +262,10 @@ foreach my $itemtype ( Koha::ItemTypes->search ) { }; } -$mss = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.ccode', authorised_value => [ -and => {'!=' => undef }, {'!=' => ''}] }); -my $ccode_avcode = $mss->count ? $mss->next->authorised_value : 'CCODE'; -my $ccodes = GetAuthorisedValues($ccode_avcode); -my @ccodes; -foreach my $ccode (@$ccodes) { - push @ccodes, { - value => $ccode->{authorised_value}, - label => $ccode->{lib}, - }; -} - -my @notforloans; -foreach my $value (@$notforloan_values) { - push @notforloans, { - value => $value->{authorised_value}, - label => $value->{lib}, - }; +my @ccodes = Koha::AuthorisedValues->get_descriptions_by_koha_field({ kohafield => 'items.ccode' }); +foreach my $ccode (@ccodes) { + $ccode->{value} = $ccode->{authorised_value}, + $ccode->{label} = $ccode->{lib}, } my @itemlosts; @@ -349,10 +295,8 @@ foreach my $field (@items_search_fields) { $template->param( branches => \@branches, - locations => \@locations, itemtypes => \@itemtypes, ccodes => \@ccodes, - notforloans => \@notforloans, itemlosts => \@itemlosts, withdrawns => \@withdrawns, items_search_fields => \@items_search_fields, diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.csv.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.csv.inc index f52e3a6934..63aaee8874 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.csv.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.csv.inc @@ -1,7 +1,7 @@ [%- USE Branches -%] [%- USE Koha -%] [%- USE ItemTypes -%] -[% USE AuthorisedValues %] +[%- USE AuthorisedValues -%] [%- SET biblio = item.biblio -%] [%- SET biblioitem = item.biblioitem -%] -"[% biblio.title | html %] [% IF ( Koha.Preference( 'marcflavour' ) == 'UNIMARC' && biblio.author ) %]by [% END %][% biblio.author | html %]", "[% (biblioitem.publicationyear || biblio.copyrightdate) | html %]", "[% biblioitem.publishercode | html %]", "[% AuthorisedValues.GetByCode( 'CCODE', item.ccode ) | html %]", "[% item.barcode | html %]", "[% item.itemcallnumber | html %]", "[% Branches.GetName(item.homebranch) | html %]", "[% Branches.GetName(item.holdingbranch) | html %]", "[% item.location | html %]", "[% ItemTypes.GetDescription(item.itype) | html %]", "[% item.stocknumber | html %]", "[% item.status | html %]","[% AuthorisedValues.GetByCode( 'LOST', item.itemlost ) || "" | html %]","[% AuthorisedValues.GetByCode( 'WITHDRAWN', item.withdrawn ) || "" | html %]", "[% (item.issues || 0) | html %]" +"[% biblio.title | html %] [% IF ( Koha.Preference( 'marcflavour' ) == 'UNIMARC' && biblio.author ) %]by [% END %][% biblio.author | html %]", "[% (biblioitem.publicationyear || biblio.copyrightdate) | html %]", "[% biblioitem.publishercode | html %]", "[% AuthorisedValues.GetByCode( 'CCODE', item.ccode ) | html %]", "[% item.barcode | html %]", "[% item.itemcallnumber | html %]", "[% Branches.GetName(item.homebranch) | html %]", "[% Branches.GetName(item.holdingbranch) | html %]", "[% AuthorisedValues.GetDescriptionByKohaField(frameworkcode => biblio.frameworkcode, kohafield => 'items.location', authorised_value => item.location) | html %]", "[% ItemTypes.GetDescription(item.itype) | html %]", "[% item.stocknumber | html %]", "[% AuthorisedValues.GetDescriptionByKohaField(frameworkcode => biblio.frameworkcode, kohafield => 'items.notforloan', authorised_value => item.notforloan) | html %]","[% AuthorisedValues.GetByCode( 'LOST', item.itemlost ) || "" | html %]","[% AuthorisedValues.GetByCode( 'WITHDRAWN', item.withdrawn ) || "" | html %]", "[% (item.issues || 0) | html %]" diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.json.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.json.inc index b0ca870087..417f7724a4 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.json.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.json.inc @@ -2,11 +2,14 @@ [%- USE Koha -%] [%- USE To -%] [%- USE ItemTypes -%] -[% USE AuthorisedValues %] +[%- USE AuthorisedValues -%] [%- biblio = item.biblio -%] [%- biblioitem = item.biblioitem -%] [ "[% FILTER escape_quotes = replace('"', '\"') ~%] + + [%~ END %]", + "[% FILTER escape_quotes ~%] [% biblio.title | html %][% IF ( Koha.Preference( 'marcflavour' ) == 'UNIMARC' && biblio.author ) %] by[% END %] [% biblio.author | html %] [%~ END %]", "[% (biblioitem.publicationyear || biblio.copyrightdate) | html %]", @@ -18,10 +21,10 @@ "[% item.itemcallnumber | html %]", "[% Branches.GetName(item.homebranch) | html %]", "[% Branches.GetName(item.holdingbranch) | html %]", - "[% item.location | html %]", + "[% AuthorisedValues.GetDescriptionByKohaField( frameworkcode => biblio.frameworkcode, kohafield => 'items.location', authorised_value => item.location) | html %]", "[% ItemTypes.GetDescription(item.itype) | html %]", "[% item.stocknumber | html %]", - "[% item.status | html %]", + "[% AuthorisedValues.GetDescriptionByKohaField( frameworkcode => biblio.frameworkcode, kohafield => 'items.notforloan', authorised_value => item.notforloan) | html %]", "[% AuthorisedValues.GetByCode( 'LOST', item.itemlost ) || "" | html %]", "[% AuthorisedValues.GetByCode( 'WITHDRAWN', item.withdrawn ) || "" | html %]", "[% (item.issues || 0) | html %]", diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt index ee1b43ea74..a9ad87d0c5 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt @@ -1,6 +1,7 @@ [% USE raw %] [% USE To %] [% USE Asset %] +[% USE AuthorisedValues %] [% BLOCK form_label %] [% SWITCH label %] @@ -110,6 +111,18 @@ [%- To.json(escaped) | $raw -%] [%- END -%] +[% notforloans = AuthorisedValues.GetDescriptionsByKohaField({ kohafield = 'items.notforloan' }) %] +[% FOREACH nfl IN notforloans %] + [% nfl.value = nfl.authorised_value %] + [% nfl.label = nfl.lib %] +[% END %] + +[% locations = AuthorisedValues.GetDescriptionsByKohaField({ kohafield = 'items.location' }) %] +[% FOREACH loc IN locations %] + [% loc.value = loc.authorised_value %] + [% loc.label = loc.lib %] +[% END %] + [%# Page starts here %] [% SET footerjs = 1 %] @@ -266,6 +279,7 @@ function submitForm($form) { var tr = '' + ' ' + + ' ' + ' ' + _("Title") + '' + ' ' + _("Publication date") + '' + ' ' + _("Publisher") + '' @@ -301,38 +315,79 @@ $('#item-search-block').show(); }); + function exportItems(format) { + var itemnumbers = []; + $('#results').find('input[name="itemnumber"]:checked').each(function() { + itemnumbers.push($(this).val()); + }); + if (itemnumbers.length) { + var href = '/cgi-bin/koha/catalogue/item-export.pl?format=' + format; + href += '&itemnumber=' + itemnumbers.join('&itemnumber='); + location = href; + } else { + $('#format-' + format).prop('checked', true); + $('#itemsearchform').submit(); + $('#format-html').prop('checked', true); + } + } + var csvExportLink = $('') .attr('href', '#') - .html(_("Export results to CSV")) - .addClass('btn btn-default btn-xs') + .html("CSV") .on('click', function(e) { e.preventDefault(); - $('#format-csv').prop('checked', true); - $('#itemsearchform').submit(); - $('#format-html').prop('checked', true); + exportItems('csv'); }); var barcodesExportLink = $('') .attr('href', '#') - .html(_("Export results to barcodes file")) - .addClass('btn btn-default btn-xs') + .html(_("Barcodes file")) .on('click', function(e) { e.preventDefault(); - $('#format-barcodes').prop('checked', true); - $('#itemsearchform').submit(); - $('#format-html').prop('checked', true); + exportItems('barcodes'); }); - var editSearchAndExportLinks = $('

') - .append(editSearchLink) - .append(' | ') - .append(csvExportLink) - .append(' ') - .append(barcodesExportLink); + var exportButton = $('

') + .addClass('btn-group') + .append($('