@@ -, +, @@
-OPACShowPlaceItemLevelHold or
-ShowPlaceItemLevelHold
---
C4/Items.pm | 6 ++++++
catalogue/detail.pl | 6 ++++++
installer/data/mysql/sysprefs.sql | 2 ++
.../en/modules/admin/preferences/cataloguing.pref | 7 +++++++
.../prog/en/modules/admin/preferences/opac.pref | 7 +++++++
.../prog/en/modules/catalogue/detail.tt | 8 ++++++++
.../prog/en/modules/reserve/request.tt | 17 ++++++++++++++---
koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 11 ++++++++++-
.../opac-tmpl/prog/en/modules/opac-reserve.tt | 9 +++++++--
opac/opac-detail.pl | 9 ++++++++-
opac/opac-reserve.pl | 14 +++++++++++---
reserve/request.pl | 22 +++++++++++++++++++++-
t/db_dependent/Items.t | 9 +++++++++
13 files changed, 116 insertions(+), 11 deletions(-)
--- a/C4/Items.pm
+++ a/C4/Items.pm
@@ -1219,6 +1219,7 @@ $filter->{fromDate} = '01/01/2013'; #Filters only serial issues by the serialite
$filter->{toDate} = '31/12/2014'; #Filters only serial issues by the serialitems.publisheddate
#The ending date in C4::Context->preference('dateformat') format
$filter->{limit} = 15; #Limits the returning set to this many items
+$filter->{itemnumber} = 165; #Returns the item with this itemnumber
Filters are expected to be validated! If a filter is not defined, that filter is not present in the $filter-HASH
@@ -1341,6 +1342,11 @@ sub GetItemsInfo {
}
push @$queryParams, $filter->{toDate};
}
+ if (exists $filter->{itemnumber}) {
+ push @$queryParams, $filter->{itemnumber};
+ $query .= " AND items.itemnumber = ?";
+ }
+
$query .= "ORDER BY home.branchname, items.enumchron, LPAD( items.copynumber, 8, '0' ), items.dateaccessioned DESC" ;
if (exists $filter->{limit}) {
--- a/catalogue/detail.pl
+++ a/catalogue/detail.pl
@@ -143,6 +143,10 @@ my $dat = &GetBiblioData($biblionumber);
my $subscriptionsnumber = CountSubscriptionFromBiblionumber($biblionumber);
my @subscriptions = GetSubscriptions( $dat->{title}, $dat->{issn}, undef, $biblionumber );
my @subs;
+if (scalar(@subscriptions)) {
+ $template->param('isSerial',1);
+}
+
foreach my $subscription (@subscriptions) {
my %cell;
@@ -412,4 +416,6 @@ if (C4::Context->preference('TagsEnabled') and $tag_quantity = C4::Context->pref
my ( $holdcount, $holds ) = C4::Reserves::GetReservesFromBiblionumber($biblionumber,1);
$template->param( holdcount => $holdcount, holds => $holds );
+$template->param('ShowPlaceItemLevelHold', C4::Context->preference('ShowPlaceItemLevelHold'));
+
output_html_with_http_headers $query, $cookie, $template->output;
--- a/installer/data/mysql/sysprefs.sql
+++ a/installer/data/mysql/sysprefs.sql
@@ -270,6 +270,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
('OpacShowLibrariesPulldownMobile','1',NULL,'Show the libraries pulldown on the mobile version of the OPAC.','YesNo'),
('OpacShowRecentComments','0',NULL,'If ON a link to recent comments will appear in the OPAC masthead','YesNo'),
('OPACShowUnusedAuthorities','1','','Show authorities that are not being used in the OPAC.','YesNo'),
+('OPACShowPlaceItemLevelHold','0',NULL,'Allow placing a item-level hold from the detailed biblio view.','YesNo'),
('opacsmallimage','','','Enter a complete URL to an image to replace the default Koha logo','free'),
('OpacStarRatings','all','disable|all|details',NULL,'Choice'),
('OpacSuppression','0','','Turn ON the OPAC Suppression feature, requires further setup, ask your system administrator for details','YesNo'),
@@ -341,6 +342,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
('ShowPatronImageInWebBasedSelfCheck','0','','If ON, displays patron image when a patron uses web-based self-checkout','YesNo'),
('ShowReviewer','full','none|full|first|surname|firstandinitial|username','Choose how a commenter\'s identity is presented alongside comments in the OPAC','Choice'),
('ShowReviewerPhoto','1','','If ON, photo of reviewer will be shown beside comments in OPAC','YesNo'),
+('ShowPlaceItemLevelHold','0',NULL,'Allow placing a item-level hold from the detailed biblio view.','YesNo'),
('singleBranchMode','0',NULL,'Operate in Single-branch mode, hide branch selection in the OPAC','YesNo'),
('SlipCSS','',NULL,'Slips CSS url.','free'),
('SMSSendDriver','','','Sets which SMS::Send driver is used to send SMS messages.','free'),
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref
@@ -18,6 +18,13 @@ Cataloging:
yes: Display
no: "Don't Display"
- easy ways to create analytical record relationships
+ -
+ - pref: ShowPlaceItemLevelHold
+ default: 0
+ choices:
+ yes: "Allow"
+ no : "Don't allow"
+ - placing a item-level hold from the detailed biblio view. This is always enabled for serials because serials need only item-level holds.
Spine Labels:
-
- When using the quick spine label printer,
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref
@@ -131,6 +131,13 @@ OPAC:
no: "Don't show"
- the item's barcode on the holdings tab.
-
+ - pref: OPACShowPlaceItemLevelHold
+ default: 0
+ choices:
+ yes: "Allow"
+ no : "Don't allow"
+ - placing a item-level hold from the detailed biblio view. This is always enabled for serials because serials need only item-level holds.
+ -
- pref: OpacHighlightedWords
choices:
yes: Highlight
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt
@@ -422,6 +422,7 @@ function verify_images() {
[% IF ( hostrecords ) %]
Host records
[% END %]
[% IF ( analyze ) %]
Used in
[% END %]
[% IF ( ShowCourseReserves ) %]
Course Reserves
[% END %]
+ [% IF ( ShowPlaceItemLevelHold || isSerial ) %]
Reserve
[% END %]
@@ -590,6 +591,13 @@ function verify_images() {
[% END %]
[% END %]
+ [% IF ( ShowPlaceItemLevelHold || isSerial ) %]
+
+ [% END %]
[% END %]
--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt
+++ a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt
@@ -425,6 +425,7 @@
+ [% UNLESS singleItemLevelHold %]
[% UNLESS ( bibitemloo.holdable ) %]
[% END %]
+ [% END %][%# IF singleItemLevelHold %]
[% UNLESS ( bibitemloo.holdable ) %]
[% END %]
@@ -489,7 +492,9 @@
[% IF ( itemLoo.available ) %]
+ value="[% itemLoo.itemnumber %]"
+ [% IF singleItemLevelHold %] checked="checked" [% END %]
+ />
[% ELSE %]
--- a/opac/opac-detail.pl
+++ a/opac/opac-detail.pl
@@ -691,7 +691,7 @@ if ( $show_holds_count || $show_priority) {
}
$template->param( show_priority => $has_hold ) ;
-my $norequests = 1;
+my $norequests = 1; #"No requests"-flag hides the "Place hold"-link in opac-detail-sidebar.inc
my %itemfields;
my (@itemloop, @otheritemloop);
my $currentbranch = C4::Context->userenv ? C4::Context->userenv->{branch} : undef;
@@ -756,6 +756,11 @@ for my $itm (@items) {
}
}
+#There is no point in enabling "Place hold" for Serials.
+# Placing a title-level hold for a Serial is crazy since we don't want "any" item but instead the specific volume and number.
+# Also choosing an item-level hold from opac-reserve.pl is problematic since there could be thousands of items.
+$norequests = 1 if $template->{VARS}->{'isSerial'};
+
# Display only one tab if one items list is empty
if (scalar(@itemloop) == 0 || scalar(@otheritemloop) == 0) {
$template->param(SeparateHoldings => 0);
@@ -1203,4 +1208,6 @@ if ( length C4::Context->preference('NumberingFormulaParsingRegexp') < 3 ) {
}
$template->{VARS}->{useFilterIssueInput} = 1 if (C4::Context->preference('FilterSerialsByIssue'));
+$template->param('OPACShowPlaceItemLevelHold', C4::Context->preference('OPACShowPlaceItemLevelHold'));
+
output_html_with_http_headers $query, $cookie, $template->output;
--- a/opac/opac-reserve.pl
+++ a/opac/opac-reserve.pl
@@ -73,8 +73,10 @@ if ($borr->{reservefee} > 0){
my $branches = GetBranches();
my $itemTypes = GetItemTypes();
-# There are two ways of calling this script, with a single biblio num
-# or multiple biblio nums.
+# There are three ways of calling this script, with a single biblio num
+# or multiple biblio nums or as a itemhold, where the target item has already been chosen.
+my $targetItemnumber = $query->param('itemnumber') ? $query->param('itemnumber') : undef;
+$template->param('singleItemLevelHold' => 1);
my $biblionumbers = $query->param('biblionumbers');
my $reserveMode = $query->param('reserve_mode');
if ($reserveMode && ($reserveMode eq 'single')) {
@@ -127,8 +129,14 @@ foreach my $biblioNumber (@biblionumbers) {
my $biblioData = GetBiblioData($biblioNumber);
$biblioDataHash{$biblioNumber} = $biblioData;
+ my @itemInfos;
- my @itemInfos = GetItemsInfo($biblioNumber);
+ if ($targetItemnumber) { #We just want the one item so use the filters to find it!
+ @itemInfos = GetItemsInfo($biblioNumber, {itemnumber => $targetItemnumber});
+ }
+ else {
+ @itemInfos = GetItemsInfo($biblioNumber);
+ }
my $marcrecord= GetMarcBiblio($biblioNumber);
--- a/reserve/request.pl
+++ a/reserve/request.pl
@@ -57,10 +57,27 @@ my ( $template, $borrowernumber, $cookie, $flags ) = get_template_and_user(
}
);
+my $targetItemnumber = $input->param('itemnumber') ? $input->param('itemnumber') : undef;
+if ($targetItemnumber) {
+ $template->param('targetItemnumber', $targetItemnumber);
+ my $targetItem = C4::Items::GetItem($targetItemnumber);
+ if ($targetItem->{enumchron}) {
+ $template->param('targetItemTitle', $targetItem->{enumchron});
+ }
+ elsif ($targetItem->{barcode}) {
+ $template->param('targetItemTitle', $targetItem->{barcode});
+ }
+ else {
+ $template->param('targetItemTitle', $targetItem->{itemnumber});
+ }
+}
+
+
my $multihold = $input->param('multi_hold');
$template->param(multi_hold => $multihold);
my $showallitems = $input->param('showallitems');
+
# get Branches and Itemtypes
my $branches = GetBranches();
my $itemtypes = GetItemTypes();
@@ -243,7 +260,10 @@ foreach my $biblionumber (@biblionumbers) {
my @itemnumbers;
## $items is array of 'item' table numbers
- if (my $items = get_itemnumbers_of($biblionumber)->{$biblionumber}){
+ if ($targetItemnumber) { #If we just want to place a hold on one item
+ push @itemnumbers, $targetItemnumber;
+ }
+ elsif (my $items = get_itemnumbers_of($biblionumber)->{$biblionumber}){
@itemnumbers = @$items;
}
my @hostitems = get_hostitemnumbers_of($biblionumber);
--- a/t/db_dependent/Items.t
+++ a/t/db_dependent/Items.t
@@ -165,6 +165,11 @@ subtest 'Filter items tests' => sub {
holdingbranch => 'MPL', },
$biblionumber
);
+ my ($item3_bibnum, $item3_bibitemnum, $item3_itemnumber) = AddItem(
+ { homebranch => 'IPT',
+ holdingbranch => 'IPT', },
+ $biblionumber
+ );
# Testing the branch filter
my @shouldBeItem2 = C4::Items::GetItemsInfo($biblionumber, {branch => 'MPL'});
@@ -173,6 +178,10 @@ subtest 'Filter items tests' => sub {
# Testing the dates filter
my @shouldBeEmpty = C4::Items::GetItemsInfo($biblionumber, {toDate => '01/01/1933'});
is( scalar(@shouldBeEmpty), 0, "Filtering by date");
+
+ # Testing the itemnumber filter
+ my @shouldBeItem3 = C4::Items::GetItemsInfo($biblionumber, {itemnumber => $item3_itemnumber});
+ is( $shouldBeItem3[0]->{itemnumber}, $item3_itemnumber, "Filtering by itemnumber");
};
# Helper method to set up a Biblio.
--