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

(-)a/C4/Items.pm (+6 lines)
Lines 1219-1224 $filter->{fromDate} = '01/01/2013'; #Filters only serial issues by the serialite Link Here
1219
$filter->{toDate} = '31/12/2014';   #Filters only serial issues by the serialitems.publisheddate
1219
$filter->{toDate} = '31/12/2014';   #Filters only serial issues by the serialitems.publisheddate
1220
                                          #The ending date in C4::Context->preference('dateformat') format
1220
                                          #The ending date in C4::Context->preference('dateformat') format
1221
$filter->{limit} = 15;              #Limits the returning set to this many items
1221
$filter->{limit} = 15;              #Limits the returning set to this many items
1222
$filter->{itemnumber} = 165;        #Returns the item with this itemnumber
1222
1223
1223
Filters are expected to be validated! If a filter is not defined, that filter is not present in the $filter-HASH
1224
Filters are expected to be validated! If a filter is not defined, that filter is not present in the $filter-HASH
1224
1225
Lines 1341-1346 sub GetItemsInfo { Link Here
1341
        }
1342
        }
1342
        push @$queryParams, $filter->{toDate};
1343
        push @$queryParams, $filter->{toDate};
1343
    }
1344
    }
1345
    if (exists $filter->{itemnumber}) {
1346
        push @$queryParams, $filter->{itemnumber};
1347
        $query .= " AND items.itemnumber = ?";
1348
    }
1349
1344
1350
1345
    $query .= "ORDER BY home.branchname, items.enumchron, LPAD( items.copynumber, 8, '0' ), items.dateaccessioned DESC" ;
1351
    $query .= "ORDER BY home.branchname, items.enumchron, LPAD( items.copynumber, 8, '0' ), items.dateaccessioned DESC" ;
1346
    if (exists $filter->{limit}) {
1352
    if (exists $filter->{limit}) {
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 270-275 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
270
('OpacShowLibrariesPulldownMobile','1',NULL,'Show the libraries pulldown on the mobile version of the OPAC.','YesNo'),
270
('OpacShowLibrariesPulldownMobile','1',NULL,'Show the libraries pulldown on the mobile version of the OPAC.','YesNo'),
271
('OpacShowRecentComments','0',NULL,'If ON a link to recent comments will appear in the OPAC masthead','YesNo'),
271
('OpacShowRecentComments','0',NULL,'If ON a link to recent comments will appear in the OPAC masthead','YesNo'),
272
('OPACShowUnusedAuthorities','1','','Show authorities that are not being used in the OPAC.','YesNo'),
272
('OPACShowUnusedAuthorities','1','','Show authorities that are not being used in the OPAC.','YesNo'),
273
('OPACShowPlaceItemLevelHold','0',NULL,'Allow placing a item-level hold from the detailed biblio view.','YesNo'),
273
('opacsmallimage','','','Enter a complete URL to an image to replace the default Koha logo','free'),
274
('opacsmallimage','','','Enter a complete URL to an image to replace the default Koha logo','free'),
274
('OpacStarRatings','all','disable|all|details',NULL,'Choice'),
275
('OpacStarRatings','all','disable|all|details',NULL,'Choice'),
275
('OpacSuppression','0','','Turn ON the OPAC Suppression feature, requires further setup, ask your system administrator for details','YesNo'),
276
('OpacSuppression','0','','Turn ON the OPAC Suppression feature, requires further setup, ask your system administrator for details','YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref (+7 lines)
Lines 131-136 OPAC: Link Here
131
                  no: "Don't show"
131
                  no: "Don't show"
132
            - the item's barcode on the holdings tab.
132
            - the item's barcode on the holdings tab.
133
        -
133
        -
134
            - pref: OPACShowPlaceItemLevelHold
135
              default: 0
136
              choices:
137
                  yes: "Allow"
138
                  no : "Don't allow"
139
            - placing a item-level hold from the detailed biblio view. This is always enabled for serials because serials need only item-level holds.
140
        -
134
            - pref: OpacHighlightedWords
141
            - pref: OpacHighlightedWords
135
              choices:
142
              choices:
136
                  yes: Highlight
143
                  yes: Highlight
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt (-1 / +10 lines)
Lines 132-137 Link Here
132
                    null,
132
                    null,
133
                [% END %]
133
                [% END %]
134
                [% IF ( ShowCourseReservesHeader ) %]null,[% END %]
134
                [% IF ( ShowCourseReservesHeader ) %]null,[% END %]
135
                [% IF ( isSerial ) %]null,[% END %]
135
            ]
136
            ]
136
        }));
137
        }));
137
138
Lines 1063-1069 YAHOO.util.Event.onContentReady("furtherm", function () { Link Here
1063
1064
1064
    [% IF ( lotsofitems ) %]
1065
    [% IF ( lotsofitems ) %]
1065
        <p>
1066
        <p>
1066
            [% IF noBranchItems %]
1067
            [% IF userBranchNotDefined %]
1067
                Limiting items to the most recent received last year.</br>
1068
                Limiting items to the most recent received last year.</br>
1068
            [% ELSE %]
1069
            [% ELSE %]
1069
                Showing only the most recent items from your branch.</br>
1070
                Showing only the most recent items from your branch.</br>
Lines 1550-1555 YAHOO.util.Event.onContentReady("furtherm", function () { Link Here
1550
            <th>Item hold queue priority</th>
1551
            <th>Item hold queue priority</th>
1551
        [% END %]
1552
        [% END %]
1552
        [% IF ( ShowCourseReservesHeader ) %]<th id="item_coursereserves">Course reserves</th>[% END %]
1553
        [% IF ( ShowCourseReservesHeader ) %]<th id="item_coursereserves">Course reserves</th>[% END %]
1554
        [% IF ( isSerial ) %]<th id="placeItemLevelHoldTh">Reserve</th>[% END %]
1553
        </tr></thead>
1555
        </tr></thead>
1554
	    <tbody>[% FOREACH ITEM_RESULT IN items %]
1556
	    <tbody>[% FOREACH ITEM_RESULT IN items %]
1555
      [% IF ITEM_RESULT.this_branch %]
1557
      [% IF ITEM_RESULT.this_branch %]
Lines 1630-1635 YAHOO.util.Event.onContentReady("furtherm", function () { Link Here
1630
                [% END %]
1632
                [% END %]
1631
            </td>
1633
            </td>
1632
        [% END %]
1634
        [% END %]
1635
        [% IF OPACShowPlaceItemLevelHold || isSerial %]
1636
            <td>
1637
                <a href="opac-reserve.pl?biblionumber=[% biblionumber %]&itemnumber=[% ITEM_RESULT.itemnumber %]">
1638
                    Place hold
1639
                </a>
1640
            </td>
1641
        [% END %]
1633
	    </tr>
1642
	    </tr>
1634
	    [% END %]</tbody>
1643
	    [% END %]</tbody>
1635
	</table>
1644
	</table>
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt (-6 / +10 lines)
Lines 425-430 Link Here
425
                            <!-- ITEM HOLDS -->
425
                            <!-- ITEM HOLDS -->
426
426
427
                                <li class="radio">
427
                                <li class="radio">
428
                                 [% UNLESS singleItemLevelHold %]
428
                                  [% UNLESS ( bibitemloo.holdable ) %]
429
                                  [% UNLESS ( bibitemloo.holdable ) %]
429
                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
430
                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
430
                                           id="reqany_[% bibitemloo.biblionumber %]"
431
                                           id="reqany_[% bibitemloo.biblionumber %]"
Lines 437-447 Link Here
437
                                           id="reqany_[% bibitemloo.biblionumber %]"
438
                                           id="reqany_[% bibitemloo.biblionumber %]"
438
                                           class="selectany"
439
                                           class="selectany"
439
                                           value="Any"
440
                                           value="Any"
440
                                           checked="checked"
441
                                           [% UNLESS singleItemLevelHold %] checked="checked" [% END %]
441
                                    />
442
                                    />
442
                                  [% END %]
443
                                  [% END %]
443
444
444
                                  <label for="reqany_[% bibitemloo.biblionumber %]">Next available copy</label>
445
                                  <label for="reqany_[% bibitemloo.biblionumber %]">Next available copy</label>
446
                                 [% END %][%# IF singleItemLevelHold %]
445
                                  [% UNLESS ( bibitemloo.holdable ) %]
447
                                  [% UNLESS ( bibitemloo.holdable ) %]
446
                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
448
                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
447
                                           id="reqspecific_[% bibitemloo.biblionumber %]"
449
                                           id="reqspecific_[% bibitemloo.biblionumber %]"
Lines 454-467 Link Here
454
                                           id="reqspecific_[% bibitemloo.biblionumber %]"
456
                                           id="reqspecific_[% bibitemloo.biblionumber %]"
455
                                           class="selectspecific"
457
                                           class="selectspecific"
456
                                           value="Specific"
458
                                           value="Specific"
459
                                           [% IF singleItemLevelHold %] checked="checked" [% END %]
457
                                    />
460
                                    />
458
                                  [% END %]
461
                                  [% END %]
459
                                  <label for="reqspecific_[% bibitemloo.biblionumber %]">A specific copy</label>
462
                                  <label for="reqspecific_[% bibitemloo.biblionumber %]">A specific copy</label>
460
                                </li>
463
                                </li>
461
464
462
                            [% END %]
465
                            [% END %]
463
                </ul>
464
                        [% END %]
466
                        [% END %]
467
                </ul>
465
                  [% IF ( OPACItemHolds ) %]
468
                  [% IF ( OPACItemHolds ) %]
466
                  [% IF ( bibitemloo.holdable ) %]
469
                  [% IF ( bibitemloo.holdable ) %]
467
470
Lines 489-495 Link Here
489
                              <td class="copy">
492
                              <td class="copy">
490
                                [% IF ( itemLoo.available ) %]
493
                                [% IF ( itemLoo.available ) %]
491
                                  <input type="radio" class="checkitem checkitem_[% bibitemloo.biblionumber %]" name="checkitem_[% bibitemloo.biblionumber %]"
494
                                  <input type="radio" class="checkitem checkitem_[% bibitemloo.biblionumber %]" name="checkitem_[% bibitemloo.biblionumber %]"
492
                                         value="[% itemLoo.itemnumber %]" />
495
                                         value="[% itemLoo.itemnumber %]"
496
                                         [% IF singleItemLevelHold %] checked="checked" [% END %]
497
                                         />
493
                                [% ELSE %]
498
                                [% ELSE %]
494
                                  <input disabled="disabled" type="radio" class="checkitem" name="checkitem" value="[% itemLoo.itemnumber %]" />
499
                                  <input disabled="disabled" type="radio" class="checkitem" name="checkitem" value="[% itemLoo.itemnumber %]" />
495
                                  <img src="/opac-tmpl/lib/famfamfam/silk/cross.png" alt="Cannot be put on hold" title="Cannot be put on hold" />
500
                                  <img src="/opac-tmpl/lib/famfamfam/silk/cross.png" alt="Cannot be put on hold" title="Cannot be put on hold" />
Lines 540-551 Link Here
540
                        </table>
545
                        </table>
541
                    </div>
546
                    </div>
542
547
543
                </fieldset>
544
                  [% END %]<!-- OPACItemHolds -->
545
546
                  [% END %]<!-- bib_available -->
548
                  [% END %]<!-- bib_available -->
547
549
550
                  [% END %]<!-- OPACItemHolds -->
548
            </div>
551
            </div>
552
                </fieldset>
549
                [% END %]
553
                [% END %]
550
554
551
              [% END %] <!-- if message -->
555
              [% END %] <!-- if message -->
(-)a/opac/opac-detail.pl (-22 / +15 lines)
Lines 77-83 $biblionumber = int($biblionumber); Link Here
77
##>> Handling the Serial issue filter parameters from the user
77
##>> Handling the Serial issue filter parameters from the user
78
##
78
##
79
# We can filter issues based on these five values.
79
# We can filter issues based on these five values.
80
my $filterBranchLimiter = $query->param('filterBranchLimiter') ? $query->param('filterBranchLimiter') : undef;
80
my $filterBranchLimiter = $query->param('filterBranchLimiter') ? $query->param('filterBranchLimiter') : '_ShowAll';
81
my $filterVolume = $query->param('filterVolume') ? $query->param('filterVolume') : undef;
81
my $filterVolume = $query->param('filterVolume') ? $query->param('filterVolume') : undef;
82
my $filterNumber = $query->param('filterNumber') ? $query->param('filterNumber') : undef;
82
my $filterNumber = $query->param('filterNumber') ? $query->param('filterNumber') : undef;
83
my $filterIssue = $query->param('filterIssue') ? $query->param('filterIssue') : undef;
83
my $filterIssue = $query->param('filterIssue') ? $query->param('filterIssue') : undef;
Lines 162-196 my @all_items; Link Here
162
if ($lotsofitems) {
162
if ($lotsofitems) {
163
    #Spare the poor old DB from this possibly excruciatinly huge read operation.
163
    #Spare the poor old DB from this possibly excruciatinly huge read operation.
164
    if (! scalar(%$filter)) { #Is the $filter empty?
164
    if (! scalar(%$filter)) { #Is the $filter empty?
165
166
        #Limit the amount of results to the system preference
167
        $filter->{limit} = C4::Context->preference('OPACmaxItemsOnDetail');
168
169
        #Limit display of Items based on the users branch
165
        #Limit display of Items based on the users branch
170
        if (C4::Context->userenv){
166
        if (C4::Context->userenv){
171
            $filter->{branch} = C4::Context->userenv->{branch};
167
            $filter->{branch} = C4::Context->userenv->{branch};
172
            $filterBranchLimiter = $filter->{branch}; #Making the branches loop react to this!
168
            $filterBranchLimiter = $filter->{branch}; #Making the branches loop react to this!
173
174
            @all_items = GetItemsInfo($biblionumber, $filter);
175
        }
169
        }
176
        #Or if branch cannot be defined or has no items, then display Items only from the past year
170
        #Or if branch cannot be defined, then display Items only from the past year
177
        if( ! (scalar(@all_items)) ) {
171
        else {
178
            delete $filter->{branch}; #Remove the branch filter as it gave no results
179
            undef $filterBranchLimiter;
180
181
            my $now = DateTime->now();
172
            my $now = DateTime->now();
182
            $now->set_year(  ($now->year() - 1)  );
173
            $now->set_year(  ($now->year() - 1)  );
183
            $filter->{fromDate} = Koha::DateUtils::output_pref({ dt => $now, dateformat => 'iso'});
174
            $filter->{fromDate} = Koha::DateUtils::output_pref({ dt => $now, dateformat => 'iso'});
184
            $template->param('noBranchItems' => 1);
175
            $template->param('userBranchNotDefined' => 1);
185
            @all_items = GetItemsInfo($biblionumber, $filter);
186
        }
176
        }
187
177
        $filter->{limit} = C4::Context->preference('OPACmaxItemsOnDetail');
188
    }
178
    }
189
}
179
}
190
#If we haven't found our items yet, then pull them using whatever we've got.
180
@all_items = GetItemsInfo($biblionumber, $filter);
191
if( ! (scalar(@all_items)) ) {
192
    @all_items = GetItemsInfo($biblionumber, $filter);
193
}
194
181
195
182
196
##Prepare the custom branches loop containing the _ShowAll entry to show issues from all libraries.
183
##Prepare the custom branches loop containing the _ShowAll entry to show issues from all libraries.
Lines 306-312 if ($session->param('busc')) { Link Here
306
293
307
        my $expanded_facet = $arrParamsBusc->{'expand'};
294
        my $expanded_facet = $arrParamsBusc->{'expand'};
308
        my $branches = GetBranches();
295
        my $branches = GetBranches();
309
        my $itemtypes = GetItemTypes;
310
        my @servers;
296
        my @servers;
311
        @servers = @{$arrParamsBusc->{'server'}} if $arrParamsBusc->{'server'};
297
        @servers = @{$arrParamsBusc->{'server'}} if $arrParamsBusc->{'server'};
312
        @servers = ("biblioserver") unless (@servers);
298
        @servers = ("biblioserver") unless (@servers);
Lines 317-323 if ($session->param('busc')) { Link Here
317
        $sort_by[0] = $default_sort_by if !$sort_by[0] && defined($default_sort_by);
303
        $sort_by[0] = $default_sort_by if !$sort_by[0] && defined($default_sort_by);
318
        my ($error, $results_hashref, $facets);
304
        my ($error, $results_hashref, $facets);
319
        eval {
305
        eval {
320
            ($error, $results_hashref, $facets) = getRecords($arrParamsBusc->{'query'},$arrParamsBusc->{'simple_query'},\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$itemtypes,$arrParamsBusc->{'query_type'},$arrParamsBusc->{'scan'});
306
            ($error, $results_hashref, $facets) = getRecords($arrParamsBusc->{'query'},$arrParamsBusc->{'simple_query'},\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$arrParamsBusc->{'query_type'},$arrParamsBusc->{'scan'});
321
        };
307
        };
322
        my $hits;
308
        my $hits;
323
        my @newresults;
309
        my @newresults;
Lines 705-711 if ( $show_holds_count || $show_priority) { Link Here
705
}
691
}
706
$template->param( show_priority => $has_hold ) ;
692
$template->param( show_priority => $has_hold ) ;
707
693
708
my $norequests = 1;
694
my $norequests = 1; #"No requests"-flag hides the "Place hold"-link in opac-detail-sidebar.inc
709
my %itemfields;
695
my %itemfields;
710
my (@itemloop, @otheritemloop);
696
my (@itemloop, @otheritemloop);
711
my $currentbranch = C4::Context->userenv ? C4::Context->userenv->{branch} : undef;
697
my $currentbranch = C4::Context->userenv ? C4::Context->userenv->{branch} : undef;
Lines 770-775 for my $itm (@items) { Link Here
770
    }
756
    }
771
}
757
}
772
758
759
#There is no point in enabling "Place hold" for Serials.
760
# Placing a title-level hold for a Serial is crazy since we don't want "any" item but instead the specific volume and number.
761
# Also choosing an item-level hold from opac-reserve.pl is problematic since there could be thousands of items.
762
$norequests = 1 if $template->{VARS}->{'isSerial'};
763
773
# Display only one tab if one items list is empty
764
# Display only one tab if one items list is empty
774
if (scalar(@itemloop) == 0 || scalar(@otheritemloop) == 0) {
765
if (scalar(@itemloop) == 0 || scalar(@otheritemloop) == 0) {
775
    $template->param(SeparateHoldings => 0);
766
    $template->param(SeparateHoldings => 0);
Lines 1217-1220 if ( length C4::Context->preference('NumberingFormulaParsingRegexp') < 3 ) { Link Here
1217
}
1208
}
1218
$template->{VARS}->{useFilterIssueInput} = 1 if (C4::Context->preference('FilterSerialsByIssue'));
1209
$template->{VARS}->{useFilterIssueInput} = 1 if (C4::Context->preference('FilterSerialsByIssue'));
1219
1210
1211
$template->param('OPACShowPlaceItemLevelHold',  C4::Context->preference('OPACShowPlaceItemLevelHold'));
1212
1220
output_html_with_http_headers $query, $cookie, $template->output;
1213
output_html_with_http_headers $query, $cookie, $template->output;
(-)a/opac/opac-reserve.pl (-3 / +11 lines)
Lines 73-80 if ($borr->{reservefee} > 0){ Link Here
73
my $branches = GetBranches();
73
my $branches = GetBranches();
74
my $itemTypes = GetItemTypes();
74
my $itemTypes = GetItemTypes();
75
75
76
# There are two ways of calling this script, with a single biblio num
76
# There are three ways of calling this script, with a single biblio num
77
# or multiple biblio nums.
77
# or multiple biblio nums or as a itemhold, where the target item has already been chosen.
78
my $targetItemnumber = $query->param('itemnumber') ? $query->param('itemnumber') : undef;
79
$template->param('singleItemLevelHold' => 1);
78
my $biblionumbers = $query->param('biblionumbers');
80
my $biblionumbers = $query->param('biblionumbers');
79
my $reserveMode = $query->param('reserve_mode');
81
my $reserveMode = $query->param('reserve_mode');
80
if ($reserveMode && ($reserveMode eq 'single')) {
82
if ($reserveMode && ($reserveMode eq 'single')) {
Lines 127-134 foreach my $biblioNumber (@biblionumbers) { Link Here
127
129
128
    my $biblioData = GetBiblioData($biblioNumber);
130
    my $biblioData = GetBiblioData($biblioNumber);
129
    $biblioDataHash{$biblioNumber} = $biblioData;
131
    $biblioDataHash{$biblioNumber} = $biblioData;
132
    my @itemInfos;
130
133
131
    my @itemInfos = GetItemsInfo($biblioNumber);
134
    if ($targetItemnumber) { #We just want the one item so use the filters to find it!
135
        @itemInfos = GetItemsInfo($biblioNumber, {itemnumber => $targetItemnumber});
136
    }
137
    else {
138
        @itemInfos = GetItemsInfo($biblioNumber);
139
    }
132
140
133
    my $marcrecord= GetMarcBiblio($biblioNumber);
141
    my $marcrecord= GetMarcBiblio($biblioNumber);
134
142
(-)a/t/db_dependent/Items.t (-5 / +9 lines)
Lines 145-151 subtest 'GetHiddenItemnumbers tests' => sub { Link Here
145
145
146
subtest 'Filter items tests' => sub {
146
subtest 'Filter items tests' => sub {
147
147
148
    plan tests => 3;
148
    plan tests => 2;
149
149
150
    # Start transaction
150
    # Start transaction
151
    $dbh->{AutoCommit} = 0;
151
    $dbh->{AutoCommit} = 0;
Lines 165-170 subtest 'Filter items tests' => sub { Link Here
165
              holdingbranch => 'MPL', },
165
              holdingbranch => 'MPL', },
166
            $biblionumber
166
            $biblionumber
167
    );
167
    );
168
    my ($item3_bibnum, $item3_bibitemnum, $item3_itemnumber) = AddItem(
169
            { homebranch => 'IPT',
170
              holdingbranch => 'IPT', },
171
            $biblionumber
172
    );
168
173
169
    # Testing the branch filter
174
    # Testing the branch filter
170
    my @shouldBeItem2 = C4::Items::GetItemsInfo($biblionumber, {branch => 'MPL'});
175
    my @shouldBeItem2 = C4::Items::GetItemsInfo($biblionumber, {branch => 'MPL'});
Lines 174-182 subtest 'Filter items tests' => sub { Link Here
174
    my @shouldBeEmpty = C4::Items::GetItemsInfo($biblionumber, {toDate => '01/01/1933'});
179
    my @shouldBeEmpty = C4::Items::GetItemsInfo($biblionumber, {toDate => '01/01/1933'});
175
    is( scalar(@shouldBeEmpty), 0, "Filtering by date");
180
    is( scalar(@shouldBeEmpty), 0, "Filtering by date");
176
181
177
    # Testing the limit filter
182
    # Testing the itemnumber filter
178
    @shouldBeEmpty = C4::Items::GetItemsInfo($biblionumber, {limit => 0});
183
    my @shouldBeItem3 = C4::Items::GetItemsInfo($biblionumber, {itemnumber => $item3_itemnumber});
179
    is( scalar(@shouldBeEmpty), 0, "Filtering by limit");
184
    is( $shouldBeItem3[0]->{itemnumber}, $item3_itemnumber, "Filtering by itemnumber");
180
};
185
};
181
186
182
# Helper method to set up a Biblio.
187
# Helper method to set up a Biblio.
183
- 

Return to bug 11157