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

(-)a/C4/Auth.pm (-1 lines)
Lines 397-403 sub get_template_and_user { Link Here
397
            OPACAmazonCoverImages     => C4::Context->preference("OPACAmazonCoverImages"),
397
            OPACAmazonCoverImages     => C4::Context->preference("OPACAmazonCoverImages"),
398
            OPACFRBRizeEditions       => C4::Context->preference("OPACFRBRizeEditions"),
398
            OPACFRBRizeEditions       => C4::Context->preference("OPACFRBRizeEditions"),
399
            OpacHighlightedWords       => C4::Context->preference("OpacHighlightedWords"),
399
            OpacHighlightedWords       => C4::Context->preference("OpacHighlightedWords"),
400
            OPACItemHolds             => C4::Context->preference("OPACItemHolds"),
401
            OPACShelfBrowser          => "". C4::Context->preference("OPACShelfBrowser"),
400
            OPACShelfBrowser          => "". C4::Context->preference("OPACShelfBrowser"),
402
            OpacShowRecentComments    => C4::Context->preference("OpacShowRecentComments"),
401
            OpacShowRecentComments    => C4::Context->preference("OpacShowRecentComments"),
403
            OPACURLOpenInNewWindow    => "" . C4::Context->preference("OPACURLOpenInNewWindow"),
402
            OPACURLOpenInNewWindow    => "" . C4::Context->preference("OPACURLOpenInNewWindow"),
(-)a/C4/ILSDI/Services.pm (-1 / +1 lines)
Lines 485-491 sub GetServices { Link Here
485
    my $canbookbereserved = CanBookBeReserved( $borrower, $biblionumber );
485
    my $canbookbereserved = CanBookBeReserved( $borrower, $biblionumber );
486
    if ($canbookbereserved) {
486
    if ($canbookbereserved) {
487
        push @availablefor, 'title level hold';
487
        push @availablefor, 'title level hold';
488
        my $canitembereserved = IsAvailableForItemLevelRequest($itemnumber);
488
        my $canitembereserved = IsAvailableForItemLevelRequest($item, $borrower);
489
        if ($canitembereserved) {
489
        if ($canitembereserved) {
490
            push @availablefor, 'item level hold';
490
            push @availablefor, 'item level hold';
491
        }
491
        }
(-)a/C4/Items.pm (+2 lines)
Lines 164-169 sub GetItem { Link Here
164
        ($data->{'serialseq'} , $data->{'publisheddate'}) = $ssth->fetchrow_array();
164
        ($data->{'serialseq'} , $data->{'publisheddate'}) = $ssth->fetchrow_array();
165
    }
165
    }
166
	#if we don't have an items.itype, use biblioitems.itemtype.
166
	#if we don't have an items.itype, use biblioitems.itemtype.
167
    # FIXME this should respect the itypes systempreference
168
    # if (C4::Context->preference('item-level_itypes')) {
167
	if( ! $data->{'itype'} ) {
169
	if( ! $data->{'itype'} ) {
168
		my $sth = $dbh->prepare("SELECT itemtype FROM biblioitems  WHERE biblionumber = ?");
170
		my $sth = $dbh->prepare("SELECT itemtype FROM biblioitems  WHERE biblionumber = ?");
169
		$sth->execute($data->{'biblionumber'});
171
		$sth->execute($data->{'biblionumber'});
(-)a/C4/Reserves.pm (-130 / +211 lines)
Lines 68-80 This modules provides somes functions to deal with reservations. Link Here
68
  The complete workflow is :
68
  The complete workflow is :
69
  ==== 1st use case ====
69
  ==== 1st use case ====
70
  patron request a document, 1st available :                      P >0, F=NULL, I=NULL
70
  patron request a document, 1st available :                      P >0, F=NULL, I=NULL
71
  a library having it run "transfertodo", and clic on the list    
71
  a library having it run "transfertodo", and clic on the list
72
         if there is no transfer to do, the reserve waiting
72
         if there is no transfer to do, the reserve waiting
73
         patron can pick it up                                    P =0, F=W,    I=filled 
73
         patron can pick it up                                    P =0, F=W,    I=filled
74
         if there is a transfer to do, write in branchtransfer    P =0, F=T,    I=filled
74
         if there is a transfer to do, write in branchtransfer    P =0, F=T,    I=filled
75
           The pickup library recieve the book, it check in       P =0, F=W,    I=filled
75
           The pickup library recieve the book, it check in       P =0, F=W,    I=filled
76
  The patron borrow the book                                      P =0, F=F,    I=filled
76
  The patron borrow the book                                      P =0, F=F,    I=filled
77
  
77
78
  ==== 2nd use case ====
78
  ==== 2nd use case ====
79
  patron requests a document, a given item,
79
  patron requests a document, a given item,
80
    If pickup is holding branch                                   P =0, F=W,   I=filled
80
    If pickup is holding branch                                   P =0, F=W,   I=filled
Lines 93-99 BEGIN { Link Here
93
    @ISA = qw(Exporter);
93
    @ISA = qw(Exporter);
94
    @EXPORT = qw(
94
    @EXPORT = qw(
95
        &AddReserve
95
        &AddReserve
96
  
96
97
        &GetReservesFromItemnumber
97
        &GetReservesFromItemnumber
98
        &GetReservesFromBiblionumber
98
        &GetReservesFromBiblionumber
99
        &GetReservesFromBorrowernumber
99
        &GetReservesFromBorrowernumber
Lines 103-111 BEGIN { Link Here
103
        &GetReserveFee
103
        &GetReserveFee
104
        &GetReserveInfo
104
        &GetReserveInfo
105
        &GetReserveStatus
105
        &GetReserveStatus
106
        
106
107
        &GetOtherReserves
107
        &GetOtherReserves
108
        
108
109
        &ModReserveFill
109
        &ModReserveFill
110
        &ModReserveAffect
110
        &ModReserveAffect
111
        &ModReserve
111
        &ModReserve
Lines 113-119 BEGIN { Link Here
113
        &ModReserveCancelAll
113
        &ModReserveCancelAll
114
        &ModReserveMinusPriority
114
        &ModReserveMinusPriority
115
        &MoveReserve
115
        &MoveReserve
116
        
116
117
        &CheckReserves
117
        &CheckReserves
118
        &CanBookBeReserved
118
        &CanBookBeReserved
119
	&CanItemBeReserved
119
	&CanItemBeReserved
Lines 123-129 BEGIN { Link Here
123
        &AutoUnsuspendReserves
123
        &AutoUnsuspendReserves
124
124
125
        &IsAvailableForItemLevelRequest
125
        &IsAvailableForItemLevelRequest
126
        
126
127
        &OPACItemHoldsAllowed
128
127
        &AlterPriority
129
        &AlterPriority
128
        &ToggleLowestPriority
130
        &ToggleLowestPriority
129
131
Lines 132-138 BEGIN { Link Here
132
        &SuspendAll
134
        &SuspendAll
133
    );
135
    );
134
    @EXPORT_OK = qw( MergeHolds );
136
    @EXPORT_OK = qw( MergeHolds );
135
}    
137
}
136
138
137
=head2 AddReserve
139
=head2 AddReserve
138
140
Lines 240-246 sub AddReserve { Link Here
240
    foreach (@$bibitems) {
242
    foreach (@$bibitems) {
241
        $sth->execute($borrowernumber, $biblionumber, $resdate, $_);
243
        $sth->execute($borrowernumber, $biblionumber, $resdate, $_);
242
    }
244
    }
243
        
245
244
    return;     # FIXME: why not have a useful return value?
246
    return;     # FIXME: why not have a useful return value?
245
}
247
}
246
248
Lines 302-308 sub GetReservesFromBiblionumber { Link Here
302
                push( @bibitemno, $bibitemnos );    # FIXME: inefficient: use fetchall_arrayref
304
                push( @bibitemno, $bibitemnos );    # FIXME: inefficient: use fetchall_arrayref
303
            }
305
            }
304
            my $count = scalar @bibitemno;
306
            my $count = scalar @bibitemno;
305
    
307
306
            # if we have two or more different specific itemtypes
308
            # if we have two or more different specific itemtypes
307
            # reserved by same person on same day
309
            # reserved by same person on same day
308
            my $bdata;
310
            my $bdata;
Lines 417-446 This function return 1 if an item can be issued by this borrower. Link Here
417
419
418
sub CanItemBeReserved{
420
sub CanItemBeReserved{
419
    my ($borrowernumber, $itemnumber) = @_;
421
    my ($borrowernumber, $itemnumber) = @_;
420
    
422
421
    my $dbh             = C4::Context->dbh;
423
    my $dbh             = C4::Context->dbh;
422
    my $allowedreserves = 0;
424
    my $allowedreserves = 0;
423
            
425
424
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
426
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
425
    my $itype         = C4::Context->preference('item-level_itypes') ? "itype" : "itemtype";
427
    my $itype         = C4::Context->preference('item-level_itypes') ? "itype" : "itemtype";
426
428
427
    # we retrieve borrowers and items informations #
429
    # we retrieve borrowers and items informations #
428
    my $item     = GetItem($itemnumber);
430
    my $item     = GetItem($itemnumber);
429
    my $borrower = C4::Members::GetMember('borrowernumber'=>$borrowernumber);     
431
    my $borrower = C4::Members::GetMember('borrowernumber'=>$borrowernumber);
430
    
432
431
    # we retrieve user rights on this itemtype and branchcode
433
    # we retrieve user rights on this itemtype and branchcode
432
    my $sth = $dbh->prepare("SELECT categorycode, itemtype, branchcode, reservesallowed 
434
    my $sth = $dbh->prepare("SELECT categorycode, itemtype, branchcode, reservesallowed
433
                             FROM issuingrules 
435
                             FROM issuingrules
434
                             WHERE (categorycode in (?,'*') ) 
436
                             WHERE (categorycode in (?,'*') )
435
                             AND (itemtype IN (?,'*')) 
437
                             AND (itemtype IN (?,'*'))
436
                             AND (branchcode IN (?,'*')) 
438
                             AND (branchcode IN (?,'*'))
437
                             ORDER BY 
439
                             ORDER BY
438
                               categorycode DESC, 
440
                               categorycode DESC,
439
                               itemtype     DESC, 
441
                               itemtype     DESC,
440
                               branchcode   DESC;"
442
                               branchcode   DESC;"
441
                           );
443
                           );
442
                           
444
443
    my $querycount ="SELECT 
445
    my $querycount ="SELECT
444
                            count(*) as count
446
                            count(*) as count
445
                            FROM reserves
447
                            FROM reserves
446
                                LEFT JOIN items USING (itemnumber)
448
                                LEFT JOIN items USING (itemnumber)
Lines 448-460 sub CanItemBeReserved{ Link Here
448
                                LEFT JOIN borrowers USING (borrowernumber)
450
                                LEFT JOIN borrowers USING (borrowernumber)
449
                            WHERE borrowernumber = ?
451
                            WHERE borrowernumber = ?
450
                                ";
452
                                ";
451
    
453
452
    
454
453
    my $itemtype     = $item->{$itype};
455
    my $itemtype     = $item->{$itype};
454
    my $categorycode = $borrower->{categorycode};
456
    my $categorycode = $borrower->{categorycode};
455
    my $branchcode   = "";
457
    my $branchcode   = "";
456
    my $branchfield  = "reserves.branchcode";
458
    my $branchfield  = "reserves.branchcode";
457
    
459
458
    if( $controlbranch eq "ItemHomeLibrary" ){
460
    if( $controlbranch eq "ItemHomeLibrary" ){
459
        $branchfield = "items.homebranch";
461
        $branchfield = "items.homebranch";
460
        $branchcode = $item->{homebranch};
462
        $branchcode = $item->{homebranch};
Lines 462-495 sub CanItemBeReserved{ Link Here
462
        $branchfield = "borrowers.branchcode";
464
        $branchfield = "borrowers.branchcode";
463
        $branchcode = $borrower->{branchcode};
465
        $branchcode = $borrower->{branchcode};
464
    }
466
    }
465
    
467
466
    # we retrieve rights 
468
    # we retrieve rights
467
    $sth->execute($categorycode, $itemtype, $branchcode);
469
    $sth->execute($categorycode, $itemtype, $branchcode);
468
    if(my $rights = $sth->fetchrow_hashref()){
470
    if(my $rights = $sth->fetchrow_hashref()){
469
        $itemtype        = $rights->{itemtype};
471
        $itemtype        = $rights->{itemtype};
470
        $allowedreserves = $rights->{reservesallowed}; 
472
        $allowedreserves = $rights->{reservesallowed};
471
    }else{
473
    }else{
472
        $itemtype = '*';
474
        $itemtype = '*';
473
    }
475
    }
474
    
476
475
    # we retrieve count
477
    # we retrieve count
476
    
478
477
    $querycount .= "AND $branchfield = ?";
479
    $querycount .= "AND $branchfield = ?";
478
    
480
479
    $querycount .= " AND $itype = ?" if ($itemtype ne "*");
481
    $querycount .= " AND $itype = ?" if ($itemtype ne "*");
480
    my $sthcount = $dbh->prepare($querycount);
482
    my $sthcount = $dbh->prepare($querycount);
481
    
483
482
    if($itemtype eq "*"){
484
    if($itemtype eq "*"){
483
        $sthcount->execute($borrowernumber, $branchcode);
485
        $sthcount->execute($borrowernumber, $branchcode);
484
    }else{
486
    }else{
485
        $sthcount->execute($borrowernumber, $branchcode, $itemtype);
487
        $sthcount->execute($borrowernumber, $branchcode, $itemtype);
486
    }
488
    }
487
    
489
488
    my $reservecount = "0";
490
    my $reservecount = "0";
489
    if(my $rowcount = $sthcount->fetchrow_hashref()){
491
    if(my $rowcount = $sthcount->fetchrow_hashref()){
490
        $reservecount = $rowcount->{count};
492
        $reservecount = $rowcount->{count};
491
    }
493
    }
492
    
493
    # we check if it's ok or not
494
    # we check if it's ok or not
494
    if( $reservecount < $allowedreserves ){
495
    if( $reservecount < $allowedreserves ){
495
        return 1;
496
        return 1;
Lines 688-695 sub GetReservesToBranch { Link Here
688
    my $dbh = C4::Context->dbh;
689
    my $dbh = C4::Context->dbh;
689
    my $sth = $dbh->prepare(
690
    my $sth = $dbh->prepare(
690
        "SELECT borrowernumber,reservedate,itemnumber,timestamp
691
        "SELECT borrowernumber,reservedate,itemnumber,timestamp
691
         FROM reserves 
692
         FROM reserves
692
         WHERE priority='0' 
693
         WHERE priority='0'
693
           AND branchcode=?"
694
           AND branchcode=?"
694
    );
695
    );
695
    $sth->execute( $frombranch );
696
    $sth->execute( $frombranch );
Lines 712-718 sub GetReservesForBranch { Link Here
712
    my ($frombranch) = @_;
713
    my ($frombranch) = @_;
713
    my $dbh          = C4::Context->dbh;
714
    my $dbh          = C4::Context->dbh;
714
	my $query        = "SELECT borrowernumber,reservedate,itemnumber,waitingdate
715
	my $query        = "SELECT borrowernumber,reservedate,itemnumber,waitingdate
715
        FROM   reserves 
716
        FROM   reserves
716
        WHERE   priority='0'
717
        WHERE   priority='0'
717
            AND found='W' ";
718
            AND found='W' ";
718
    if ($frombranch){
719
    if ($frombranch){
Lines 737-747 sub GetReservesForBranch { Link Here
737
738
738
sub GetReserveStatus {
739
sub GetReserveStatus {
739
    my ($itemnumber) = @_;
740
    my ($itemnumber) = @_;
740
    
741
741
    my $dbh = C4::Context->dbh;
742
    my $dbh = C4::Context->dbh;
742
    
743
743
    my $itemstatus = $dbh->prepare("SELECT found FROM reserves WHERE itemnumber = ?");
744
    my $itemstatus = $dbh->prepare("SELECT found FROM reserves WHERE itemnumber = ?");
744
    
745
745
    $itemstatus->execute($itemnumber);
746
    $itemstatus->execute($itemnumber);
746
    my ($found) = $itemstatus->fetchrow_array;
747
    my ($found) = $itemstatus->fetchrow_array;
747
    return $found;
748
    return $found;
Lines 803-809 sub CheckReserves { Link Here
803
           LEFT JOIN itemtypes   ON biblioitems.itemtype   = itemtypes.itemtype
804
           LEFT JOIN itemtypes   ON biblioitems.itemtype   = itemtypes.itemtype
804
        ";
805
        ";
805
    }
806
    }
806
   
807
807
    if ($item) {
808
    if ($item) {
808
        $sth = $dbh->prepare("$select WHERE itemnumber = ?");
809
        $sth = $dbh->prepare("$select WHERE itemnumber = ?");
809
        $sth->execute($item);
810
        $sth->execute($item);
Lines 818-824 sub CheckReserves { Link Here
818
    return ( '' ) unless $itemnumber; # bail if we got nothing.
819
    return ( '' ) unless $itemnumber; # bail if we got nothing.
819
820
820
    # if item is not for loan it cannot be reserved either.....
821
    # if item is not for loan it cannot be reserved either.....
821
    #    execpt where items.notforloan < 0 :  This indicates the item is holdable. 
822
    #    execpt where items.notforloan < 0 :  This indicates the item is holdable.
822
    return ( '' ) if  ( $notforloan_per_item > 0 ) or $notforloan_per_itemtype;
823
    return ( '' ) if  ( $notforloan_per_item > 0 ) or $notforloan_per_itemtype;
823
824
824
    # Find this item in the reserves
825
    # Find this item in the reserves
Lines 873-879 sub CancelExpiredReserves { Link Here
873
    # Cancel reserves that have passed their expiration date.
874
    # Cancel reserves that have passed their expiration date.
874
    my $dbh = C4::Context->dbh;
875
    my $dbh = C4::Context->dbh;
875
    my $sth = $dbh->prepare( "
876
    my $sth = $dbh->prepare( "
876
        SELECT * FROM reserves WHERE DATE(expirationdate) < DATE( CURDATE() ) 
877
        SELECT * FROM reserves WHERE DATE(expirationdate) < DATE( CURDATE() )
877
        AND expirationdate IS NOT NULL
878
        AND expirationdate IS NOT NULL
878
        AND found IS NULL
879
        AND found IS NULL
879
    " );
880
    " );
Lines 882-888 sub CancelExpiredReserves { Link Here
882
    while ( my $res = $sth->fetchrow_hashref() ) {
883
    while ( my $res = $sth->fetchrow_hashref() ) {
883
        CancelReserve( $res->{'biblionumber'}, '', $res->{'borrowernumber'} );
884
        CancelReserve( $res->{'biblionumber'}, '', $res->{'borrowernumber'} );
884
    }
885
    }
885
  
886
886
    # Cancel reserves that have been waiting too long
887
    # Cancel reserves that have been waiting too long
887
    if ( C4::Context->preference("ExpireReservesMaxPickUpDelay") ) {
888
    if ( C4::Context->preference("ExpireReservesMaxPickUpDelay") ) {
888
        my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay");
889
        my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay");
Lines 1038-1049 If C<$rank> is 'del', the hold request is cancelled. Link Here
1038
1039
1039
If C<$rank> is an integer greater than zero, the priority of
1040
If C<$rank> is an integer greater than zero, the priority of
1040
the request is set to that value.  Since priority != 0 means
1041
the request is set to that value.  Since priority != 0 means
1041
that the item is not waiting on the hold shelf, setting the 
1042
that the item is not waiting on the hold shelf, setting the
1042
priority to a non-zero value also sets the request's found
1043
priority to a non-zero value also sets the request's found
1043
status and waiting date to NULL. 
1044
status and waiting date to NULL.
1044
1045
1045
The optional C<$itemnumber> parameter is used only when
1046
The optional C<$itemnumber> parameter is used only when
1046
C<$rank> is a non-zero integer; if supplied, the itemnumber 
1047
C<$rank> is a non-zero integer; if supplied, the itemnumber
1047
of the hold request is set accordingly; if omitted, the itemnumber
1048
of the hold request is set accordingly; if omitted, the itemnumber
1048
is cleared.
1049
is cleared.
1049
1050
Lines 1073-1092 sub ModReserve { Link Here
1073
        $query = qq/
1074
        $query = qq/
1074
            INSERT INTO old_reserves
1075
            INSERT INTO old_reserves
1075
            SELECT *
1076
            SELECT *
1076
            FROM   reserves 
1077
            FROM   reserves
1077
            WHERE  biblionumber   = ?
1078
            WHERE  biblionumber   = ?
1078
             AND   borrowernumber = ?
1079
             AND   borrowernumber = ?
1079
        /;
1080
        /;
1080
        $sth = $dbh->prepare($query);
1081
        $sth = $dbh->prepare($query);
1081
        $sth->execute( $biblio, $borrower );
1082
        $sth->execute( $biblio, $borrower );
1082
        $query = qq/
1083
        $query = qq/
1083
            DELETE FROM reserves 
1084
            DELETE FROM reserves
1084
            WHERE  biblionumber   = ?
1085
            WHERE  biblionumber   = ?
1085
             AND   borrowernumber = ?
1086
             AND   borrowernumber = ?
1086
        /;
1087
        /;
1087
        $sth = $dbh->prepare($query);
1088
        $sth = $dbh->prepare($query);
1088
        $sth->execute( $biblio, $borrower );
1089
        $sth->execute( $biblio, $borrower );
1089
        
1090
1090
    }
1091
    }
1091
    elsif ($rank =~ /^\d+/ and $rank > 0) {
1092
    elsif ($rank =~ /^\d+/ and $rank > 0) {
1092
        my $query = "
1093
        my $query = "
Lines 1171-1177 sub ModReserveFill { Link Here
1171
                ";
1172
                ";
1172
    $sth = $dbh->prepare($query);
1173
    $sth = $dbh->prepare($query);
1173
    $sth->execute( $biblionumber, $resdate, $borrowernumber );
1174
    $sth->execute( $biblionumber, $resdate, $borrowernumber );
1174
    
1175
1175
    # now fix the priority on the others (if the priority wasn't
1176
    # now fix the priority on the others (if the priority wasn't
1176
    # already sorted!)....
1177
    # already sorted!)....
1177
    unless ( $priority == 0 ) {
1178
    unless ( $priority == 0 ) {
Lines 1216-1222 with the biblionumber & the borrowernumber, we can affect the itemnumber Link Here
1216
to the correct reserve.
1217
to the correct reserve.
1217
1218
1218
if $transferToDo is not set, then the status is set to "Waiting" as well.
1219
if $transferToDo is not set, then the status is set to "Waiting" as well.
1219
otherwise, a transfer is on the way, and the end of the transfer will 
1220
otherwise, a transfer is on the way, and the end of the transfer will
1220
take care of the waiting status
1221
take care of the waiting status
1221
1222
1222
=cut
1223
=cut
Lines 1297-1303 sub ModReserveCancelAll { Link Here
1297
1298
1298
  &ModReserveMinusPriority($itemnumber,$borrowernumber,$biblionumber)
1299
  &ModReserveMinusPriority($itemnumber,$borrowernumber,$biblionumber)
1299
1300
1300
Reduce the values of queuded list     
1301
Reduce the values of queuded list
1301
1302
1302
=cut
1303
=cut
1303
1304
Lines 1308-1314 sub ModReserveMinusPriority { Link Here
1308
    my $dbh   = C4::Context->dbh;
1309
    my $dbh   = C4::Context->dbh;
1309
    my $query = "
1310
    my $query = "
1310
        UPDATE reserves
1311
        UPDATE reserves
1311
        SET    priority = 0 , itemnumber = ? 
1312
        SET    priority = 0 , itemnumber = ?
1312
        WHERE  borrowernumber=?
1313
        WHERE  borrowernumber=?
1313
          AND  biblionumber=?
1314
          AND  biblionumber=?
1314
    ";
1315
    ";
Lines 1330-1371 Current implementation this query should have a single result. Link Here
1330
sub GetReserveInfo {
1331
sub GetReserveInfo {
1331
	my ( $borrowernumber, $biblionumber ) = @_;
1332
	my ( $borrowernumber, $biblionumber ) = @_;
1332
    my $dbh = C4::Context->dbh;
1333
    my $dbh = C4::Context->dbh;
1333
	my $strsth="SELECT 
1334
	my $strsth="SELECT
1334
	               reservedate, 
1335
	               reservedate,
1335
	               reservenotes, 
1336
	               reservenotes,
1336
	               reserves.borrowernumber,
1337
	               reserves.borrowernumber,
1337
				   reserves.biblionumber, 
1338
				   reserves.biblionumber,
1338
				   reserves.branchcode,
1339
				   reserves.branchcode,
1339
				   reserves.waitingdate,
1340
				   reserves.waitingdate,
1340
				   notificationdate, 
1341
				   notificationdate,
1341
				   reminderdate, 
1342
				   reminderdate,
1342
				   priority, 
1343
				   priority,
1343
				   found,
1344
				   found,
1344
				   firstname, 
1345
				   firstname,
1345
				   surname, 
1346
				   surname,
1346
				   phone, 
1347
				   phone,
1347
				   email, 
1348
				   email,
1348
				   address, 
1349
				   address,
1349
				   address2,
1350
				   address2,
1350
				   cardnumber, 
1351
				   cardnumber,
1351
				   city, 
1352
				   city,
1352
				   zipcode,
1353
				   zipcode,
1353
				   biblio.title, 
1354
				   biblio.title,
1354
				   biblio.author,
1355
				   biblio.author,
1355
				   items.holdingbranch, 
1356
				   items.holdingbranch,
1356
				   items.itemcallnumber, 
1357
				   items.itemcallnumber,
1357
				   items.itemnumber,
1358
				   items.itemnumber,
1358
				   items.location, 
1359
				   items.location,
1359
				   barcode, 
1360
				   barcode,
1360
				   notes
1361
				   notes
1361
			FROM reserves 
1362
			FROM reserves
1362
			 LEFT JOIN items USING(itemnumber) 
1363
			 LEFT JOIN items USING(itemnumber)
1363
		     LEFT JOIN borrowers USING(borrowernumber)
1364
		     LEFT JOIN borrowers USING(borrowernumber)
1364
		     LEFT JOIN biblio ON  (reserves.biblionumber=biblio.biblionumber) 
1365
		     LEFT JOIN biblio ON  (reserves.biblionumber=biblio.biblionumber)
1365
			WHERE 
1366
			WHERE
1366
				reserves.borrowernumber=?
1367
				reserves.borrowernumber=?
1367
				AND reserves.biblionumber=?";
1368
				AND reserves.biblionumber=?";
1368
	my $sth = $dbh->prepare($strsth); 
1369
	my $sth = $dbh->prepare($strsth);
1369
	$sth->execute($borrowernumber,$biblionumber);
1370
	$sth->execute($borrowernumber,$biblionumber);
1370
1371
1371
	my $data = $sth->fetchrow_hashref;
1372
	my $data = $sth->fetchrow_hashref;
Lines 1375-1396 sub GetReserveInfo { Link Here
1375
1376
1376
=head2 IsAvailableForItemLevelRequest
1377
=head2 IsAvailableForItemLevelRequest
1377
1378
1378
  my $is_available = IsAvailableForItemLevelRequest($itemnumber);
1379
  my $is_available = IsAvailableForItemLevelRequest($item_record,$borrower_record);
1379
1380
1380
Checks whether a given item record is available for an
1381
Checks whether a given item record is available for an
1381
item-level hold request.  An item is available if
1382
item-level hold request.  An item is available if
1382
1383
1383
* it is not lost AND 
1384
* it is not lost AND
1384
* it is not damaged AND 
1385
* it is not damaged AND
1385
* it is not withdrawn AND 
1386
* it is not withdrawn AND
1386
* does not have a not for loan value > 0
1387
* does not have a not for loan value > 0
1387
1388
1388
Whether or not the item is currently on loan is 
1389
Need to check the issuingrules onshelfholds column,
1389
also checked - if the AllowOnShelfHolds system preference
1390
if this is set items on the shelf can be placed on hold
1390
is ON, an item can be requested even if it is currently
1391
on loan to somebody else.  If the system preference
1392
is OFF, an item that is currently checked out cannot
1393
be the target of an item-level hold request.
1394
1391
1395
Note that IsAvailableForItemLevelRequest() does not
1392
Note that IsAvailableForItemLevelRequest() does not
1396
check if the staff operator is authorized to place
1393
check if the staff operator is authorized to place
Lines 1401-1450 and canreservefromotherbranches. Link Here
1401
=cut
1398
=cut
1402
1399
1403
sub IsAvailableForItemLevelRequest {
1400
sub IsAvailableForItemLevelRequest {
1404
    my $itemnumber = shift;
1401
    my $item = shift;
1405
   
1402
    my $borrower = shift;
1406
    my $item = GetItem($itemnumber);
1407
1403
1404
    my $dbh = C4::Context->dbh;
1408
    # must check the notforloan setting of the itemtype
1405
    # must check the notforloan setting of the itemtype
1409
    # FIXME - a lot of places in the code do this
1406
    # FIXME - a lot of places in the code do this
1410
    #         or something similar - need to be
1407
    #         or something similar - need to be
1411
    #         consolidated
1408
    #         consolidated
1412
    my $dbh = C4::Context->dbh;
1409
    my $itype;
1413
    my $notforloan_query;
1414
    if (C4::Context->preference('item-level_itypes')) {
1410
    if (C4::Context->preference('item-level_itypes')) {
1415
        $notforloan_query = "SELECT itemtypes.notforloan
1411
        # We cant trust GetItem to honour the syspref, so safest to do it ourselves
1416
                             FROM items
1412
        # When GetItem is fixed, we can remove this
1417
                             JOIN itemtypes ON (itemtypes.itemtype = items.itype)
1413
        $itype = $item->{itype};
1418
                             WHERE itemnumber = ?";
1419
    } else {
1420
        $notforloan_query = "SELECT itemtypes.notforloan
1421
                             FROM items
1422
                             JOIN biblioitems USING (biblioitemnumber)
1423
                             JOIN itemtypes USING (itemtype)
1424
                             WHERE itemnumber = ?";
1425
    }
1414
    }
1426
    my $sth = $dbh->prepare($notforloan_query);
1415
    else {
1427
    $sth->execute($itemnumber);
1416
        # XXX This is a bit dodgy. It relies on biblio itemtype column having different name.
1428
    my $notforloan_per_itemtype = 0;
1417
        # So if we already have a biblioitems join when calling this function,
1429
    if (my ($notforloan) = $sth->fetchrow_array) {
1418
        # we don't need to access the database again
1430
        $notforloan_per_itemtype = 1 if $notforloan;
1419
        $itype = $item->{itemtype};
1420
    }
1421
    unless ($itype) {
1422
        my $query = "SELECT itemtype FROM biblioitems WHERE biblioitemnumber = ? ";
1423
        my $sth = $dbh->prepare($query);
1424
        $sth->execute($item->{biblioitemnumber});
1425
        if (my $data = $sth->fetchrow_hashref()){
1426
            $itype = $data->{itemtype};
1427
        }
1431
    }
1428
    }
1432
1429
1433
    my $available_per_item = 1;
1430
    my $notforloan_per_itemtype
1434
    $available_per_item = 0 if $item->{itemlost} or
1431
      = $dbh->selectrow_array("SELECT notforloan FROM itemtypes WHERE itemtype = ?",
1435
                               ( $item->{notforloan} > 0 ) or
1432
                              undef, $itype);
1436
                               ($item->{damaged} and not C4::Context->preference('AllowHoldsOnDamagedItems')) or
1433
1437
                               $item->{wthdrawn} or
1434
    return 0 if
1438
                               $notforloan_per_itemtype;
1435
        $notforloan_per_itemtype ||
1436
        $item->{itemlost}        ||
1437
        $item->{notforloan} > 0  ||
1438
        $item->{wthdrawn}        ||
1439
        ($item->{damaged} && !C4::Context->preference('AllowHoldsOnDamagedItems'));
1439
1440
1440
1441
1441
    if (C4::Context->preference('AllowOnShelfHolds')) {
1442
    if (OnShelfHoldsAllowed($itype,$borrower->{categorycode},$item->{holdingbranch})) {
1442
        return $available_per_item;
1443
        return 1;
1443
    } else {
1444
    } else {
1444
        return ($available_per_item and ($item->{onloan} or GetReserveStatus($itemnumber) eq "W")); 
1445
        return $item->{onloan} || GetReserveStatus($item->{itemnumber}) eq "W";
1445
    }
1446
    }
1446
}
1447
}
1447
1448
1449
=head2 OnShelfHoldsAllowed
1450
1451
  OnShelfHoldsAllowed($itemtype,$borrowercategory,$branchcode);
1452
1453
Checks issuingrules, using the borrowers categorycode, the itemtype, and branchcode to see if onshelf
1454
holds are allowed, returns true if so.
1455
1456
=cut
1457
1458
sub OnShelfHoldsAllowed {
1459
    my ($itype,$borrowercategory,$branchcode) = @_;
1460
1461
    my $query = "SELECT onshelfholds FROM issuingrules WHERE
1462
          (issuingrules.categorycode = ? OR issuingrules.categorycode = '*')
1463
        AND
1464
          (issuingrules.itemtype = ? OR issuingrules.itemtype = '*')
1465
        AND
1466
          (issuingrules.branchcode = ? OR issuingrules.branchcode = '*')
1467
        ORDER BY
1468
          issuingrules.categorycode desc,
1469
          issuingrules.itemtype desc,
1470
          issuingrules.branchcode desc
1471
       LIMIT 1";
1472
    my $dbh = C4::Context->dbh;
1473
    my $onshelfholds = $dbh->selectrow_array($query, undef, $borrowercategory,$itype,$branchcode);
1474
    return $onshelfholds;
1475
}
1476
1448
=head2 AlterPriority
1477
=head2 AlterPriority
1449
1478
1450
  AlterPriority( $where, $borrowernumber, $biblionumber, $reservedate );
1479
  AlterPriority( $where, $borrowernumber, $biblionumber, $reservedate );
Lines 1466-1473 sub AlterPriority { Link Here
1466
    $sth->finish();
1495
    $sth->finish();
1467
1496
1468
    if ( $where eq 'up' || $where eq 'down' ) {
1497
    if ( $where eq 'up' || $where eq 'down' ) {
1469
    
1498
1470
      my $priority = $reserve->{'priority'};        
1499
      my $priority = $reserve->{'priority'};
1471
      $priority = $where eq 'up' ? $priority - 1 : $priority + 1;
1500
      $priority = $where eq 'up' ? $priority - 1 : $priority + 1;
1472
      _FixPriority( $biblionumber, $borrowernumber, $priority )
1501
      _FixPriority( $biblionumber, $borrowernumber, $priority )
1473
1502
Lines 1505-1511 sub ToggleLowestPriority { Link Here
1505
        $borrowernumber,
1534
        $borrowernumber,
1506
    );
1535
    );
1507
    $sth->finish;
1536
    $sth->finish;
1508
    
1537
1509
    _FixPriority( $biblionumber, $borrowernumber, '999999' );
1538
    _FixPriority( $biblionumber, $borrowernumber, '999999' );
1510
}
1539
}
1511
1540
Lines 1612-1618 the array index (+1 as array starts from 0) Link Here
1612
and if $rank is supplied will splice item from the array and splice it back in again
1641
and if $rank is supplied will splice item from the array and splice it back in again
1613
in new priority rank
1642
in new priority rank
1614
1643
1615
=cut 
1644
=cut
1616
1645
1617
sub _FixPriority {
1646
sub _FixPriority {
1618
    my ( $biblio, $borrowernumber, $rank, $ignoreSetLowestRank ) = @_;
1647
    my ( $biblio, $borrowernumber, $rank, $ignoreSetLowestRank ) = @_;
Lines 1691-1700 sub _FixPriority { Link Here
1691
        );
1720
        );
1692
        $sth->finish;
1721
        $sth->finish;
1693
    }
1722
    }
1694
    
1723
1695
    $sth = $dbh->prepare( "SELECT borrowernumber FROM reserves WHERE lowestPriority = 1 ORDER BY priority" );
1724
    $sth = $dbh->prepare( "SELECT borrowernumber FROM reserves WHERE lowestPriority = 1 ORDER BY priority" );
1696
    $sth->execute();
1725
    $sth->execute();
1697
    
1726
1698
    unless ( $ignoreSetLowestRank ) {
1727
    unless ( $ignoreSetLowestRank ) {
1699
      while ( my $res = $sth->fetchrow_hashref() ) {
1728
      while ( my $res = $sth->fetchrow_hashref() ) {
1700
        _FixPriority( $biblio, $res->{'borrowernumber'}, '999999', 1 );
1729
        _FixPriority( $biblio, $res->{'borrowernumber'}, '999999', 1 );
Lines 1754-1760 sub _Findgroupreserve { Link Here
1754
        push( @results, $data );
1783
        push( @results, $data );
1755
    }
1784
    }
1756
    return @results if @results;
1785
    return @results if @results;
1757
    
1786
1758
    # check for title-level targetted match
1787
    # check for title-level targetted match
1759
    my $title_level_target_query = qq/
1788
    my $title_level_target_query = qq/
1760
        SELECT reserves.biblionumber        AS biblionumber,
1789
        SELECT reserves.biblionumber        AS biblionumber,
Lines 1833-1839 sub _koha_notify_reserve { Link Here
1833
1862
1834
    my $dbh = C4::Context->dbh;
1863
    my $dbh = C4::Context->dbh;
1835
    my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber);
1864
    my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber);
1836
    
1865
1837
    # Try to get the borrower's email address
1866
    # Try to get the borrower's email address
1838
    my $to_address;
1867
    my $to_address;
1839
    my $which_address = C4::Context->preference('AutoEmailPrimaryAddress');
1868
    my $which_address = C4::Context->preference('AutoEmailPrimaryAddress');
Lines 1843-1849 sub _koha_notify_reserve { Link Here
1843
    } else {
1872
    } else {
1844
        $to_address = $borrower->{$which_address};
1873
        $to_address = $borrower->{$which_address};
1845
    }
1874
    }
1846
    
1875
1847
    my $letter_code;
1876
    my $letter_code;
1848
    my $print_mode = 0;
1877
    my $print_mode = 0;
1849
    my $messagingprefs;
1878
    my $messagingprefs;
Lines 1888-1894 sub _koha_notify_reserve { Link Here
1888
            borrowernumber => $borrowernumber,
1917
            borrowernumber => $borrowernumber,
1889
            message_transport_type => 'print',
1918
            message_transport_type => 'print',
1890
        } );
1919
        } );
1891
        
1920
1892
        return;
1921
        return;
1893
    }
1922
    }
1894
1923
Lines 1967-1972 sub _ShiftPriorityByDateAndPriority { Link Here
1967
    return $new_priority;  # so the caller knows what priority they wind up receiving
1996
    return $new_priority;  # so the caller knows what priority they wind up receiving
1968
}
1997
}
1969
1998
1999
=head2 OPACItemHoldsAllowed
2000
2001
  OPACItemHoldsAllowed($item_record,$borrower_record);
2002
2003
Checks issuingrules, using the borrowers categorycode, the itemtype, and branchcode to see
2004
if specific item holds are allowed, returns true if so.
2005
2006
=cut
2007
2008
sub OPACItemHoldsAllowed {
2009
    my ($item,$borrower) = @_;
2010
2011
    my $branchcode = $item->{homebranch} or die "No homebranch";
2012
    my $itype;
2013
    my $dbh = C4::Context->dbh;
2014
    if (C4::Context->preference('item-level_itypes')) {
2015
       # We cant trust GetItem to honour the syspref, so safest to do it ourselves
2016
       # When GetItem is fixed, we can remove this
2017
       $itype = $item->{itype};
2018
    }
2019
    else {
2020
       my $query = "SELECT itemtype FROM biblioitems WHERE biblioitemnumber = ? ";
2021
       my $sth = $dbh->prepare($query);
2022
       $sth->execute($item->{biblioitemnumber});
2023
       if (my $data = $sth->fetchrow_hashref()){
2024
           $itype = $data->{itemtype};
2025
       }
2026
    }
2027
2028
    my $query = "SELECT opacitemholds,categorycode,itemtype,branchcode FROM issuingrules WHERE
2029
          (issuingrules.categorycode = ? OR issuingrules.categorycode = '*')
2030
        AND
2031
          (issuingrules.itemtype = ? OR issuingrules.itemtype = '*')
2032
        AND
2033
          (issuingrules.branchcode = ? OR issuingrules.branchcode = '*')
2034
        ORDER BY
2035
          issuingrules.categorycode desc,
2036
          issuingrules.itemtype desc,
2037
          issuingrules.branchcode desc
2038
       LIMIT 1";
2039
    my $dbh = C4::Context->dbh;
2040
    my $sth = $dbh->prepare($query);
2041
    $sth->execute($borrower->{categorycode},$itype,$branchcode);
2042
    my $data = $sth->fetchrow_hashref;
2043
    if ($data->{opacitemholds}){
2044
       return 1;
2045
    }
2046
    else {
2047
       return 0;
2048
    }
2049
}
2050
1970
=head2 MoveReserve
2051
=head2 MoveReserve
1971
2052
1972
  MoveReserve( $itemnumber, $borrowernumber, $cancelreserve )
2053
  MoveReserve( $itemnumber, $borrowernumber, $cancelreserve )
(-)a/C4/VirtualShelves/Page.pm (-1 lines)
Lines 238-244 sub shelfpage { Link Here
238
            # explicitly fetch this shelf
238
            # explicitly fetch this shelf
239
            my ($shelfnumber2,$shelfname,$owner,$category,$sorton) = GetShelf($shelfnumber);
239
            my ($shelfnumber2,$shelfname,$owner,$category,$sorton) = GetShelf($shelfnumber);
240
240
241
            $template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
242
            if (C4::Context->preference('TagsEnabled')) {
241
            if (C4::Context->preference('TagsEnabled')) {
243
                $template->param(TagsEnabled => 1);
242
                $template->param(TagsEnabled => 1);
244
                    foreach (qw(TagsShowOnList TagsInputOnList)) {
243
                    foreach (qw(TagsShowOnList TagsInputOnList)) {
(-)a/admin/smart-rules.pl (-8 / +11 lines)
Lines 101-112 elsif ($op eq 'delete-branch-item') { Link Here
101
# save the values entered
101
# save the values entered
102
elsif ($op eq 'add') {
102
elsif ($op eq 'add') {
103
    my $sth_search = $dbh->prepare('SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?');
103
    my $sth_search = $dbh->prepare('SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?');
104
    my $sth_insert = $dbh->prepare('INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, lengthunit, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount, overduefinescap) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
104
    my $sth_insert = $dbh->prepare('INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, lengthunit, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount, onshelfholds, opacitemholds, reservesmaxpickupdelay, overduefinescap) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
105
    my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, lengthunit = ?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?, overduefinescap=?  WHERE branchcode=? AND categorycode=? AND itemtype=?");
105
    my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, lengthunit=?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?, onshelfholds=?, opacitemholds=?, reservesmaxpickupdelay=?, overduefinescap=? WHERE branchcode=? AND categorycode=? AND itemtype=?");
106
    
106
    
107
    my $br = $branch; # branch
107
    my $br = $branch; # branch
108
    my $bor  = $input->param('categorycode'); # borrower category
108
    my $bor  = $input->param('categorycode'); # borrower category
109
    my $cat  = $input->param('itemtype');     # item type
109
    my $itemtype  = $input->param('itemtype');     # item type
110
    my $fine = $input->param('fine');
110
    my $fine = $input->param('fine');
111
    my $finedays     = $input->param('finedays');
111
    my $finedays     = $input->param('finedays');
112
    my $firstremind  = $input->param('firstremind');
112
    my $firstremind  = $input->param('firstremind');
Lines 114-119 elsif ($op eq 'add') { Link Here
114
    my $maxissueqty  = $input->param('maxissueqty');
114
    my $maxissueqty  = $input->param('maxissueqty');
115
    my $renewalsallowed  = $input->param('renewalsallowed');
115
    my $renewalsallowed  = $input->param('renewalsallowed');
116
    my $reservesallowed  = $input->param('reservesallowed');
116
    my $reservesallowed  = $input->param('reservesallowed');
117
    my $onshelfholds     = $input->param('onshelfholds') || 0;
117
    $maxissueqty =~ s/\s//g;
118
    $maxissueqty =~ s/\s//g;
118
    $maxissueqty = undef if $maxissueqty !~ /^\d+/;
119
    $maxissueqty = undef if $maxissueqty !~ /^\d+/;
119
    my $issuelength  = $input->param('issuelength');
120
    my $issuelength  = $input->param('issuelength');
Lines 122-136 elsif ($op eq 'add') { Link Here
122
    $hardduedate = format_date_in_iso($hardduedate);
123
    $hardduedate = format_date_in_iso($hardduedate);
123
    my $hardduedatecompare = $input->param('hardduedatecompare');
124
    my $hardduedatecompare = $input->param('hardduedatecompare');
124
    my $rentaldiscount = $input->param('rentaldiscount');
125
    my $rentaldiscount = $input->param('rentaldiscount');
126
    my $reservesmaxpickupdelay = $input->param('reservesmaxpickupdelay');
127
    my $opacitemholds = $input->param('opacitemholds') || 0;
125
    my $overduefinescap = $input->param('overduefinescap') || undef;
128
    my $overduefinescap = $input->param('overduefinescap') || undef;
126
    $debug and warn "Adding $br, $bor, $cat, $fine, $maxissueqty";
129
    $debug and warn "Adding $br, $bor, $itemtype, $fine, $maxissueqty";
127
130
128
    $sth_search->execute($br,$bor,$cat);
131
    $sth_search->execute($br,$bor,$itemtype);
129
    my $res = $sth_search->fetchrow_hashref();
132
    my $res = $sth_search->fetchrow_hashref();
130
    if ($res->{total}) {
133
    if ($res->{total}) {
131
        $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$lengthunit, $hardduedate,$hardduedatecompare,$rentaldiscount,$overduefinescap, $br,$bor,$cat);
134
        $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$lengthunit, $hardduedate,$hardduedatecompare,$rentaldiscount, $onshelfholds, $opacitemholds, $reservesmaxpickupdelay, $overduefinescap, $br,$bor,$itemtype);
132
    } else {
135
    } else {
133
        $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$lengthunit,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount,$overduefinescap);
136
        $sth_insert->execute($br,$bor,$itemtype,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$lengthunit,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount,$onshelfholds,$opacitemholds,$reservesmaxpickupdelay,$overduefinescap);
134
    }
137
    }
135
} 
138
} 
136
elsif ($op eq "set-branch-defaults") {
139
elsif ($op eq "set-branch-defaults") {
Lines 385-391 while (my $row = $sth2->fetchrow_hashref) { Link Here
385
    $row->{'humancategorycode'} ||= $row->{'categorycode'};
388
    $row->{'humancategorycode'} ||= $row->{'categorycode'};
386
    $row->{'default_humancategorycode'} = 1 if $row->{'humancategorycode'} eq '*';
389
    $row->{'default_humancategorycode'} = 1 if $row->{'humancategorycode'} eq '*';
387
    $row->{'fine'} = sprintf('%.2f', $row->{'fine'});
390
    $row->{'fine'} = sprintf('%.2f', $row->{'fine'});
388
    if ($row->{'hardduedate'} ne '0000-00-00') {
391
    if ($row->{'hardduedate'} && $row->{'hardduedate'} ne '0000-00-00') {
389
       $row->{'hardduedate'} = format_date( $row->{'hardduedate'});
392
       $row->{'hardduedate'} = format_date( $row->{'hardduedate'});
390
       $row->{'hardduedatebefore'} = 1 if ($row->{'hardduedatecompare'} == -1);
393
       $row->{'hardduedatebefore'} = 1 if ($row->{'hardduedatecompare'} == -1);
391
       $row->{'hardduedateexact'} = 1 if ($row->{'hardduedatecompare'} ==  0);
394
       $row->{'hardduedateexact'} = 1 if ($row->{'hardduedatecompare'} ==  0);
(-)a/admin/systempreferences.pl (-2 lines)
Lines 186-192 $tabsysprefs{HomeOrHoldingBranch} = "Circulation"; Link Here
186
$tabsysprefs{HomeOrHoldingBranchReturn}      = "Circulation";
186
$tabsysprefs{HomeOrHoldingBranchReturn}      = "Circulation";
187
$tabsysprefs{RandomizeHoldsQueueWeight}      = "Circulation";
187
$tabsysprefs{RandomizeHoldsQueueWeight}      = "Circulation";
188
$tabsysprefs{StaticHoldsQueueWeight}         = "Circulation";
188
$tabsysprefs{StaticHoldsQueueWeight}         = "Circulation";
189
$tabsysprefs{AllowOnShelfHolds}              = "Circulation";
190
$tabsysprefs{AllowHoldsOnDamagedItems}       = "Circulation";
189
$tabsysprefs{AllowHoldsOnDamagedItems}       = "Circulation";
191
$tabsysprefs{UseBranchTransferLimits}        = "Circulation";
190
$tabsysprefs{UseBranchTransferLimits}        = "Circulation";
192
$tabsysprefs{AllowHoldPolicyOverride}        = "Circulation";
191
$tabsysprefs{AllowHoldPolicyOverride}        = "Circulation";
Lines 366-372 $tabsysprefs{suggestion} = "OPAC"; Link Here
366
$tabsysprefs{OpacTopissue}         = "OPAC";
365
$tabsysprefs{OpacTopissue}         = "OPAC";
367
$tabsysprefs{OpacBrowser}          = "OPAC";
366
$tabsysprefs{OpacBrowser}          = "OPAC";
368
$tabsysprefs{OpacRenewalAllowed}   = "OPAC";
367
$tabsysprefs{OpacRenewalAllowed}   = "OPAC";
369
$tabsysprefs{OPACItemHolds}        = "OPAC";
370
$tabsysprefs{OPACGroupResults}     = "OPAC";
368
$tabsysprefs{OPACGroupResults}     = "OPAC";
371
$tabsysprefs{XSLTDetailsDisplay}   = "OPAC";
369
$tabsysprefs{XSLTDetailsDisplay}   = "OPAC";
372
$tabsysprefs{XSLTResultsDisplay}   = "OPAC";
370
$tabsysprefs{XSLTResultsDisplay}   = "OPAC";
(-)a/installer/data/mysql/it-IT/necessari/system_preferences.sql (-1 lines)
Lines 17-23 Link Here
17
-- 51 Franklin Street' WHERE variable = ' Fifth Floor' WHERE variable = ' Boston' WHERE variable = ' MA 02110-1301 USA.
17
-- 51 Franklin Street' WHERE variable = ' Fifth Floor' WHERE variable = ' Boston' WHERE variable = ' MA 02110-1301 USA.
18
18
19
UPDATE systempreferences SET value = 'cataloguing' WHERE variable = 'AcqCreateItem';
19
UPDATE systempreferences SET value = 'cataloguing' WHERE variable = 'AcqCreateItem';
20
UPDATE systempreferences SET value = '1' WHERE variable = 'AllowOnShelfHolds';
21
UPDATE systempreferences SET value = '1' WHERE variable = 'AllowRenewalLimitOverride';
20
UPDATE systempreferences SET value = '1' WHERE variable = 'AllowRenewalLimitOverride';
22
UPDATE systempreferences SET value = 'annual' WHERE variable = 'autoBarcode';
21
UPDATE systempreferences SET value = 'annual' WHERE variable = 'autoBarcode';
23
UPDATE systempreferences SET value = 'email' WHERE variable = 'AutoEmailPrimaryAddress';
22
UPDATE systempreferences SET value = 'email' WHERE variable = 'AutoEmailPrimaryAddress';
(-)a/installer/data/mysql/kohastructure.sql (+3 lines)
Lines 999-1004 CREATE TABLE `issuingrules` ( -- circulation and fine rules Link Here
999
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
999
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
1000
  `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
1000
  `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
1001
  overduefinescap decimal default NULL, -- the maximum amount of an overdue fine
1001
  overduefinescap decimal default NULL, -- the maximum amount of an overdue fine
1002
  onshelfholds tinyint(1) NOT NULL default 0, -- allow holds for items that are on shelf
1003
  opacitemholds tinyint(1) NOT NULL default "0", -- allow opac users to place specific items on hold
1004
  reservesmaxpickupdelay smallint(6) default NULL, -- max pickup delay
1002
  PRIMARY KEY  (`branchcode`,`categorycode`,`itemtype`),
1005
  PRIMARY KEY  (`branchcode`,`categorycode`,`itemtype`),
1003
  KEY `categorycode` (`categorycode`),
1006
  KEY `categorycode` (`categorycode`),
1004
  KEY `itemtype` (`itemtype`)
1007
  KEY `itemtype` (`itemtype`)
(-)a/installer/data/mysql/sysprefs.sql (-2 lines)
Lines 186-192 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES Link Here
186
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OAI-PMH:archiveID','KOHA-OAI-TEST','OAI-PMH archive identification',NULL,'Free');
186
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OAI-PMH:archiveID','KOHA-OAI-TEST','OAI-PMH archive identification',NULL,'Free');
187
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OAI-PMH:MaxCount','50','OAI-PMH maximum number of records by answer to ListRecords and ListIdentifiers queries',NULL,'Integer');
187
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OAI-PMH:MaxCount','50','OAI-PMH maximum number of records by answer to ListRecords and ListIdentifiers queries',NULL,'Integer');
188
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OAI-PMH:ConfFile','','If empty, Koha OAI Server operates in normal mode, otherwise it operates in extended mode.',NULL,'File');
188
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OAI-PMH:ConfFile','','If empty, Koha OAI Server operates in normal mode, otherwise it operates in extended mode.',NULL,'File');
189
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OPACItemHolds','1','Allow OPAC users to place hold on specific items. If OFF, users can only request next available copy.','','YesNo');
190
189
191
INSERT INTO `systempreferences` (variable, value,options,type, explanation) VALUES ('AddPatronLists','categorycode','categorycode|category_type','Choice','Allow user to choose what list to pick up from when adding patrons');
190
INSERT INTO `systempreferences` (variable, value,options,type, explanation) VALUES ('AddPatronLists','categorycode','categorycode|category_type','Choice','Allow user to choose what list to pick up from when adding patrons');
192
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ExtendedPatronAttributes','0','Use extended patron IDs and attributes',NULL,'YesNo');
191
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ExtendedPatronAttributes','0','Use extended patron IDs and attributes',NULL,'YesNo');
Lines 219-225 INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES Link Here
219
('XSLTDetailsDisplay','','','Enable XSL stylesheet control over details page display on intranet','Free'),
218
('XSLTDetailsDisplay','','','Enable XSL stylesheet control over details page display on intranet','Free'),
220
('XSLTResultsDisplay','','','Enable XSL stylesheet control over results page display on intranet','Free');
219
('XSLTResultsDisplay','','','Enable XSL stylesheet control over results page display on intranet','Free');
221
INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AdvancedSearchTypes','itemtypes','itemtypes|ccode','Select which set of fields comprise the Type limit in the advanced search','Choice');
220
INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AdvancedSearchTypes','itemtypes','itemtypes|ccode','Select which set of fields comprise the Type limit in the advanced search','Choice');
222
INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AllowOnShelfHolds', '0', '', 'Allow hold requests to be placed on items that are not on loan', 'YesNo');
223
INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AllowHoldsOnDamagedItems', '1', '', 'Allow hold requests to be placed on damaged items', 'YesNo');
221
INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AllowHoldsOnDamagedItems', '1', '', 'Allow hold requests to be placed on damaged items', 'YesNo');
224
INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('OpacSuppression', '0', '', 'Turn ON the OPAC Suppression feature, requires further setup, ask your system administrator for details', 'YesNo');
222
INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('OpacSuppression', '0', '', 'Turn ON the OPAC Suppression feature, requires further setup, ask your system administrator for details', 'YesNo');
225
-- FIXME: add FrameworksLoaded, noOPACUserLogin?
223
-- FIXME: add FrameworksLoaded, noOPACUserLogin?
(-)a/installer/data/mysql/updatedatabase.pl (-1 / +35 lines)
Lines 2092-2098 if (C4::Context->preference("Version") < TransformToNum($DBversion)) { Link Here
2092
    $dbh->do("UPDATE `systempreferences` SET options='10' WHERE variable='globalDueDate'");
2092
    $dbh->do("UPDATE `systempreferences` SET options='10' WHERE variable='globalDueDate'");
2093
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='numSearchResults'");
2093
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='numSearchResults'");
2094
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='OPACnumSearchResults'");
2094
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='OPACnumSearchResults'");
2095
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='ReservesMaxPickupDelay'");
2096
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='TransfersMaxDaysWarning'");
2095
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='TransfersMaxDaysWarning'");
2097
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='StaticHoldsQueueWeight'");
2096
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='StaticHoldsQueueWeight'");
2098
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='holdCancelLength'");
2097
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='holdCancelLength'");
Lines 5657-5662 if (C4::Context->preference("Version") < TransformToNum($DBversion)) { Link Here
5657
    SetVersion ($DBversion);
5656
    SetVersion ($DBversion);
5658
}
5657
}
5659
5658
5659
5660
5661
$DBversion = '3.09.00.XXX';
5662
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
5663
    # First create the column
5664
    $dbh->do("ALTER TABLE issuingrules ADD onshelfholds tinyint(1) default 0");
5665
    # Now update the column
5666
    if (C4::Context->preference("AllowOnShelfHolds")){
5667
        # Pref is on, set allow for all rules
5668
        $dbh->do("UPDATE issuingrules SET onshelfholds=1");
5669
    } else {
5670
        # If the preference is not set, leave off
5671
        $dbh->do("UPDATE issuingrules SET onshelfholds=0");
5672
    }
5673
    $dbh->do("ALTER TABLE issuingrules MODIFY onshelfholds tinyint(1) default 0 NOT NULL");
5674
    # Remove from the systempreferences table
5675
    $dbh->do("DELETE FROM systempreferences WHERE variable = 'AllowOnShelfHolds'");
5676
5677
    # First create the column
5678
    $dbh->do("ALTER TABLE issuingrules ADD opacitemholds tinyint(1) DEFAULT 0");
5679
    # Now update the column
5680
    if (C4::Context->preference("OPACItemHolds")){
5681
       # Pref is on, set allow for all rules
5682
       $dbh->do("UPDATE issuingrules SET opacitemholds=1");
5683
    }
5684
    # If the preference is not set, leave off
5685
    # Remove from the systempreferences table
5686
    $dbh->do("DELETE FROM systempreferences WHERE variable = 'OPACItemHolds'");
5687
5688
    $dbh->do("ALTER TABLE issuingrules ADD reservesmaxpickupdelay smallint(6) DEFAULT NULL");
5689
5690
    print "Upgrade to $DBversion done (Move AllowOnShelfHolds to circulation matrix; Move OPACItemHolds system preference to circulation matrix; ReservesMaxPickupDelay circulation rule)\n";
5691
    SetVersion ($DBversion);
5692
}
5693
5660
=head1 FUNCTIONS
5694
=head1 FUNCTIONS
5661
5695
5662
=head2 TableExists($table)
5696
=head2 TableExists($table)
(-)a/installer/html-template-to-template-toolkit.pl (-1 / +1 lines)
Lines 32-38 my @globals = ("themelang","JacketImages","OPACAmazonCoverImages","GoogleJackets Link Here
32
"SyndeticsEnabled", "OpacRenewalAllowed", "item_level_itypes","noItemTypeImages",
32
"SyndeticsEnabled", "OpacRenewalAllowed", "item_level_itypes","noItemTypeImages",
33
"virtualshelves", "RequestOnOpac", "COinSinOPACResults", "OPACXSLTResultsDisplay",
33
"virtualshelves", "RequestOnOpac", "COinSinOPACResults", "OPACXSLTResultsDisplay",
34
"OPACItemsResultsDisplay", "LibraryThingForLibrariesID", "opacuserlogin", "TagsEnabled",
34
"OPACItemsResultsDisplay", "LibraryThingForLibrariesID", "opacuserlogin", "TagsEnabled",
35
"TagsShowOnList", "TagsInputOnList","loggedinusername","AllowOnShelfHolds","opacbookbag",
35
"TagsShowOnList", "TagsInputOnList","loggedinusername","opacbookbag",
36
"OPACAmazonEnabled", "SyndeticsCoverImages","using_https");
36
"OPACAmazonEnabled", "SyndeticsCoverImages","using_https");
37
37
38
# Arguments:
38
# Arguments:
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (-6 lines)
Lines 269-280 Circulation: Link Here
269
                  no: "Don't allow"
269
                  no: "Don't allow"
270
            - hold requests to be placed on damaged items.
270
            - hold requests to be placed on damaged items.
271
        -
271
        -
272
            - pref: AllowOnShelfHolds
273
              choices:
274
                  yes: Allow
275
                  no: "Don't allow"
276
            - hold requests to be placed on items that are not checked out.
277
        -
278
            - pref: AllowHoldDateInFuture
272
            - pref: AllowHoldDateInFuture
279
              choices:
273
              choices:
280
                  yes: Allow
274
                  yes: Allow
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref (-6 lines)
Lines 379-390 OPAC: Link Here
379
#              choices:
379
#              choices:
380
#            - If ON, enables subject cloud on OPAC
380
#            - If ON, enables subject cloud on OPAC
381
        -
381
        -
382
            - pref: OPACItemHolds
383
              choices:
384
                  yes: Allow
385
                  no: "Don't allow"
386
            - patrons to place holds on specific items in the OPAC. If this is disabled, users can only put a hold on the next available item.
387
        -
388
            - pref: OpacRenewalAllowed
382
            - pref: OpacRenewalAllowed
389
              choices:
383
              choices:
390
                  yes: Allow
384
                  yes: Allow
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt (-51 / +43 lines)
Lines 76-132 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
76
                <th>Suspension in days (day)</th>
76
                <th>Suspension in days (day)</th>
77
                <th>Renewals allowed (count)</th>
77
                <th>Renewals allowed (count)</th>
78
                <th>Holds allowed (count)</th>
78
                <th>Holds allowed (count)</th>
79
		<th>Rental discount (%)</th>
79
                <th>On Shelf Holds Allowed</th>
80
				<th>&nbsp;</th>
80
                <th>Allow OPAC Users to place Holds on Items</th>
81
                <th>Holds Max Pickup Delay (day)</th>
82
                <th>Rental discount (%)</th>
83
                <th>&nbsp;</th>
81
            </tr>
84
            </tr>
82
				[% FOREACH rule IN rules %]
85
        [% FOREACH rule IN rules %]
83
					[% UNLESS ( loop.odd ) %]
86
            [% IF ( loop.odd ) %] <tr> [% ELSE %] <tr class="highlight"> [% END %]
84
					<tr class="highlight">
87
                <td>[% IF ( rule.default_humancategorycode ) %]<em>All</em>[% ELSE %][% rule.humancategorycode %][% END %]</td>
85
					[% ELSE %]
88
                <td>[% IF ( rule.default_humanitemtype ) %]<em>All</em>[% ELSE %][% rule.humanitemtype %][% END %]</td>
86
					<tr>
89
                <td>[% IF ( rule.unlimited_maxissueqty ) %] Unlimited [% ELSE %][% rule.maxissueqty %][% END %]</td>
87
					[% END %]
90
                <td>[% rule.issuelength %]</td>
88
							<td>[% IF ( rule.default_humancategorycode ) %]
91
                <td>[% rule.lengthunit %]</td>
89
									<em>All</em>
92
                <td>
90
								[% ELSE %]
93
                [% IF ( rule.hardduedate ) %]
91
									[% rule.humancategorycode %]
94
                    [% IF ( rule.hardduedatebefore ) %]
92
								[% END %]
95
                        before [% rule.hardduedate %]
93
							</td>
96
                    [% ELSIF ( rule.hardduedateexact ) %]
94
							<td>[% IF ( rule.default_humanitemtype ) %]
97
                        on [% rule.hardduedate %]
95
									<em>All</em>
98
                    [% ELSIF ( rule.hardduedateafter ) %]
96
								[% ELSE %]
99
                        after [% rule.hardduedate %]
97
									[% rule.humanitemtype %]
100
                    [% END %]
98
								[% END %]
101
                [% ELSE %]
99
							</td>
102
                    None defined
100
							<td>[% IF ( rule.unlimited_maxissueqty ) %]
103
                [% END %]   
101
									Unlimited
104
                </td>
102
								[% ELSE %]
105
                <td>[% rule.fine %]</td>
103
									[% rule.maxissueqty %]
106
                <td>[% rule.chargeperiod %]</td>
104
								[% END %]
107
                <td>[% rule.firstremind %]</td>
105
							</td>
108
                <td>[% rule.overduefinescap FILTER format("%.2f") %]</td>
106
							<td>[% rule.issuelength %]</td>
109
                <td>[% rule.finedays %]</td>
107
							<td>
110
                <td>[% rule.renewalsallowed %]</td>
108
							    [% rule.lengthunit %]
111
                <td>[% rule.reservesallowed %]</td>
109
							</td>
112
                <td>[% IF rule.onshelfholds %]Yes[% ELSE %]No[% END %]</td>
110
                                                        <td>[% IF ( rule.hardduedate ) %]
113
                <td>[% IF rule.opacitemholds %]Yes[% ELSE %]No[% END %]</td>
111
                                                               [% IF ( rule.hardduedatebefore ) %]before [% rule.hardduedate %]</td>
114
                <td>[% rule.reservesmaxpickupdelay %]</td>
112
                                                               [% ELSE %][% IF ( rule.hardduedateexact ) %]on [% rule.hardduedate %]</td>
115
                <td>[% rule.rentaldiscount %]</td>
113
                                                                                 [% ELSE %][% IF ( rule.hardduedateafter ) %]after [% rule.hardduedate %]</td>[% END %]
116
                <td> <a class="button" href="/cgi-bin/koha/admin/smart-rules.pl?op=delete&amp;itemtype=[% rule.itemtype %]&amp;categorycode=[% rule.categorycode %]&amp;branch=[% rule.current_branch %]">Delete</a> </td>
114
                                                                                 [% END %]
117
             </tr>
115
                                                               [% END %]
118
        [% END %]
116
                                                            [% ELSE %]None defined[% END %]   
117
							<td>[% rule.fine %]</td>
118
							<td>[% rule.chargeperiod %]</td>
119
							<td>[% rule.firstremind %]</td>
120
                            <td>[% rule.overduefinescap FILTER format("%.2f") %]</td>
121
							<td>[% rule.finedays %]</td>
122
							<td>[% rule.renewalsallowed %]</td>
123
							<td>[% rule.reservesallowed %]</td>
124
							<td>[% rule.rentaldiscount %]</td>
125
							<td>
126
								<a class="button" href="/cgi-bin/koha/admin/smart-rules.pl?op=delete&amp;itemtype=[% rule.itemtype %]&amp;categorycode=[% rule.categorycode %]&amp;branch=[% rule.current_branch %]">Delete</a>
127
							</td>
128
                	</tr>
129
            	[% END %]
130
                <tr>
119
                <tr>
131
                    <td>
120
                    <td>
132
                        <select name="categorycode">
121
                        <select name="categorycode">
Lines 167-173 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
167
                    <td><input name="finedays" size="3" /> </td>
156
                    <td><input name="finedays" size="3" /> </td>
168
                    <td><input name="renewalsallowed" size="2" /></td>
157
                    <td><input name="renewalsallowed" size="2" /></td>
169
                    <td><input name="reservesallowed" size="2" /></td>
158
                    <td><input name="reservesallowed" size="2" /></td>
170
		    <td><input name="rentaldiscount" size="2" /></td>
159
                    <td><input type="checkbox" name="onshelfholds" value="1" /></td>
160
                    <td><input type="checkbox" name="opacitemholds" value="1" /></td>
161
                    <td><input name="reservesmaxpickupdelay" size="2" /></td>
162
                    <td><input name="rentaldiscount" size="2" /></td>
171
                    <td><input type="hidden" name="branch" value="[% current_branch %]"/><input type="submit" value="Add" class="submit" /></td>
163
                    <td><input type="hidden" name="branch" value="[% current_branch %]"/><input type="submit" value="Add" class="submit" /></td>
172
                </tr>
164
                </tr>
173
            </table>
165
            </table>
(-)a/koha-tmpl/opac-tmpl/prog/en/includes/opac-detail-sidebar.inc (-7 / +1 lines)
Lines 2-14 Link Here
2
    [% UNLESS ( norequests ) %]
2
    [% UNLESS ( norequests ) %]
3
        [% IF ( opacuserlogin ) %]
3
        [% IF ( opacuserlogin ) %]
4
            [% IF ( RequestOnOpac ) %]
4
            [% IF ( RequestOnOpac ) %]
5
                [% IF ( AllowOnShelfHolds ) %]
5
                <li><a class="reserve" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% biblionumber %]">Place hold</a></li>
6
                    <li><a class="reserve" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% biblionumber %]">Place hold</a></li>
7
                [% ELSE %]
8
                    [% IF ( ItemsIssued ) %]
9
                        <li><a class="reserve" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% biblionumber %]">Place hold</a></li>
10
                    [% END %]
11
                [% END %]
12
            [% END %]
6
            [% END %]
13
        [% END %]
7
        [% END %]
14
    [% END %]
8
    [% END %]
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt (-103 / +74 lines)
Lines 209-231 Link Here
209
            [% IF ( bad_data ) %]
209
            [% IF ( bad_data ) %]
210
              <div id="bad_data" class="dialog alert">ERROR: Internal error: incomplete hold request.</div>
210
              <div id="bad_data" class="dialog alert">ERROR: Internal error: incomplete hold request.</div>
211
            [% END %]
211
            [% END %]
212
          [% ELSE %]
212
          [% ELSIF ( none_available ) %]
213
            [% IF ( none_available ) %]
214
                <div id="none_available" class="dialog alert"><strong>Sorry</strong>, none of these items can be placed on hold.
213
                <div id="none_available" class="dialog alert"><strong>Sorry</strong>, none of these items can be placed on hold.
215
                </div>
214
                </div>
216
              [% END %]
217
          [% END %]<!-- NAME="message" -->
215
          [% END %]<!-- NAME="message" -->
218
216
219
      [% UNLESS ( message ) %][% UNLESS ( none_available ) %]<h3>Confirm holds for:
217
      [% UNLESS ( message ) %][% UNLESS ( none_available ) %]<h3>Confirm holds for:
220
                      [% FOREACH USER_INF IN USER_INFO %]
218
                      [% FOREACH USER_INF IN USER_INFO %]
221
                        [% USER_INF.firstname %] [% USER_INF.surname %] ([% USER_INF.cardnumber %])
219
                        [% USER_INF.firstname %] [% USER_INF.surname %] ([% USER_INF.cardnumber %])
222
                      [% END %]
220
                      [% END %]
223
                    </h3>[% END %]
221
                    </h3>
224
	      [% IF (RESERVE_CHARGE) %]
222
          [% IF (RESERVE_CHARGE) %]
225
	      <div class="dialog alert" id="reserve_fee">
223
	      <div class="dialog alert" id="reserve_fee">
226
	        There is a charge of [% RESERVE_CHARGE %] for placing this hold
224
	        There is a charge of [% RESERVE_CHARGE %] for placing this hold
227
	      </div>
225
	      </div>
228
	      [% END %]
226
          [% END %]
227
      [% END %][% END %]
229
228
230
            <form action="/cgi-bin/koha/opac-reserve.pl" method="post" id="hold-request-form">
229
            <form action="/cgi-bin/koha/opac-reserve.pl" method="post" id="hold-request-form">
231
            <input type="hidden" name="place_reserve" value="1"/>
230
            <input type="hidden" name="place_reserve" value="1"/>
Lines 234-271 Link Here
234
            <input type="hidden" name="biblionumbers" id="biblionumbers"/>
233
            <input type="hidden" name="biblionumbers" id="biblionumbers"/>
235
            <input type="hidden" name="selecteditems" id="selections"/>
234
            <input type="hidden" name="selecteditems" id="selections"/>
236
            <div id="bigloop">
235
            <div id="bigloop">
236
            [% extra_cols = 2 %]
237
              <table id="bibitemloop">
237
              <table id="bibitemloop">
238
                [% UNLESS ( none_available ) %]<tr>
238
                <tr>
239
                [% UNLESS ( none_available ) %]
239
                  <th>Hold</th>
240
                  <th>Hold</th>
241
                [% END %]
240
                  <th>Title</th>
242
                  <th>Title</th>
241
                  [% UNLESS ( item_level_itypes ) %]
243
                [% UNLESS ( item_level_itypes ) %]
242
                    <th>Item type</th>
244
                    <th>Item type</th>
243
                  [% END %]
245
                [% END %]
246
                [% UNLESS ( none_available ) %]
244
                  [% IF showholds && showpriority %]
247
                  [% IF showholds && showpriority %]
248
                    [% extra_cols = extra_cols + 1 %]
245
                  <th>Holds and priority</th>
249
                  <th>Holds and priority</th>
246
                  [% ELSIF showholds %]
250
                  [% ELSIF showholds %]
251
                    [% extra_cols = extra_cols + 1 %]
247
                  <th>Holds</th>
252
                  <th>Holds</th>
248
                  [% ELSIF showpriority %]
253
                  [% ELSIF showpriority %]
254
                    [% extra_cols = extra_cols + 1 %]
249
                  <th>Priority</th>
255
                  <th>Priority</th>
250
                  [% END %]
256
                  [% END %]
251
		  [% IF ( reserve_in_future ) %]
257
		  [% IF ( reserve_in_future ) %]
258
                    [% extra_cols = extra_cols + 1 %]
252
        <th>Hold starts on date</th>
259
        <th>Hold starts on date</th>
253
		  [% END %]
260
		  [% END %]
254
        <th>Hold not needed after</th>
261
        <th>Hold not needed after</th>
255
                  [% IF ( OPACItemHolds ) %]
256
                    <th id="place_on_hdr" style="display:none">Place on</th>
262
                    <th id="place_on_hdr" style="display:none">Place on</th>
257
                  [% END %]
258
                  [% UNLESS ( singleBranchMode ) %]
263
                  [% UNLESS ( singleBranchMode ) %]
259
		    [% IF ( choose_branch ) %]
264
		    [% IF ( choose_branch ) %]
265
                      [% extra_cols = extra_cols + 1 %]
260
                        <th>Pickup location</th>
266
                        <th>Pickup location</th>
261
		    [% END %]
267
		    [% END %]
262
                  [% END %]
268
                  [% END %]
263
                </tr>[% ELSE %]<tr><th colspan="5">Title</th></tr>[% END %]
269
                [% END %]
270
                </tr>
264
271
265
                [% FOREACH bibitemloo IN bibitemloop %]
272
                [% FOREACH bibitemloo IN bibitemloop %]
266
                  <tr>
273
                <tr>
267
                      [% IF ( bibitemloo.holdable ) %]
274
                    [% UNLESS none_available %]
268
					  <td>
275
                    <td>
276
                        [% IF ( bibitemloo.holdable ) %]
269
                      <input class="reserve_mode" name="reserve_mode" type="hidden" value="single"/>
277
                      <input class="reserve_mode" name="reserve_mode" type="hidden" value="single"/>
270
                      <input class="single_bib" name="single_bib" type="hidden" value="[% bibitemloo.biblionumber %]"/>
278
                      <input class="single_bib" name="single_bib" type="hidden" value="[% bibitemloo.biblionumber %]"/>
271
                        <span class="confirmjs_hold" title="[% bibitemloo.biblionumber %]"></span>
279
                        <span class="confirmjs_hold" title="[% bibitemloo.biblionumber %]"></span>
Lines 276-313 Link Here
276
                                 value="any" />
284
                                 value="any" />
277
                          <label class="confirm_label" for="[% bibitemloo.checkitem_bib %]">Next available copy</label>
285
                          <label class="confirm_label" for="[% bibitemloo.checkitem_bib %]">Next available copy</label>
278
                        </span>
286
                        </span>
279
					</td>
287
                        [% ELSE %]
280
                      [% ELSE %]
288
                        &nbsp;
281
					  [% UNLESS ( none_available ) %]<td>&nbsp;</td>[% END %]
289
                        [% END %]
282
                      [% END %]
290
                    </td>
283
                    [% IF ( bibitemloo.holdable ) %]<td>[% ELSE %]<td colspan="5">[% END %]
291
                    [% END %]
292
                    <td>
284
                      <a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% bibitemloo.biblionumber %]">[% bibitemloo.title |html %][% IF ( bibitemloo.subtitle ) %] [% FOREACH subtitl IN bibitemloo.subtitle %][% subtitl.subfield %][% END %][% END %]</a>
293
                      <a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% bibitemloo.biblionumber %]">[% bibitemloo.title |html %][% IF ( bibitemloo.subtitle ) %] [% FOREACH subtitl IN bibitemloo.subtitle %][% subtitl.subfield %][% END %][% END %]</a>
285
                      [% IF ( bibitemloo.author ) %],  by [% bibitemloo.author %][% END %]
294
                      [% IF ( bibitemloo.author ) %],  by [% bibitemloo.author %][% END %]
286
295
287
                      [% UNLESS ( bibitemloo.holdable ) %]
296
                      [% UNLESS ( bibitemloo.holdable ) %]
288
297
                          <div class="bibmessage">
289
                        [% IF ( bibitemloo.already_reserved ) %]
298
                        [% IF ( bibitemloo.already_reserved ) %]
290
                          <div class="bibmessage">You have already requested this title.</div>
299
                            You have already requested this title.
300
                        [% ELSIF ( bibitemloo.bib_available ) %]
301
                            No available items.
291
                        [% ELSE %]
302
                        [% ELSE %]
292
                          [% UNLESS ( bibitemloo.bib_available ) %]
303
                            This title cannot be requested.
293
                            <div class="bibmessage">No available items.</div>
294
                          [% ELSE %]
295
                            <div class="bibmessage">This title cannot be requested.</div>
296
                          [% END %]
297
                        [% END %]
298
299
300
                        [% END %]
304
                        [% END %]
301
305
                          </div>
306
                      [% END %]
302
                    </td>
307
                    </td>
303
                    [% IF ( bibitemloo.holdable ) %]
304
            <!-- HOLDABLE -->
305
                        [% UNLESS ( item_level_itypes ) %]
308
                        [% UNLESS ( item_level_itypes ) %]
306
                        <td>
309
                        <td>
307
                            [% IF ( bibitemloo.imageurl ) %]<img src="[% bibitemloo.imageurl %]" alt="" />[% END %]
310
                            [% IF ( bibitemloo.imageurl ) %]<img src="[% bibitemloo.imageurl %]" alt="" />[% END %]
308
                            [% bibitemloo.description %]
311
                            [% bibitemloo.description %]
309
                        </td>
312
                        </td>
310
                        [% END %]
313
                        [% END %]
314
                    [% IF ( bibitemloo.holdable ) %]
315
            <!-- HOLDABLE -->
311
                        [% IF showholds || showpriority %]
316
                        [% IF showholds || showpriority %]
312
                        <td>
317
                        <td>
313
                        [% IF showpriority %] [% bibitemloo.rank %] [% END %]
318
                        [% IF showpriority %] [% bibitemloo.rank %] [% END %]
Lines 332-399 Link Here
332
        <input name="expiration_date_[% bibitemloo.biblionumber %]" id="to" size="10" readonly="readonly" class="datepickerto" />
337
        <input name="expiration_date_[% bibitemloo.biblionumber %]" id="to" size="10" readonly="readonly" class="datepickerto" />
333
      <p style="margin:.3em 2em;">
338
      <p style="margin:.3em 2em;">
334
      <a href="#" style="font-size:85%;text-decoration:none;" onclick="document.getElementById('expiration_date_[% bibitemloo.biblionumber %]').value='';return false;">Clear date</a></p>
339
      <a href="#" style="font-size:85%;text-decoration:none;" onclick="document.getElementById('expiration_date_[% bibitemloo.biblionumber %]').value='';return false;">Clear date</a></p>
335
    </td>[% END %]
340
    </td>
336
341
337
                    [% IF ( bibitemloo.holdable ) %]
342
                        <td class="place_on_type" style="display:none">
338
		    <!-- HOLD ABLE -->
339
		    [% IF ( OPACItemHolds ) %]
340
		    <!-- ITEM HOLDS -->
343
		    <!-- ITEM HOLDS -->
341
                                          <td class="place_on_type" style="display:none">
344
                          <ul>
342
                                            <ul>
345
                              <li>
343
                                                <li>
346
                                  <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
344
                                                  [% UNLESS ( bibitemloo.holdable ) %]
347
                                         id="reqany_[% bibitemloo.biblionumber %]"
345
                                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
348
                                         class="selectany"
346
                                                           id="reqany_[% bibitemloo.biblionumber %]"
349
                                         value="Any"
347
                                                           class="selectany"
350
                                         checked="checked"
348
                                                           value="Any"
351
                                  />
349
                                                           disabled="disabled"
352
                                <label for="reqany_[% bibitemloo.biblionumber %]">Next available copy</label>
350
                                                    />
353
                              </li>
351
                                                  [% ELSE %]
354
                        [% IF ( bibitemloo.itemholdable ) %]
352
                                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
355
                              <li>
353
                                                           id="reqany_[% bibitemloo.biblionumber %]"
356
                                  <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
354
                                                           class="selectany"
357
                                         id="reqspecific_[% bibitemloo.biblionumber %]"
355
                                                           value="Any"
358
                                         class="selectspecific"
356
                                                           checked="checked"
359
                                         value="Specific"
357
                                                    />
360
                                  />
358
                                                  [% END %]
361
                                <label for="reqspecific_[% bibitemloo.biblionumber %]">A specific copy</label>
359
                                                  <label for="reqany_[% bibitemloo.biblionumber %]">Next available copy</label>
362
                              </li>
360
                                                </li>
363
                        [% END %]
361
                                                <li>
364
                          </ul>
362
                                                  [% UNLESS ( bibitemloo.holdable ) %]
365
                        </td>
363
                                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
366
364
                                                           id="reqspecific_[% bibitemloo.biblionumber %]"
367
                        [% UNLESS ( singleBranchMode ) %]
365
                                                           class="selectspecific"
366
                                                           disabled="disabled"
367
                                                           value="Specific"
368
                                                    />
369
                                                  [% ELSE %]
370
                                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
371
                                                           id="reqspecific_[% bibitemloo.biblionumber %]"
372
                                                           class="selectspecific"
373
                                                           value="Specific"
374
                                                    />
375
                                                  [% END %]
376
                                                  <label for="reqspecific_[% bibitemloo.biblionumber %]">A specific copy</label>
377
                                                </li>
378
                                            </ul>
379
                                          </td>
380
                                        [% END %][% END %]
381
382
                    [% UNLESS ( singleBranchMode ) %]
383
                        [% IF ( bibitemloo.holdable ) %]
384
			    [% IF ( choose_branch ) %]
368
			    [% IF ( choose_branch ) %]
385
			                   <td>
369
                        <td>
386
                         [% UNLESS ( bibitemloo.holdable ) %]
387
                            <select name="branch" id="branch_[% bibitemloo.biblionumber %]" disabled="disabled">
388
                              [% FOREACH branchChoicesLoo IN bibitemloo.branchChoicesLoop %]
389
                                [% IF ( branchChoicesLoo.selected ) %]
390
                                  <option value="[% branchChoicesLoo.value %]" selected="selected">[% branchChoicesLoo.branchname %]</option>
391
                                [% ELSE %]
392
                                  <option value="[% branchChoicesLoo.value %]">[% branchChoicesLoo.branchname %]</option>
393
                                [% END %]
394
                              [% END %]
395
                          </select>
396
                          [% ELSE %]
397
                            <select name="branch" id="branch_[% bibitemloo.biblionumber %]">
370
                            <select name="branch" id="branch_[% bibitemloo.biblionumber %]">
398
                              [% FOREACH branchChoicesLoo IN bibitemloo.branchChoicesLoop %]
371
                              [% FOREACH branchChoicesLoo IN bibitemloo.branchChoicesLoop %]
399
                                [% IF ( branchChoicesLoo.selected ) %]
372
                                [% IF ( branchChoicesLoo.selected ) %]
Lines 403-417 Link Here
403
                                [% END %]
376
                                [% END %]
404
                              [% END %]
377
                              [% END %]
405
                            </select>
378
                            </select>
406
                          [% END %]
407
                       </td>
379
                       </td>
408
			    [% END %]
380
                            [% END %]
409
		        [% END %]
381
                        [% END %]
410
                    [% END %]
382
                    [% ELSIF NOT none_available %]
383
                       <td colspan="[% extra_cols %]">&nbsp;</td>
384
                    [% END # holdable%]
411
                  </tr>
385
                  </tr>
412
386
413
                  [% IF ( OPACItemHolds ) %]
387
                    [% IF ( bibitemloo.itemholdable ) %]
414
                  [% IF ( bibitemloo.holdable ) %]
415
                    <tr class="copiesrow" id="copiesrow_[% bibitemloo.biblionumber %]">
388
                    <tr class="copiesrow" id="copiesrow_[% bibitemloo.biblionumber %]">
416
                      <td>&nbsp;</td>
389
                      <td>&nbsp;</td>
417
                      <td colspan="[% itemtable_colspan %]">
390
                      <td colspan="[% itemtable_colspan %]">
Lines 490-500 Link Here
490
                        </table>
463
                        </table>
491
                      </td>
464
                      </td>
492
                    </tr>
465
                    </tr>
493
                  [% END %]<!-- bib_available -->
466
                    [% END # itemholdable%]
494
                  [% END %]<!-- OPACItemHolds -->
467
                [% END %]<!-- bibitemloop -->
495
                [% END %]
468
              </table>
496
              </table><!-- bibitemloop -->
497
              [% END %] <!-- if message -->
498
            </div><!-- bigloop -->
469
            </div><!-- bigloop -->
499
470
500
            [% UNLESS ( message ) %]
471
            [% UNLESS ( message ) %]
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt (-11 / +7 lines)
Lines 258-275 function highlightOn() { Link Here
258
258
259
				<p>
259
				<p>
260
                                [% IF ( RequestOnOpac ) %]
260
                                [% IF ( RequestOnOpac ) %]
261
					[% UNLESS ( GROUP_RESULT.norequests ) %]
261
                                    [% UNLESS ( GROUP_RESULT.norequests ) %]
262
						[% IF ( opacuserlogin ) %]
262
                                        [% IF ( opacuserlogin ) %]
263
							[% IF ( AllowOnShelfHolds ) %]
263
                                            [% IF ( GROUP_RESULT.holdable ) %]
264
                                <a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% GROUP_RESULT.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue-->
264
                                <a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% GROUP_RESULT.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue-->
265
							[% ELSE %]
265
                                            [% END %]
266
								[% IF ( GROUP_RESULT.itemsissued ) %]
266
                                        [% END %]
267
                                    <a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% GROUP_RESULT.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue-->
267
                                    [% END %]
268
								[% END %]
268
                                [% END %]
269
							[% END %]
270
						[% END %]
271
					[% END %]
272
				[% END %]
273
269
274
				[% IF ( opacbookbag || virtualshelves ) %]<input type="checkbox" name="biblionumber" value="[% GROUP_RESULT.biblionumber %]" title="Click to add to cart" /> <label for="bib[% GROUP_RESULT.biblionumber %]">[% END %]<img src="[% themelang %]/images/[% GROUP_RESULT.itemtype %].gif" alt="[% GROUP_RESULT.ccode %]" title="[% GROUP_RESULT.ccode %]" />[% IF ( opacbookbag || virtualshelves ) %]</label>[% END %] [% IF ( GROUP_RESULT.classification ) %]
270
				[% IF ( opacbookbag || virtualshelves ) %]<input type="checkbox" name="biblionumber" value="[% GROUP_RESULT.biblionumber %]" title="Click to add to cart" /> <label for="bib[% GROUP_RESULT.biblionumber %]">[% END %]<img src="[% themelang %]/images/[% GROUP_RESULT.itemtype %].gif" alt="[% GROUP_RESULT.ccode %]" title="[% GROUP_RESULT.ccode %]" />[% IF ( opacbookbag || virtualshelves ) %]</label>[% END %] [% IF ( GROUP_RESULT.classification ) %]
275
                                    <a href="/cgi-bin/koha/opac-search.pl?q=callnum:[% GROUP_RESULT.classification |url %]">
271
                                    <a href="/cgi-bin/koha/opac-search.pl?q=callnum:[% GROUP_RESULT.classification |url %]">
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt (-5 / +1 lines)
Lines 567-578 $(document).ready(function(){ Link Here
567
                [% IF ( RequestOnOpac ) %]
567
                [% IF ( RequestOnOpac ) %]
568
                    [% UNLESS ( SEARCH_RESULT.norequests ) %]
568
                    [% UNLESS ( SEARCH_RESULT.norequests ) %]
569
                        [% IF ( opacuserlogin ) %]
569
                        [% IF ( opacuserlogin ) %]
570
                            [% IF ( AllowOnShelfHolds ) %]
570
                            [% IF ( SEARCH_RESULT.holdable ) %]
571
                                <a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% SEARCH_RESULT.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue-->
571
                                <a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% SEARCH_RESULT.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue-->
572
                            [% ELSE %]
573
                                [% IF ( SEARCH_RESULT.itemsissued ) %]
574
                                    <a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% SEARCH_RESULT.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue-->
575
                                [% END %]
576
                            [% END %]
572
                            [% END %]
577
                        [% END %]
573
                        [% END %]
578
                    [% END %]
574
                    [% END %]
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt (-1 / +1 lines)
Lines 382-388 $(function() { Link Here
382
      [% IF ( RequestOnOpac ) %]
382
      [% IF ( RequestOnOpac ) %]
383
          [% UNLESS ( itemsloo.norequests ) %]
383
          [% UNLESS ( itemsloo.norequests ) %]
384
            [% IF ( opacuserlogin ) %]
384
            [% IF ( opacuserlogin ) %]
385
              [% IF ( AllowOnShelfHolds ) %]
385
              [% IF ( itemsloo.allow_onshelf_holds ) %]
386
                <a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% itemsloo.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue-->
386
                <a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% itemsloo.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue-->
387
              [% ELSE %]
387
              [% ELSE %]
388
                [% IF ( itemsloo.itemsissued ) %]
388
                [% IF ( itemsloo.itemsissued ) %]
(-)a/opac/opac-ISBDdetail.pl (-7 / +2 lines)
Lines 69-85 my ( $template, $loggedinuser, $cookie ) = get_template_and_user( Link Here
69
my $biblionumber = $query->param('biblionumber');
69
my $biblionumber = $query->param('biblionumber');
70
70
71
# get biblionumbers stored in the cart
71
# get biblionumbers stored in the cart
72
my @cart_list;
72
if(my $cart_list = $query->cookie("bib_list")){
73
73
    my @cart_list = split(/\//, $cart_list);
74
if($query->cookie("bib_list")){
75
    my $cart_list = $query->cookie("bib_list");
76
    @cart_list = split(/\//, $cart_list);
77
    if ( grep {$_ eq $biblionumber} @cart_list) {
74
    if ( grep {$_ eq $biblionumber} @cart_list) {
78
        $template->param( incart => 1 );
75
        $template->param( incart => 1 );
79
    }
76
    }
80
}
77
}
81
78
82
$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
83
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
79
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
84
80
85
my $marcflavour      = C4::Context->preference("marcflavour");
81
my $marcflavour      = C4::Context->preference("marcflavour");
Lines 162-168 foreach ( @$reviews ) { Link Here
162
158
163
$template->param(
159
$template->param(
164
    RequestOnOpac       => C4::Context->preference("RequestOnOpac"),
160
    RequestOnOpac       => C4::Context->preference("RequestOnOpac"),
165
    AllowOnShelfHolds   => C4::Context->preference('AllowOnShelfHolds'),
166
    norequests   => $norequests,
161
    norequests   => $norequests,
167
    ISBD         => $res,
162
    ISBD         => $res,
168
    biblionumber => $biblionumber,
163
    biblionumber => $biblionumber,
(-)a/opac/opac-MARCdetail.pl (-6 / +2 lines)
Lines 82-98 $template->param( Link Here
82
);
82
);
83
83
84
# get biblionumbers stored in the cart
84
# get biblionumbers stored in the cart
85
my @cart_list;
85
if(my $cart_list = $query->cookie("bib_list")){
86
86
    my @cart_list = split(/\//, $cart_list);
87
if($query->cookie("bib_list")){
88
    my $cart_list = $query->cookie("bib_list");
89
    @cart_list = split(/\//, $cart_list);
90
    if ( grep {$_ eq $biblionumber} @cart_list) {
87
    if ( grep {$_ eq $biblionumber} @cart_list) {
91
        $template->param( incart => 1 );
88
        $template->param( incart => 1 );
92
    }
89
    }
93
}
90
}
94
91
95
$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
96
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
92
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
97
93
98
# adding the $RequestOnOpac param
94
# adding the $RequestOnOpac param
(-)a/opac/opac-detail.pl (-2 lines)
Lines 387-394 if ($session->param('busc')) { Link Here
387
}
387
}
388
388
389
389
390
391
$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
392
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
390
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
393
391
394
392
(-)a/opac/opac-reserve.pl (-18 / +25 lines)
Lines 380-385 foreach my $biblioNum (@biblionumbers) { Link Here
380
380
381
    $biblioLoopIter{itemLoop} = [];
381
    $biblioLoopIter{itemLoop} = [];
382
    my $numCopiesAvailable = 0;
382
    my $numCopiesAvailable = 0;
383
    my $numCopiesOPACAvailable = 0;
383
    foreach my $itemInfo (@{$biblioData->{itemInfos}}) {
384
    foreach my $itemInfo (@{$biblioData->{itemInfos}}) {
384
        my $itemNum = $itemInfo->{itemnumber};
385
        my $itemNum = $itemInfo->{itemnumber};
385
        my $itemLoopIter = {};
386
        my $itemLoopIter = {};
Lines 472-487 foreach my $biblioNum (@biblionumbers) { Link Here
472
473
473
        my $branch = C4::Circulation::_GetCircControlBranch($itemLoopIter, $borr);
474
        my $branch = C4::Circulation::_GetCircControlBranch($itemLoopIter, $borr);
474
475
475
        my $branchitemrule = GetBranchItemRule( $branch, $itemInfo->{'itype'} );
476
        my $policy_holdallowed = !$itemLoopIter->{already_reserved};
476
        my $policy_holdallowed = 1;
477
        if ($policy_holdallowed) {
477
478
            if (my $branchitemrule = GetBranchItemRule( $branch, $itemInfo->{'itype'} )) {
478
        if ( $branchitemrule->{'holdallowed'} == 0 ||
479
                $policy_holdallowed =
479
                ( $branchitemrule->{'holdallowed'} == 1 && $borr->{'branchcode'} ne $itemInfo->{'homebranch'} ) ) {
480
                  ($branchitemrule->{'holdallowed'} == 2) ||
480
            $policy_holdallowed = 0;
481
                  ($branchitemrule->{'holdallowed'} == 1
482
                      && $borr->{'branchcode'} eq $itemInfo->{'homebranch'});
483
            } else {
484
                $policy_holdallowed = 0; # No rule - not allowed
485
            }
481
        }
486
        }
482
487
        $policy_holdallowed &&=
483
        if (IsAvailableForItemLevelRequest($itemNum) and $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum) and ($itemLoopIter->{already_reserved} ne 1)) {
488
            IsAvailableForItemLevelRequest($itemInfo,$borr) &&
484
            $itemLoopIter->{available} = 1;
489
            CanItemBeReserved($borrowernumber,$itemNum);
490
491
        if ($policy_holdallowed) {
492
            if ( OPACItemHoldsAllowed( $itemInfo, $borr ) ) {
493
                $itemLoopIter->{available} = 1;
494
                $numCopiesOPACAvailable++;
495
            }
485
            $numCopiesAvailable++;
496
            $numCopiesAvailable++;
486
        }
497
        }
487
498
Lines 507-524 foreach my $biblioNum (@biblionumbers) { Link Here
507
        $numBibsAvailable++;
518
        $numBibsAvailable++;
508
        $biblioLoopIter{bib_available} = 1;
519
        $biblioLoopIter{bib_available} = 1;
509
        $biblioLoopIter{holdable} = 1;
520
        $biblioLoopIter{holdable} = 1;
510
        $anyholdable = 1;
521
        $biblioLoopIter{itemholdable} = 1 if $numCopiesOPACAvailable;
511
    }
522
    }
512
    if ($biblioLoopIter{already_reserved}) {
523
    if ($biblioLoopIter{already_reserved}) {
513
        $biblioLoopIter{holdable} = undef;
524
        $biblioLoopIter{holdable} = undef;
514
        $anyholdable = undef;
525
        $biblioLoopIter{itemholdable} = undef;
515
    }
516
    if(not CanBookBeReserved($borrowernumber,$biblioNum)){
517
        $biblioLoopIter{holdable} = undef;
518
        $anyholdable = undef;
519
    }
526
    }
527
    $biblioLoopIter{holdable} &&= CanBookBeReserved($borrowernumber,$biblioNum);
520
528
521
    push @$biblioLoop, \%biblioLoopIter;
529
    push @$biblioLoop, \%biblioLoopIter;
530
531
    $anyholdable = 1 if $biblioLoopIter{holdable};
522
}
532
}
523
533
524
if ( $numBibsAvailable == 0 || !$anyholdable) {
534
if ( $numBibsAvailable == 0 || !$anyholdable) {
Lines 526-534 if ( $numBibsAvailable == 0 || !$anyholdable) { Link Here
526
}
536
}
527
537
528
my $itemTableColspan = 7;
538
my $itemTableColspan = 7;
529
if (! $template->{VARS}->{'OPACItemHolds'}) {
530
    $itemTableColspan--;
531
}
532
if (! $template->{VARS}->{'singleBranchMode'}) {
539
if (! $template->{VARS}->{'singleBranchMode'}) {
533
    $itemTableColspan--;
540
    $itemTableColspan--;
534
}
541
}
(-)a/opac/opac-search.pl (-1 / +18 lines)
Lines 51-56 use C4::Tags qw(get_tags); Link Here
51
use C4::Branch; # GetBranches
51
use C4::Branch; # GetBranches
52
use C4::SocialData;
52
use C4::SocialData;
53
use C4::Ratings;
53
use C4::Ratings;
54
use C4::Members;
55
use C4::Reserves;
54
56
55
use POSIX qw(ceil floor strftime);
57
use POSIX qw(ceil floor strftime);
56
use URI::Escape;
58
use URI::Escape;
Lines 124-130 if (C4::Context->preference("marcflavour") eq "UNIMARC" ) { Link Here
124
elsif (C4::Context->preference("marcflavour") eq "MARC21" ) {
126
elsif (C4::Context->preference("marcflavour") eq "MARC21" ) {
125
    $template->param('usmarc' => 1);
127
    $template->param('usmarc' => 1);
126
}
128
}
127
$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
129
128
$template->param( 'OPACNoResultsFound' => C4::Context->preference('OPACNoResultsFound') );
130
$template->param( 'OPACNoResultsFound' => C4::Context->preference('OPACNoResultsFound') );
129
131
130
$template->param(
132
$template->param(
Lines 505-512 if ($@ || $error) { Link Here
505
    exit;
507
    exit;
506
}
508
}
507
509
510
my $borrower = $borrowernumber ? GetMember( borrowernumber => $borrowernumber ) : undef;
511
508
# At this point, each server has given us a result set
512
# At this point, each server has given us a result set
509
# now we build that set for template display
513
# now we build that set for template display
514
my %allow_onshelf_holds;
510
my @sup_results_array;
515
my @sup_results_array;
511
for (my $i=0;$i<@servers;$i++) {
516
for (my $i=0;$i<@servers;$i++) {
512
    my $server = $servers[$i];
517
    my $server = $servers[$i];
Lines 521-531 for (my $i=0;$i<@servers;$i++) { Link Here
521
                # we need to set the offset parameter of searchResults to 0
526
                # we need to set the offset parameter of searchResults to 0
522
                my @group_results = searchResults( 'opac', $query_desc, $group->{'group_count'},$results_per_page, 0, $scan,
527
                my @group_results = searchResults( 'opac', $query_desc, $group->{'group_count'},$results_per_page, 0, $scan,
523
                                                   $group->{"RECORDS"});
528
                                                   $group->{"RECORDS"});
529
                if ($borrower) {
530
                    $_->{holdable} =
531
                        IsAvailableForItemLevelRequest($_, $borrower) &&
532
                        OPACItemHoldsAllowed($_, $borrower)
533
                      foreach @group_results;
534
                }
524
                push @newresults, { group_label => $group->{'group_label'}, GROUP_RESULTS => \@group_results };
535
                push @newresults, { group_label => $group->{'group_label'}, GROUP_RESULTS => \@group_results };
525
            }
536
            }
526
        } else {
537
        } else {
527
            @newresults = searchResults('opac', $query_desc, $hits, $results_per_page, $offset, $scan,
538
            @newresults = searchResults('opac', $query_desc, $hits, $results_per_page, $offset, $scan,
528
                                        $results_hashref->{$server}->{"RECORDS"});
539
                                        $results_hashref->{$server}->{"RECORDS"});
540
            if ($borrower) {
541
                $_->{holdable} =
542
                    IsAvailableForItemLevelRequest($_, $borrower) &&
543
                    OPACItemHoldsAllowed($_, $borrower)
544
                  foreach @newresults;
545
            }
529
        }
546
        }
530
547
531
        # must define a value for size if not present in DB
548
        # must define a value for size if not present in DB
(-)a/reserve/request.pl (-2 / +1 lines)
Lines 456-462 foreach my $biblionumber (@biblionumbers) { Link Here
456
            if (
456
            if (
457
                   $policy_holdallowed
457
                   $policy_holdallowed
458
                && !$item->{cantreserve}
458
                && !$item->{cantreserve}
459
                && IsAvailableForItemLevelRequest($itemnumber)
459
                && IsAvailableForItemLevelRequest($item, $borrowerinfo)
460
                && CanItemBeReserved(
460
                && CanItemBeReserved(
461
                    $borrowerinfo->{borrowernumber}, $itemnumber
461
                    $borrowerinfo->{borrowernumber}, $itemnumber
462
                )
462
                )
463
- 

Return to bug 5786