View | Details | Raw Unified | Return to bug 18433
Collapse All | Expand All

(-)a/Koha/AuthorisedValueCategories.pm (+1 lines)
Lines 22-27 use Carp; Link Here
22
use Koha::Database;
22
use Koha::Database;
23
23
24
use Koha::AuthorisedValueCategory;
24
use Koha::AuthorisedValueCategory;
25
use Koha::MarcSubfieldStructures;
25
26
26
use base qw(Koha::Objects);
27
use base qw(Koha::Objects);
27
28
(-)a/Koha/Template/Plugin/AuthorisedValues.pm (+28 lines)
Lines 23-28 use base qw( Template::Plugin ); Link Here
23
23
24
use C4::Koha;
24
use C4::Koha;
25
use Koha::AuthorisedValues;
25
use Koha::AuthorisedValues;
26
use Koha::AuthorisedValueCategories;
26
27
27
sub GetByCode {
28
sub GetByCode {
28
    my ( $self, $category, $code, $opac ) = @_;
29
    my ( $self, $category, $code, $opac ) = @_;
Lines 68-73 sub GetCategories { Link Here
68
    ];
69
    ];
69
}
70
}
70
71
72
sub GetDescriptionByKohaField {
73
    my ( $self, $params ) = @_;
74
    my $frameworkcode    = $params->{frameworkcode} || '';
75
    my $kohafield        = $params->{kohafield};
76
    my $authorised_value = $params->{authorised_value};
77
    my $description = Koha::AuthorisedValues->get_description_by_koha_field(
78
        {
79
            frameworkcode    => $frameworkcode,
80
            kohafield        => $kohafield,
81
            authorised_value => $authorised_value
82
        }
83
    );
84
    return $description ? $description->{lib} : $authorised_value;
85
}
86
87
sub GetDescriptionsByKohaField {
88
    my ( $self, $params ) = @_;
89
90
    my $frameworkcode    = $params->{frameworkcode} || '';
91
    my $kohafield        = $params->{kohafield};
92
93
    return Koha::AuthorisedValues->get_descriptions_by_koha_field({
94
        frameworkcode => $frameworkcode,
95
        kohafield     => $kohafield,
96
    });
97
}
98
71
1;
99
1;
72
100
73
=head1 NAME
101
=head1 NAME
(-)a/catalogue/item-export.pl (+64 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2017 BibLibre
4
#
5
# This file is part of Koha
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
use CGI;
23
24
use C4::Auth;
25
use C4::Output;
26
27
my $cgi = new CGI;
28
29
my ($template, $borrowernumber, $cookie) = get_template_and_user({
30
    template_name => 'catalogue/itemsearch_csv.tt',
31
    query => $cgi,
32
    type => 'intranet',
33
    authnotrequired => 0,
34
    flagsrequired   => { catalogue => 1 },
35
});
36
37
my @itemnumbers = $cgi->multi_param('itemnumber');
38
my $format = $cgi->param('format') // 'csv';
39
40
my @items = Koha::Items->search({ itemnumber => { -in => \@itemnumbers } });
41
42
if ($format eq 'barcodes') {
43
    print $cgi->header({
44
        type => 'text/plain',
45
        attachment => 'barcodes.txt',
46
    });
47
48
    foreach my $item (@items) {
49
        print $item->barcode . "\n";
50
    }
51
    exit;
52
}
53
54
$template->param(
55
    results => \@items,
56
);
57
58
print $cgi->header({
59
    type => 'text/csv',
60
    attachment => 'items.csv',
61
});
62
for my $line ( split '\n', $template->output ) {
63
    print "$line\n" unless $line =~ m|^\s*$|;
64
}
(-)a/catalogue/itemsearch.pl (-48 / +4 lines)
Lines 90-101 my ($template, $borrowernumber, $cookie) = get_template_and_user({ Link Here
90
    flagsrequired   => { catalogue => 1 },
90
    flagsrequired   => { catalogue => 1 },
91
});
91
});
92
92
93
my $mss = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.notforloan', authorised_value => { not => undef } });
94
my $notforloan_values = $mss->count ? GetAuthorisedValues($mss->next->authorised_value) : [];
95
96
$mss = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.location', authorised_value => { not => undef } });
97
my $location_values = $mss->count ? GetAuthorisedValues($mss->next->authorised_value) : [];
98
99
if (scalar keys %params > 0) {
93
if (scalar keys %params > 0) {
100
    # Parameters given, it's a search
94
    # Parameters given, it's a search
101
95
Lines 213-237 if (scalar keys %params > 0) { Link Here
213
    }
207
    }
214
208
215
    if ($results) {
209
    if ($results) {
216
        # Get notforloan labels
217
        my $notforloan_map = {};
218
        foreach my $nfl_value (@$notforloan_values) {
219
            $notforloan_map->{$nfl_value->{authorised_value}} = $nfl_value->{lib};
220
        }
221
222
        # Get location labels
223
        my $location_map = {};
224
        foreach my $loc_value (@$location_values) {
225
            $location_map->{$loc_value->{authorised_value}} = $loc_value->{lib};
226
        }
227
228
        foreach my $item (@$results) {
210
        foreach my $item (@$results) {
229
            $item->{biblio} = GetBiblio($item->{biblionumber});
211
            $item->{biblio} = GetBiblio($item->{biblionumber});
230
            ($item->{biblioitem}) = GetBiblioItemByBiblioNumber($item->{biblionumber});
212
            ($item->{biblioitem}) = GetBiblioItemByBiblioNumber($item->{biblionumber});
231
            $item->{status} = $notforloan_map->{$item->{notforloan}};
232
            if (defined $item->{location}) {
233
                $item->{location} = $location_map->{$item->{location}};
234
            }
235
        }
213
        }
236
    }
214
    }
237
215
Lines 261-273 if (scalar keys %params > 0) { Link Here
261
# Display the search form
239
# Display the search form
262
240
263
my @branches = map { value => $_->branchcode, label => $_->branchname }, Koha::Libraries->search( {}, { order_by => 'branchname' } );
241
my @branches = map { value => $_->branchcode, label => $_->branchname }, Koha::Libraries->search( {}, { order_by => 'branchname' } );
264
my @locations;
265
foreach my $location (@$location_values) {
266
    push @locations, {
267
        value => $location->{authorised_value},
268
        label => $location->{lib} // $location->{authorised_value},
269
    };
270
}
271
my @itemtypes;
242
my @itemtypes;
272
foreach my $itemtype ( Koha::ItemTypes->search ) {
243
foreach my $itemtype ( Koha::ItemTypes->search ) {
273
    push @itemtypes, {
244
    push @itemtypes, {
Lines 276-298 foreach my $itemtype ( Koha::ItemTypes->search ) { Link Here
276
    };
247
    };
277
}
248
}
278
249
279
$mss = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.ccode', authorised_value => { not => undef } });
250
my @ccodes = Koha::AuthorisedValues->get_descriptions_by_koha_field({ kohafield => 'items.ccode' });
280
my $ccode_avcode = $mss->count ? $mss->next->authorised_value : 'CCODE';
251
foreach my $ccode (@ccodes) {
281
my $ccodes = GetAuthorisedValues($ccode_avcode);
252
    $ccode->{value} = $ccode->{authorised_value},
282
my @ccodes;
253
    $ccode->{label} = $ccode->{lib},
283
foreach my $ccode (@$ccodes) {
284
    push @ccodes, {
285
        value => $ccode->{authorised_value},
286
        label => $ccode->{lib},
287
    };
288
}
289
290
my @notforloans;
291
foreach my $value (@$notforloan_values) {
292
    push @notforloans, {
293
        value => $value->{authorised_value},
294
        label => $value->{lib},
295
    };
296
}
254
}
297
255
298
my @items_search_fields = GetItemSearchFields();
256
my @items_search_fields = GetItemSearchFields();
Lines 306-315 foreach my $field (@items_search_fields) { Link Here
306
264
307
$template->param(
265
$template->param(
308
    branches => \@branches,
266
    branches => \@branches,
309
    locations => \@locations,
310
    itemtypes => \@itemtypes,
267
    itemtypes => \@itemtypes,
311
    ccodes => \@ccodes,
268
    ccodes => \@ccodes,
312
    notforloans => \@notforloans,
313
    items_search_fields => \@items_search_fields,
269
    items_search_fields => \@items_search_fields,
314
    authorised_values_json => to_json($authorised_values),
270
    authorised_values_json => to_json($authorised_values),
315
);
271
);
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.csv.inc (-1 / +2 lines)
Lines 1-5 Link Here
1
[%- USE Branches -%]
1
[%- USE Branches -%]
2
[%- USE Koha -%]
2
[%- USE Koha -%]
3
[%- USE AuthorisedValues -%]
3
[%- biblio = item.biblio -%]
4
[%- biblio = item.biblio -%]
4
[%- biblioitem = item.biblioitem -%]
5
[%- biblioitem = item.biblioitem -%]
5
"[% 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 %]"
6
"[% 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 %]", "[% AuthorisedValues.GetDescriptionByKohaField( frameworkcode => biblio.frameworkcode, kohafield => 'items.location', authorised_value => item.location) |html %]", "[% item.stocknumber |html %]", "[% AuthorisedValues.GetDescriptionByKohaField(frameworkcode => biblio.frameworkcode, kohafield => 'items.notforloan', authorised_value => item.notforloan) |html %]", "[% (item.issues || 0) |html %]"
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.json.inc (-2 / +6 lines)
Lines 1-9 Link Here
1
[%- USE Branches -%]
1
[%- USE Branches -%]
2
[%- USE Koha -%]
2
[%- USE Koha -%]
3
[%- USE AuthorisedValues -%]
3
[%- biblio = item.biblio -%]
4
[%- biblio = item.biblio -%]
4
[%- biblioitem = item.biblioitem -%]
5
[%- biblioitem = item.biblioitem -%]
5
[
6
[
6
  "[% FILTER escape_quotes = replace('"', '\"') ~%]
7
  "[% FILTER escape_quotes = replace('"', '\"') ~%]
8
    <input type="checkbox" name="itemnumber" value="[% item.itemnumber %]"/>
9
  [%~ END %]",
10
  "[% FILTER escape_quotes ~%]
7
    <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 %]
11
    <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 %]
8
  [%~ END %]",
12
  [%~ END %]",
9
  "[% (biblioitem.publicationyear || biblio.copyrightdate) |html %]",
13
  "[% (biblioitem.publicationyear || biblio.copyrightdate) |html %]",
Lines 15-23 Link Here
15
  "[% item.itemcallnumber |html %]",
19
  "[% item.itemcallnumber |html %]",
16
  "[% Branches.GetName(item.homebranch) |html %]",
20
  "[% Branches.GetName(item.homebranch) |html %]",
17
  "[% Branches.GetName(item.holdingbranch) |html %]",
21
  "[% Branches.GetName(item.holdingbranch) |html %]",
18
  "[% item.location |html %]",
22
  "[% AuthorisedValues.GetDescriptionByKohaField( frameworkcode => biblio.frameworkcode, kohafield => 'items.location', authorised_value => item.location) | html %]",
19
  "[% item.stocknumber |html %]",
23
  "[% item.stocknumber |html %]",
20
  "[% item.status |html %]",
24
  "[% AuthorisedValues.GetDescriptionByKohaField( frameworkcode => biblio.frameworkcode, kohafield => 'items.notforloan', authorised_value => item.notforloan) | html %]",
21
  "[% (item.issues || 0) |html %]",
25
  "[% (item.issues || 0) |html %]",
22
  "[% FILTER escape_quotes ~%]
26
  "[% FILTER escape_quotes ~%]
23
    <a href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=[% item.biblionumber %]&itemnumber=[% item.itemnumber %]">Edit</a>
27
    <a href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=[% item.biblionumber %]&itemnumber=[% item.itemnumber %]">Edit</a>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt (-17 / +85 lines)
Lines 1-5 Link Here
1
[% USE CGI %]
1
[% USE CGI %]
2
[% USE JSON.Escape %]
2
[% USE JSON.Escape %]
3
[% USE AuthorisedValues %]
3
4
4
[% BLOCK form_label %]
5
[% BLOCK form_label %]
5
  [% SWITCH label %]
6
  [% SWITCH label %]
Lines 155-160 Link Here
155
  </div>
156
  </div>
156
[% END %]
157
[% END %]
157
158
159
[% notforloans = AuthorisedValues.GetDescriptionsByKohaField({ kohafield = 'items.notforloan' }) %]
160
[% FOREACH nfl IN notforloans %]
161
    [% nfl.value = nfl.authorised_value %]
162
    [% nfl.label = nfl.lib %]
163
[% END %]
164
165
[% locations = AuthorisedValues.GetDescriptionsByKohaField({ kohafield = 'items.location' }) %]
166
[% FOREACH loc IN locations %]
167
    [% loc.value = loc.authorised_value %]
168
    [% loc.label = loc.lib %]
169
[% END %]
170
158
[%# Page starts here %]
171
[%# Page starts here %]
159
172
160
[% INCLUDE 'doc-head-open.inc' %]
173
[% INCLUDE 'doc-head-open.inc' %]
Lines 207-212 Link Here
207
    function submitForm($form) {
220
    function submitForm($form) {
208
      var tr = ''
221
      var tr = ''
209
        + '    <tr>'
222
        + '    <tr>'
223
        + '      <th></th>'
210
        + '      <th>' + _("Title") + '</th>'
224
        + '      <th>' + _("Title") + '</th>'
211
        + '      <th>' + _("Publication date") + '</th>'
225
        + '      <th>' + _("Publication date") + '</th>'
212
        + '      <th>' + _("Publisher") + '</th>'
226
        + '      <th>' + _("Publisher") + '</th>'
Lines 239-276 Link Here
239
          $('#item-search-block').show();
253
          $('#item-search-block').show();
240
        });
254
        });
241
255
256
      function exportItems(format) {
257
        var itemnumbers = [];
258
        $('#results').find('input[name="itemnumber"]:checked').each(function() {
259
          itemnumbers.push($(this).val());
260
        });
261
        if (itemnumbers.length) {
262
          var href = '/cgi-bin/koha/catalogue/item-export.pl?format=' + format;
263
          href += '&itemnumber=' + itemnumbers.join('&itemnumber=');
264
          location = href;
265
        } else {
266
          $('#format-' + format).prop('checked', true);
267
          $('#itemsearchform').submit();
268
          $('#format-html').prop('checked', true);
269
        }
270
      }
271
242
      var csvExportLink = $('<a>')
272
      var csvExportLink = $('<a>')
243
        .attr('href', '#')
273
        .attr('href', '#')
244
        .html(_("Export results to CSV"))
274
        .html(_("CSV"))
245
        .addClass('btn btn-default btn-xs')
246
        .on('click', function(e) {
275
        .on('click', function(e) {
247
          e.preventDefault();
276
          e.preventDefault();
248
          $('#format-csv').prop('checked', true);
277
          exportItems('csv')
249
          $('#itemsearchform').submit();
250
          $('#format-html').prop('checked', true);
251
        });
278
        });
252
      var barcodesExportLink = $('<a>')
279
      var barcodesExportLink = $('<a>')
253
        .attr('href', '#')
280
        .attr('href', '#')
254
        .html(_("Export results to barcodes file"))
281
        .html(_("Barcodes file"))
255
        .addClass('btn btn-default btn-xs')
256
        .on('click', function(e) {
282
        .on('click', function(e) {
257
          e.preventDefault();
283
          e.preventDefault();
258
          $('#format-barcodes').prop('checked', true);
284
          exportItems('barcodes');
259
          $('#itemsearchform').submit();
260
          $('#format-html').prop('checked', true);
261
        });
285
        });
262
286
263
      var editSearchAndExportLinks = $('<p>')
287
      var exportButton = $('<div>')
264
        .append(editSearchLink)
288
        .addClass('btn-group')
265
        .append(' | ')
289
        .append($('<button>')
266
        .append(csvExportLink)
290
            .addClass('btn btn-default btn-xs dropdown-toggle')
291
            .attr('id', 'export-button')
292
            .attr('data-toggle', 'dropdown')
293
            .attr('aria-haspopup', 'true')
294
            .attr('aria-expanded', 'false')
295
            .html(_("Export all results to") + ' <span class="caret"></span>'))
296
        .append($('<ul>')
297
            .addClass('dropdown-menu')
298
            .append($('<li>').append(csvExportLink))
299
            .append($('<li>').append(barcodesExportLink)));
300
301
      var selectVisibleRows = $('<a>')
302
        .attr('href', '#')
303
        .append('<i class="fa fa-check"></i> ')
304
        .append(_("Select visible rows"))
305
        .on('click', function(e) {
306
            e.preventDefault();
307
            $('#results input[type="checkbox"]').prop('checked', true).change();
308
        });
309
      var clearSelection = $('<a>')
310
        .attr('href', '#')
311
        .append('<i class="fa fa-remove"></i> ')
312
        .append(_("Clear selection"))
313
        .on('click', function(e) {
314
            e.preventDefault();
315
            $('#results input[type="checkbox"]').prop('checked', false).change();
316
        });
317
      var exportLinks = $('<p>')
318
        .append(selectVisibleRows)
267
        .append(' ')
319
        .append(' ')
268
        .append(barcodesExportLink);
320
        .append(clearSelection)
321
        .append(' | ')
322
        .append(exportButton);
269
323
270
      var results_heading = $('<div>').addClass('results-heading')
324
      var results_heading = $('<div>').addClass('results-heading')
271
        .append("<h1>" + _("Item search results") + "</h1>")
325
        .append("<h1>" + _("Item search results") + "</h1>")
272
        .append($('<p>').append(advSearchLink))
326
        .append($('<p>').append(advSearchLink))
273
        .append(editSearchAndExportLinks);
327
        .append($('<p>').append(editSearchLink))
328
        .append(exportLinks);
274
      $('#results-wrapper').empty()
329
      $('#results-wrapper').empty()
275
        .append(results_heading)
330
        .append(results_heading)
276
        .append(table);
331
        .append(table);
Lines 309-315 Link Here
309
          });
364
          });
310
        },
365
        },
311
        'sDom': '<"top pager"ilp>t<"bottom pager"ip>r',
366
        'sDom': '<"top pager"ilp>t<"bottom pager"ip>r',
367
        'aaSorting': [[1, 'asc']],
312
        'aoColumns': [
368
        'aoColumns': [
369
          { 'sName': 'checkbox', 'bSortable': false },
313
          { 'sName': 'title' },
370
          { 'sName': 'title' },
314
          { 'sName': 'publicationyear' },
371
          { 'sName': 'publicationyear' },
315
          { 'sName': 'publishercode' },
372
          { 'sName': 'publishercode' },
Lines 322-333 Link Here
322
          { 'sName': 'stocknumber' },
379
          { 'sName': 'stocknumber' },
323
          { 'sName': 'notforloan' },
380
          { 'sName': 'notforloan' },
324
          { 'sName': 'issues' },
381
          { 'sName': 'issues' },
325
          { 'sName': 'checkbox', 'bSortable': false }
382
          { 'sName': 'actions', 'bSortable': false }
326
        ],
383
        ],
327
        "sPaginationType": "full_numbers"
384
        "sPaginationType": "full_numbers"
328
      })).columnFilter({
385
      })).columnFilter({
329
        'sPlaceHolder': 'head:after',
386
        'sPlaceHolder': 'head:after',
330
        'aoColumns': [
387
        'aoColumns': [
388
          null,
331
          { 'type': 'text' },
389
          { 'type': 'text' },
332
          { 'type': 'text' },
390
          { 'type': 'text' },
333
          { 'type': 'text' },
391
          { 'type': 'text' },
Lines 351-356 Link Here
351
          null
409
          null
352
        ]
410
        ]
353
      });
411
      });
412
413
      $('#results').on('change', 'input[type="checkbox"]', function() {
414
        var countSelected = $(this).parents('table').find('input:checked').length;
415
        var caret = ' <span class="caret">';
416
        if (countSelected > 0) {
417
          $('#export-button').html(_("Export selected results to") + caret);
418
        } else {
419
          $('#export-button').html(_("Export all results to") + caret);
420
        }
421
      })
354
    }
422
    }
355
423
356
    $(document).ready(function () {
424
    $(document).ready(function () {
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch_csv.tt (-2 / +1 lines)
Lines 1-4 Link Here
1
[% INCLUDE csv_headers/catalogue/itemsearch.tt %]
1
[% INCLUDE csv_headers/catalogue/itemsearch.tt %]
2
[% FOREACH item IN results -%]
2
[% FOREACH item IN results -%]
3
  [% INCLUDE 'catalogue/itemsearch_item.csv.inc' item = item +%]
3
  [%- INCLUDE 'catalogue/itemsearch_item.csv.inc' item = item +%]
4
[%- END -%]
4
[%- END -%]
5
- 

Return to bug 18433