Bugzilla – Attachment 62181 Details for
Bug 18433
Allow to select results to export in item search
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 18433: Allow to select results to export in item search
Bug-18433-Allow-to-select-results-to-export-in-ite.patch (text/plain), 19.62 KB, created by
Marc Véron
on 2017-04-14 19:52:38 UTC
(
hide
)
Description:
Bug 18433: Allow to select results to export in item search
Filename:
MIME Type:
Creator:
Marc Véron
Created:
2017-04-14 19:52:38 UTC
Size:
19.62 KB
patch
obsolete
>From f7072fe609ce6aa5fbfc1abfa32edfe0be2c2efc Mon Sep 17 00:00:00 2001 >From: Julian Maurice <julian.maurice@biblibre.com> >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 <veron@veron.ch> >--- > Koha/AuthorisedValueCategories.pm | 23 +++++ > Koha/Item.pm | 14 +++ > Koha/Template/Plugin/AuthorisedValues.pm | 9 ++ > catalogue/item-export.pl | 70 +++++++++++++ > catalogue/itemsearch.pl | 45 +-------- > .../en/includes/catalogue/itemsearch_item.csv.inc | 5 +- > .../en/includes/catalogue/itemsearch_item.json.inc | 10 +- > .../prog/en/modules/catalogue/itemsearch.tt | 108 +++++++++++++++++---- > 8 files changed, 222 insertions(+), 62 deletions(-) > create mode 100755 catalogue/item-export.pl > >diff --git a/Koha/AuthorisedValueCategories.pm b/Koha/AuthorisedValueCategories.pm >index b756f6a..5702893 100644 >--- a/Koha/AuthorisedValueCategories.pm >+++ b/Koha/AuthorisedValueCategories.pm >@@ -22,6 +22,7 @@ use Carp; > use Koha::Database; > > use Koha::AuthorisedValueCategory; >+use Koha::MarcSubfieldStructures; > > use base qw(Koha::Objects); > >@@ -35,6 +36,28 @@ Koha::AuthorisedValueCategories - Koha AuthorisedValueCategory Object set class > > =cut > >+=head3 findByKohaField >+ >+ my $category = Koha::AuthorisedValueCategories->findByKohaField($kohafield, [$frameworkcode]); >+ >+Returns the authorised value category linked to the given koha field >+ >+=cut >+ >+sub findByKohaField { >+ my ($class, $kohafield, $frameworkcode) = @_; >+ >+ $frameworkcode //= ''; >+ >+ my ($subfield) = Koha::MarcSubfieldStructures->search({ >+ frameworkcode => $frameworkcode, >+ kohafield => $kohafield, >+ authorised_value => { not => undef }, >+ }); >+ >+ return $subfield ? $class->find($subfield->authorised_value) : undef; >+} >+ > =head3 type > > =cut >diff --git a/Koha/Item.pm b/Koha/Item.pm >index a921018..ccf394e 100644 >--- a/Koha/Item.pm >+++ b/Koha/Item.pm >@@ -92,6 +92,20 @@ sub biblio { > return Koha::Biblio->_new_from_dbic( $biblio_rs ); > } > >+=head3 biblioitem >+ >+my $biblio = $item->biblio; >+ >+Return the biblioitem record of this item >+ >+=cut >+ >+sub biblioitem { >+ my ( $self ) = @_; >+ my $biblioitem_rs = $self->_result->biblioitem; >+ return Koha::Biblioitem->_new_from_dbic( $biblioitem_rs ); >+} >+ > =head3 get_transfer > > my $transfer = $item->get_transfer; >diff --git a/Koha/Template/Plugin/AuthorisedValues.pm b/Koha/Template/Plugin/AuthorisedValues.pm >index 05c27b8..280b4eb 100644 >--- a/Koha/Template/Plugin/AuthorisedValues.pm >+++ b/Koha/Template/Plugin/AuthorisedValues.pm >@@ -23,6 +23,7 @@ use base qw( Template::Plugin ); > > use C4::Koha; > use Koha::AuthorisedValues; >+use Koha::AuthorisedValueCategories; > > sub GetByCode { > my ( $self, $category, $code, $opac ) = @_; >@@ -68,6 +69,14 @@ sub GetCategories { > ]; > } > >+sub GetCategoryByKohaField { >+ my ($self, $kohafield, $frameworkcode) = @_; >+ >+ my $category = Koha::AuthorisedValueCategories->findByKohaField($kohafield, $frameworkcode); >+ >+ return $category ? $category->category_name : undef; >+} >+ > 1; > > =head1 NAME >diff --git a/catalogue/item-export.pl b/catalogue/item-export.pl >new file mode 100755 >index 0000000..564cd0be >--- /dev/null >+++ b/catalogue/item-export.pl >@@ -0,0 +1,70 @@ >+#!/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; >+foreach my $itemnumber (@itemnumbers) { >+ my $item = Koha::Items->find($itemnumber); >+ if ($item) { >+ push @items, $item; >+ } >+} >+ >+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 5f20dd3..7ca7013 100755 >--- a/catalogue/itemsearch.pl >+++ b/catalogue/itemsearch.pl >@@ -27,7 +27,7 @@ use C4::Items; > use C4::Biblio; > use C4::Koha; > >-use Koha::AuthorisedValues; >+use Koha::AuthorisedValueCategories; > use Koha::Item::Search::Field qw(GetItemSearchFields); > use Koha::ItemTypes; > use Koha::Libraries; >@@ -90,12 +90,6 @@ my ($template, $borrowernumber, $cookie) = get_template_and_user({ > flagsrequired => { catalogue => 1 }, > }); > >-my $mss = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.notforloan', authorised_value => { not => undef } }); >-my $notforloan_values = $mss->count ? GetAuthorisedValues($mss->next->authorised_value) : []; >- >-$mss = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.location', authorised_value => { not => undef } }); >-my $location_values = $mss->count ? GetAuthorisedValues($mss->next->authorised_value) : []; >- > if (scalar keys %params > 0) { > # Parameters given, it's a search > >@@ -213,25 +207,9 @@ 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}; >- } >- > foreach my $item (@$results) { > $item->{biblio} = GetBiblio($item->{biblionumber}); > ($item->{biblioitem}) = GetBiblioItemByBiblioNumber($item->{biblionumber}); >- $item->{status} = $notforloan_map->{$item->{notforloan}}; >- if (defined $item->{location}) { >- $item->{location} = $location_map->{$item->{location}}; >- } > } > } > >@@ -261,13 +239,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, { >@@ -276,8 +247,8 @@ foreach my $itemtype ( Koha::ItemTypes->search ) { > }; > } > >-$mss = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.ccode', authorised_value => { not => undef } }); >-my $ccode_avcode = $mss->count ? $mss->next->authorised_value : 'CCODE'; >+my $ccode_avcategory = Koha::AuthorisedValueCategories->findByKohaField('items.ccode'); >+my $ccode_avcode = $ccode_avcategory ? $ccode_avcategory->category_name : 'CCODE'; > my $ccodes = GetAuthorisedValues($ccode_avcode); > my @ccodes; > foreach my $ccode (@$ccodes) { >@@ -287,14 +258,6 @@ foreach my $ccode (@$ccodes) { > }; > } > >-my @notforloans; >-foreach my $value (@$notforloan_values) { >- push @notforloans, { >- value => $value->{authorised_value}, >- label => $value->{lib}, >- }; >-} >- > my @items_search_fields = GetItemSearchFields(); > > my $authorised_values = {}; >@@ -306,10 +269,8 @@ foreach my $field (@items_search_fields) { > > $template->param( > branches => \@branches, >- locations => \@locations, > itemtypes => \@itemtypes, > ccodes => \@ccodes, >- notforloans => \@notforloans, > items_search_fields => \@items_search_fields, > authorised_values_json => to_json($authorised_values), > ); >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 5e38a58..aeef03e 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,5 +1,8 @@ > [%- USE Branches -%] > [%- USE Koha -%] >+[%- USE AuthorisedValues -%] > [%- biblio = item.biblio -%] > [%- 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 %]", "[% biblioitem.collectiontitle |html %]", "[% item.barcode |html %]", "[% item.itemcallnumber |html %]", "[% Branches.GetName(item.homebranch) |html %]", "[% Branches.GetName(item.holdingbranch) |html %]", "[% item.location |html %]", "[% item.stocknumber |html %]", "[% item.status |html %]", "[% (item.issues || 0) |html %]" >+[%- notforloan_avcategory = AuthorisedValues.GetCategoryByKohaField('items.notforloan') -%] >+[%- location_avcategory = AuthorisedValues.GetCategoryByKohaField('items.location') -%] >+"[% biblio.title |html %] [% IF ( Koha.Preference( 'marcflavour' ) == 'UNIMARC' && biblio.author ) %]by [% END %][% biblio.author |html %]", "[% (biblioitem.publicationyear || biblio.copyrightdate) |html %]", "[% biblioitem.publishercode |html %]", "[% biblioitem.collectiontitle |html %]", "[% item.barcode |html %]", "[% item.itemcallnumber |html %]", "[% Branches.GetName(item.homebranch) |html %]", "[% Branches.GetName(item.holdingbranch) |html %]", "[% IF location_avcategory %][% AuthorisedValues.GetByCode(location_avcategory, item.location) |html %][% ELSE %][% item.location |html %][% END %]", "[% item.stocknumber |html %]", "[% IF notforloan_avcategory %][% AuthorisedValues.GetByCode(notforloan_avcategory, item.notforloan) |html %][% ELSE %][% item.notforloan |html %][% END %]", "[% (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 4085b94..20f6d42 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 >@@ -1,9 +1,15 @@ > [%- USE Branches -%] > [%- USE Koha -%] >+[%- USE AuthorisedValues -%] > [%- biblio = item.biblio -%] > [%- biblioitem = item.biblioitem -%] >+[%- notforloan_avcategory = AuthorisedValues.GetCategoryByKohaField('items.notforloan') -%] >+[%- location_avcategory = AuthorisedValues.GetCategoryByKohaField('items.location') -%] > [ > "[% FILTER escape_quotes = replace('"', '\"') ~%] >+ <input type="checkbox" name="itemnumber" value="[% item.itemnumber %]"/> >+ [%~ END %]", >+ "[% FILTER escape_quotes ~%] > <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblio.biblionumber %]" title="Go to record detail page">[% biblio.title |html %]</a>[% IF ( Koha.Preference( 'marcflavour' ) == 'UNIMARC' && biblio.author ) %] by[% END %] [% biblio.author |html %] > [%~ END %]", > "[% (biblioitem.publicationyear || biblio.copyrightdate) |html %]", >@@ -15,9 +21,9 @@ > "[% item.itemcallnumber |html %]", > "[% Branches.GetName(item.homebranch) |html %]", > "[% Branches.GetName(item.holdingbranch) |html %]", >- "[% item.location |html %]", >+ "[% IF location_avcategory %][% AuthorisedValues.GetByCode(location_avcategory, item.location) | html %][% ELSE %][% item.location |html %][% END %]", > "[% item.stocknumber |html %]", >- "[% item.status |html %]", >+ "[% IF notforloan_avcategory %][% AuthorisedValues.GetByCode(notforloan_avcategory, item.notforloan) | html %][% ELSE %][% item.notforloan |html %][% END %]", > "[% (item.issues || 0) |html %]", > "[% FILTER escape_quotes ~%] > <a href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=[% item.biblionumber %]&itemnumber=[% item.itemnumber %]">Edit</a> >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 5905e3e..e721da6 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt >@@ -1,5 +1,6 @@ > [% USE CGI %] > [% USE JSON.Escape %] >+[% USE AuthorisedValues %] > > [% BLOCK form_label %] > [% SWITCH label %] >@@ -155,6 +156,24 @@ > </div> > [% END %] > >+[% notforloan_avcategory = AuthorisedValues.GetCategoryByKohaField('items.notforloan') %] >+[% IF notforloan_avcategory %] >+ [% notforloans = AuthorisedValues.Get(notforloan_avcategory) %] >+ [% FOREACH nfl IN notforloans %] >+ [% nfl.value = nfl.authorised_value %] >+ [% nfl.label = nfl.lib %] >+ [% END %] >+[% END %] >+ >+[% location_avcategory = AuthorisedValues.GetCategoryByKohaField('items.location') %] >+[% IF location_avcategory %] >+ [% locations = AuthorisedValues.Get(location_avcategory) %] >+ [% FOREACH loc IN locations %] >+ [% loc.value = loc.authorised_value %] >+ [% loc.label = loc.lib %] >+ [% END %] >+[% END %] >+ > [%# Page starts here %] > > [% INCLUDE 'doc-head-open.inc' %] >@@ -207,6 +226,7 @@ > function submitForm($form) { > var tr = '' > + ' <tr>' >+ + ' <th></th>' > + ' <th>' + _("Title") + '</th>' > + ' <th>' + _("Publication date") + '</th>' > + ' <th>' + _("Publisher") + '</th>' >@@ -239,38 +259,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 = $('<a>') > .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 = $('<a>') > .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 = $('<p>') >- .append(editSearchLink) >- .append(' | ') >- .append(csvExportLink) >+ var exportButton = $('<div>') >+ .addClass('btn-group') >+ .append($('<button>') >+ .addClass('btn btn-default btn-xs dropdown-toggle') >+ .attr('id', 'export-button') >+ .attr('data-toggle', 'dropdown') >+ .attr('aria-haspopup', 'true') >+ .attr('aria-expanded', 'false') >+ .html(_("Export all results to") + ' <span class="caret"></span>')) >+ .append($('<ul>') >+ .addClass('dropdown-menu') >+ .append($('<li>').append(csvExportLink)) >+ .append($('<li>').append(barcodesExportLink))); >+ >+ var selectVisibleRows = $('<a>') >+ .attr('href', '#') >+ .append('<i class="fa fa-check"></i> ') >+ .append(_("Select visible rows")) >+ .on('click', function(e) { >+ e.preventDefault(); >+ $('#results input[type="checkbox"]').prop('checked', true).change(); >+ }); >+ var clearSelection = $('<a>') >+ .attr('href', '#') >+ .append('<i class="fa fa-remove"></i> ') >+ .append(_("Clear selection")) >+ .on('click', function(e) { >+ e.preventDefault(); >+ $('#results input[type="checkbox"]').prop('checked', false).change(); >+ }); >+ var exportLinks = $('<p>') >+ .append(selectVisibleRows) > .append(' ') >- .append(barcodesExportLink); >+ .append(clearSelection) >+ .append(' | ') >+ .append(exportButton); > > var results_heading = $('<div>').addClass('results-heading') > .append("<h1>" + _("Item search results") + "</h1>") > .append($('<p>').append(advSearchLink)) >- .append(editSearchAndExportLinks); >+ .append($('<p>').append(editSearchLink)) >+ .append(exportLinks); > $('#results-wrapper').empty() > .append(results_heading) > .append(table); >@@ -309,7 +370,9 @@ > }); > }, > 'sDom': '<"top pager"ilp>t<"bottom pager"ip>r', >+ 'aaSorting': [[1, 'asc']], > 'aoColumns': [ >+ { 'sName': 'checkbox', 'bSortable': false }, > { 'sName': 'title' }, > { 'sName': 'publicationyear' }, > { 'sName': 'publishercode' }, >@@ -322,12 +385,13 @@ > { 'sName': 'stocknumber' }, > { 'sName': 'notforloan' }, > { 'sName': 'issues' }, >- { 'sName': 'checkbox', 'bSortable': false } >+ { 'sName': 'actions', 'bSortable': false } > ], > "sPaginationType": "full_numbers" > })).columnFilter({ > 'sPlaceHolder': 'head:after', > 'aoColumns': [ >+ null, > { 'type': 'text' }, > { 'type': 'text' }, > { 'type': 'text' }, >@@ -351,6 +415,16 @@ > null > ] > }); >+ >+ $('#results').on('change', 'input[type="checkbox"]', function() { >+ var countSelected = $(this).parents('table').find('input:checked').length; >+ var caret = ' <span class="caret">'; >+ if (countSelected > 0) { >+ $('#export-button').html(_("Export selected results to") + caret); >+ } else { >+ $('#export-button').html(_("Export all results to") + caret); >+ } >+ }) > } > > $(document).ready(function () { >-- >2.1.4
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 18433
:
62170
|
62181
|
62358
|
62388
|
62389
|
62390
|
62415
|
62416
|
62417
|
62449
|
62472
|
95380
|
97479
|
99123
|
99124
|
99159
|
99160
|
99161
|
99162