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

(-)a/C4/Auth.pm (-1 lines)
Lines 402-408 sub get_template_and_user { Link Here
402
            OPACAmazonCoverImages     => C4::Context->preference("OPACAmazonCoverImages"),
402
            OPACAmazonCoverImages     => C4::Context->preference("OPACAmazonCoverImages"),
403
            OPACFRBRizeEditions       => C4::Context->preference("OPACFRBRizeEditions"),
403
            OPACFRBRizeEditions       => C4::Context->preference("OPACFRBRizeEditions"),
404
            OpacHighlightedWords       => C4::Context->preference("OpacHighlightedWords"),
404
            OpacHighlightedWords       => C4::Context->preference("OpacHighlightedWords"),
405
            OPACItemHolds             => C4::Context->preference("OPACItemHolds"),
406
            OPACShelfBrowser          => "". C4::Context->preference("OPACShelfBrowser"),
405
            OPACShelfBrowser          => "". C4::Context->preference("OPACShelfBrowser"),
407
            OpacShowRecentComments    => C4::Context->preference("OpacShowRecentComments"),
406
            OpacShowRecentComments    => C4::Context->preference("OpacShowRecentComments"),
408
            OPACURLOpenInNewWindow    => "" . C4::Context->preference("OPACURLOpenInNewWindow"),
407
            OPACURLOpenInNewWindow    => "" . C4::Context->preference("OPACURLOpenInNewWindow"),
(-)a/C4/ILSDI/Services.pm (-1 / +1 lines)
Lines 495-501 sub GetServices { Link Here
495
    my $canbookbereserved = CanBookBeReserved( $borrower, $biblionumber );
495
    my $canbookbereserved = CanBookBeReserved( $borrower, $biblionumber );
496
    if ($canbookbereserved) {
496
    if ($canbookbereserved) {
497
        push @availablefor, 'title level hold';
497
        push @availablefor, 'title level hold';
498
        my $canitembereserved = IsAvailableForItemLevelRequest($itemnumber);
498
        my $canitembereserved = IsAvailableForItemLevelRequest($item, $borrower);
499
        if ($canitembereserved) {
499
        if ($canitembereserved) {
500
            push @availablefor, 'item level hold';
500
            push @availablefor, 'item level hold';
501
        }
501
        }
(-)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 / +210 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};
1431
    }
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
        }
1428
    }
1429
1430
    my $notforloan_per_itemtype
1431
      = $dbh->selectrow_array("SELECT notforloan FROM itemtypes WHERE itemtype = ?",
1432
                              undef, $itype);
1432
1433
1433
    my $available_per_item = 1;
1434
    return 0 if
1434
    $available_per_item = 0 if $item->{itemlost} or
1435
        $notforloan_per_itemtype ||
1435
                               ( $item->{notforloan} > 0 ) or
1436
        $item->{itemlost}        ||
1436
                               ($item->{damaged} and not C4::Context->preference('AllowHoldsOnDamagedItems')) or
1437
        $item->{notforloan} > 0  ||
1437
                               $item->{wthdrawn} or
1438
        $item->{wthdrawn}        ||
1438
                               $notforloan_per_itemtype;
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 $sth = $dbh->prepare($query);
2040
    $sth->execute($borrower->{categorycode},$itype,$branchcode);
2041
    my $data = $sth->fetchrow_hashref;
2042
    if ($data->{opacitemholds}){
2043
       return 1;
2044
    }
2045
    else {
2046
       return 0;
2047
    }
2048
}
2049
1970
=head2 MoveReserve
2050
=head2 MoveReserve
1971
2051
1972
  MoveReserve( $itemnumber, $borrowernumber, $cancelreserve )
2052
  MoveReserve( $itemnumber, $borrowernumber, $cancelreserve )
(-)a/C4/VirtualShelves/Page.pm (-1 lines)
Lines 237-243 sub shelfpage { Link Here
237
            # explicitly fetch this shelf
237
            # explicitly fetch this shelf
238
            my ($shelfnumber2,$shelfname,$owner,$category,$sorton) = GetShelf($shelfnumber);
238
            my ($shelfnumber2,$shelfname,$owner,$category,$sorton) = GetShelf($shelfnumber);
239
239
240
            $template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
241
            if (C4::Context->preference('TagsEnabled')) {
240
            if (C4::Context->preference('TagsEnabled')) {
242
                $template->param(TagsEnabled => 1);
241
                $template->param(TagsEnabled => 1);
243
                    foreach (qw(TagsShowOnList TagsInputOnList)) {
242
                    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 367-373 $tabsysprefs{suggestion} = "OPAC"; Link Here
367
$tabsysprefs{OpacTopissue}         = "OPAC";
366
$tabsysprefs{OpacTopissue}         = "OPAC";
368
$tabsysprefs{OpacBrowser}          = "OPAC";
367
$tabsysprefs{OpacBrowser}          = "OPAC";
369
$tabsysprefs{OpacRenewalAllowed}   = "OPAC";
368
$tabsysprefs{OpacRenewalAllowed}   = "OPAC";
370
$tabsysprefs{OPACItemHolds}        = "OPAC";
371
$tabsysprefs{OPACGroupResults}     = "OPAC";
369
$tabsysprefs{OPACGroupResults}     = "OPAC";
372
$tabsysprefs{XSLTDetailsDisplay}   = "OPAC";
370
$tabsysprefs{XSLTDetailsDisplay}   = "OPAC";
373
$tabsysprefs{XSLTResultsDisplay}   = "OPAC";
371
$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 1019-1024 CREATE TABLE `issuingrules` ( -- circulation and fine rules Link Here
1019
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
1019
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
1020
  `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
1020
  `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
1021
  overduefinescap decimal default NULL, -- the maximum amount of an overdue fine
1021
  overduefinescap decimal default NULL, -- the maximum amount of an overdue fine
1022
  onshelfholds tinyint(1) NOT NULL default 0, -- allow holds for items that are on shelf
1023
  opacitemholds tinyint(1) NOT NULL default "0", -- allow opac users to place specific items on hold
1024
  reservesmaxpickupdelay smallint(6) default NULL, -- max pickup delay
1022
  PRIMARY KEY  (`branchcode`,`categorycode`,`itemtype`),
1025
  PRIMARY KEY  (`branchcode`,`categorycode`,`itemtype`),
1023
  KEY `categorycode` (`categorycode`),
1026
  KEY `categorycode` (`categorycode`),
1024
  KEY `itemtype` (`itemtype`)
1027
  KEY `itemtype` (`itemtype`)
(-)a/installer/data/mysql/sysprefs.sql (-2 lines)
Lines 187-193 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES Link Here
187
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:archiveID','KOHA-OAI-TEST','OAI-PMH archive identification',NULL,'Free');
188
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:MaxCount','50','OAI-PMH maximum number of records by answer to ListRecords and ListIdentifiers queries',NULL,'Integer');
189
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('OAI-PMH:ConfFile','','If empty, Koha OAI Server operates in normal mode, otherwise it operates in extended mode.',NULL,'File');
190
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');
191
190
192
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');
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');
193
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ExtendedPatronAttributes','0','Use extended patron IDs and attributes',NULL,'YesNo');
192
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ExtendedPatronAttributes','0','Use extended patron IDs and attributes',NULL,'YesNo');
Lines 220-226 INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES Link Here
220
('XSLTDetailsDisplay','','','Enable XSL stylesheet control over details page display on intranet','Free'),
219
('XSLTDetailsDisplay','','','Enable XSL stylesheet control over details page display on intranet','Free'),
221
('XSLTResultsDisplay','','','Enable XSL stylesheet control over results page display on intranet','Free');
220
('XSLTResultsDisplay','','','Enable XSL stylesheet control over results page display on intranet','Free');
222
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');
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');
223
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');
224
INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AllowHoldsOnDamagedItems', '1', '', 'Allow hold requests to be placed on damaged items', 'YesNo');
222
INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AllowHoldsOnDamagedItems', '1', '', 'Allow hold requests to be placed on damaged items', 'YesNo');
225
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');
223
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');
226
-- FIXME: add FrameworksLoaded, noOPACUserLogin?
224
-- FIXME: add FrameworksLoaded, noOPACUserLogin?
(-)a/installer/data/mysql/updatedatabase.pl (-1 / +35 lines)
Lines 2093-2099 if (C4::Context->preference("Version") < TransformToNum($DBversion)) { Link Here
2093
    $dbh->do("UPDATE `systempreferences` SET options='10' WHERE variable='globalDueDate'");
2093
    $dbh->do("UPDATE `systempreferences` SET options='10' WHERE variable='globalDueDate'");
2094
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='numSearchResults'");
2094
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='numSearchResults'");
2095
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='OPACnumSearchResults'");
2095
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='OPACnumSearchResults'");
2096
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='ReservesMaxPickupDelay'");
2097
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='TransfersMaxDaysWarning'");
2096
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='TransfersMaxDaysWarning'");
2098
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='StaticHoldsQueueWeight'");
2097
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='StaticHoldsQueueWeight'");
2099
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='holdCancelLength'");
2098
    $dbh->do("UPDATE `systempreferences` SET type='Integer' WHERE variable='holdCancelLength'");
Lines 6438-6443 if ( CheckVersion($DBversion) ) { Link Here
6438
}
6437
}
6439
6438
6440
6439
6440
6441
6442
$DBversion = '3.11.00.XXX';
6443
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
6444
    # First create the column
6445
    $dbh->do("ALTER TABLE issuingrules ADD onshelfholds tinyint(1) default 0");
6446
    # Now update the column
6447
    if (C4::Context->preference("AllowOnShelfHolds")){
6448
        # Pref is on, set allow for all rules
6449
        $dbh->do("UPDATE issuingrules SET onshelfholds=1");
6450
    } else {
6451
        # If the preference is not set, leave off
6452
        $dbh->do("UPDATE issuingrules SET onshelfholds=0");
6453
    }
6454
    $dbh->do("ALTER TABLE issuingrules MODIFY onshelfholds tinyint(1) default 0 NOT NULL");
6455
    # Remove from the systempreferences table
6456
    $dbh->do("DELETE FROM systempreferences WHERE variable = 'AllowOnShelfHolds'");
6457
6458
    # First create the column
6459
    $dbh->do("ALTER TABLE issuingrules ADD opacitemholds tinyint(1) DEFAULT 0");
6460
    # Now update the column
6461
    if (C4::Context->preference("OPACItemHolds")){
6462
       # Pref is on, set allow for all rules
6463
       $dbh->do("UPDATE issuingrules SET opacitemholds=1");
6464
    }
6465
    # If the preference is not set, leave off
6466
    # Remove from the systempreferences table
6467
    $dbh->do("DELETE FROM systempreferences WHERE variable = 'OPACItemHolds'");
6468
6469
    $dbh->do("ALTER TABLE issuingrules ADD reservesmaxpickupdelay smallint(6) DEFAULT NULL");
6470
6471
    print "Upgrade to $DBversion done (Move AllowOnShelfHolds to circulation matrix; Move OPACItemHolds system preference to circulation matrix; ReservesMaxPickupDelay circulation rule)\n";
6472
    SetVersion ($DBversion);
6473
}
6474
6441
=head1 FUNCTIONS
6475
=head1 FUNCTIONS
6442
6476
6443
=head2 TableExists($table)
6477
=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 333-344 Circulation: Link Here
333
                  no: "Don't allow"
333
                  no: "Don't allow"
334
            - hold requests to be placed on damaged items.
334
            - hold requests to be placed on damaged items.
335
        -
335
        -
336
            - pref: AllowOnShelfHolds
337
              choices:
338
                  yes: Allow
339
                  no: "Don't allow"
340
            - hold requests to be placed on items that are not checked out.
341
        -
342
            - pref: AllowHoldDateInFuture
336
            - pref: AllowHoldDateInFuture
343
              choices:
337
              choices:
344
                  yes: Allow
338
                  yes: Allow
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref (-6 lines)
Lines 426-437 OPAC: Link Here
426
#              choices:
426
#              choices:
427
#            - If ON, enables subject cloud on OPAC
427
#            - If ON, enables subject cloud on OPAC
428
        -
428
        -
429
            - pref: OPACItemHolds
430
              choices:
431
                  yes: Allow
432
                  no: "Don't allow"
433
            - 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.
434
        -
435
            - pref: OpacRenewalAllowed
429
            - pref: OpacRenewalAllowed
436
              choices:
430
              choices:
437
                  yes: Allow
431
                  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 (-95 / +73 lines)
Lines 210-232 Link Here
210
            [% IF ( bad_data ) %]
210
            [% IF ( bad_data ) %]
211
              <div id="bad_data" class="dialog alert">ERROR: Internal error: incomplete hold request.</div>
211
              <div id="bad_data" class="dialog alert">ERROR: Internal error: incomplete hold request.</div>
212
            [% END %]
212
            [% END %]
213
          [% ELSE %]
213
          [% ELSIF ( none_available ) %]
214
            [% IF ( none_available ) %]
215
                <div id="none_available" class="dialog alert"><strong>Sorry</strong>, none of these items can be placed on hold.
214
                <div id="none_available" class="dialog alert"><strong>Sorry</strong>, none of these items can be placed on hold.
216
                </div>
215
                </div>
217
              [% END %]
218
          [% END %]<!-- NAME="message" -->
216
          [% END %]<!-- NAME="message" -->
219
217
220
      [% UNLESS ( message ) %][% UNLESS ( none_available ) %]<h3>Confirm holds for:
218
      [% UNLESS ( message ) %][% UNLESS ( none_available ) %]<h3>Confirm holds for:
221
                      [% FOREACH USER_INF IN USER_INFO %]
219
                      [% FOREACH USER_INF IN USER_INFO %]
222
                        [% USER_INF.firstname %] [% USER_INF.surname %] ([% USER_INF.cardnumber %])
220
                        [% USER_INF.firstname %] [% USER_INF.surname %] ([% USER_INF.cardnumber %])
223
                      [% END %]
221
                      [% END %]
224
                    </h3>[% END %]
222
                    </h3>
225
	      [% IF (RESERVE_CHARGE) %]
223
          [% IF (RESERVE_CHARGE) %]
226
	      <div class="dialog alert" id="reserve_fee">
224
	      <div class="dialog alert" id="reserve_fee">
227
	        There is a charge of [% RESERVE_CHARGE %] for placing this hold
225
	        There is a charge of [% RESERVE_CHARGE %] for placing this hold
228
	      </div>
226
	      </div>
229
	      [% END %]
227
          [% END %]
228
      [% END %][% END %]
230
229
231
            <form action="/cgi-bin/koha/opac-reserve.pl" method="post" id="hold-request-form">
230
            <form action="/cgi-bin/koha/opac-reserve.pl" method="post" id="hold-request-form">
232
            <input type="hidden" name="place_reserve" value="1"/>
231
            <input type="hidden" name="place_reserve" value="1"/>
Lines 235-272 Link Here
235
            <input type="hidden" name="biblionumbers" id="biblionumbers"/>
234
            <input type="hidden" name="biblionumbers" id="biblionumbers"/>
236
            <input type="hidden" name="selecteditems" id="selections"/>
235
            <input type="hidden" name="selecteditems" id="selections"/>
237
            <div id="bigloop">
236
            <div id="bigloop">
237
            [% extra_cols = 2 %]
238
              <table id="bibitemloop">
238
              <table id="bibitemloop">
239
                [% UNLESS ( none_available ) %]<tr>
239
                <tr>
240
                [% UNLESS ( none_available ) %]
240
                  <th>Hold</th>
241
                  <th>Hold</th>
242
                [% END %]
241
                  <th>Title</th>
243
                  <th>Title</th>
242
                  [% UNLESS ( item_level_itypes ) %]
244
                [% UNLESS ( item_level_itypes ) %]
243
                    <th>Item type</th>
245
                    <th>Item type</th>
244
                  [% END %]
246
                [% END %]
247
                [% UNLESS ( none_available ) %]
245
                  [% IF showholds && showpriority %]
248
                  [% IF showholds && showpriority %]
249
                    [% extra_cols = extra_cols + 1 %]
246
                  <th>Holds and priority</th>
250
                  <th>Holds and priority</th>
247
                  [% ELSIF showholds %]
251
                  [% ELSIF showholds %]
252
                    [% extra_cols = extra_cols + 1 %]
248
                  <th>Holds</th>
253
                  <th>Holds</th>
249
                  [% ELSIF showpriority %]
254
                  [% ELSIF showpriority %]
255
                    [% extra_cols = extra_cols + 1 %]
250
                  <th>Priority</th>
256
                  <th>Priority</th>
251
                  [% END %]
257
                  [% END %]
252
		  [% IF ( reserve_in_future ) %]
258
		  [% IF ( reserve_in_future ) %]
259
                    [% extra_cols = extra_cols + 1 %]
253
        <th>Hold starts on date</th>
260
        <th>Hold starts on date</th>
254
		  [% END %]
261
		  [% END %]
255
        <th>Hold not needed after</th>
262
        <th>Hold not needed after</th>
256
                  [% IF ( OPACItemHolds ) %]
257
                    <th id="place_on_hdr" style="display:none">Place on</th>
263
                    <th id="place_on_hdr" style="display:none">Place on</th>
258
                  [% END %]
259
                  [% UNLESS ( singleBranchMode ) %]
264
                  [% UNLESS ( singleBranchMode ) %]
260
		    [% IF ( choose_branch ) %]
265
		    [% IF ( choose_branch ) %]
266
                      [% extra_cols = extra_cols + 1 %]
261
                        <th>Pickup location</th>
267
                        <th>Pickup location</th>
262
		    [% END %]
268
		    [% END %]
263
                  [% END %]
269
                  [% END %]
264
                </tr>[% ELSE %]<tr><th colspan="5">Title</th></tr>[% END %]
270
                [% END %]
271
                </tr>
265
272
266
                [% FOREACH bibitemloo IN bibitemloop %]
273
                [% FOREACH bibitemloo IN bibitemloop %]
267
                  <tr>
274
                <tr>
268
                      [% IF ( bibitemloo.holdable ) %]
275
                    [% UNLESS none_available %]
269
                                    <td class="hold">
276
                    <td class="hold">
277
                        [% IF ( bibitemloo.holdable ) %]
270
                      <input class="reserve_mode" name="reserve_mode" type="hidden" value="single"/>
278
                      <input class="reserve_mode" name="reserve_mode" type="hidden" value="single"/>
271
                      <input class="single_bib" name="single_bib" type="hidden" value="[% bibitemloo.biblionumber %]"/>
279
                      <input class="single_bib" name="single_bib" type="hidden" value="[% bibitemloo.biblionumber %]"/>
272
                        <span class="confirmjs_hold" title="[% bibitemloo.biblionumber %]"></span>
280
                        <span class="confirmjs_hold" title="[% bibitemloo.biblionumber %]"></span>
Lines 277-294 Link Here
277
                                 value="any" />
285
                                 value="any" />
278
                          <label class="confirm_label" for="[% bibitemloo.checkitem_bib %]">Next available copy</label>
286
                          <label class="confirm_label" for="[% bibitemloo.checkitem_bib %]">Next available copy</label>
279
                        </span>
287
                        </span>
280
					</td>
288
                        [% ELSE %]
281
                      [% ELSE %]
289
                        &nbsp;
282
                                      [% UNLESS ( none_available ) %]<td class="hold">&nbsp;</td>[% END %]
290
                        [% END %]
283
                      [% END %]
291
                    </td>
284
                    [% IF ( bibitemloo.holdable ) %]<td class="title">[% ELSE %]<td class="title" colspan="5">[% END %]
292
                    [% END %]
293
                    <td class="title">
285
                      <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>
294
                      <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>
286
                      [% IF ( bibitemloo.author ) %],  by [% bibitemloo.author %][% END %]
295
                      [% IF ( bibitemloo.author ) %],  by [% bibitemloo.author %][% END %]
287
296
288
                      [% UNLESS ( bibitemloo.holdable ) %]
297
                      [% UNLESS ( bibitemloo.holdable ) %]
289
298
                          <div class="bibmessage">
290
                        [% IF ( bibitemloo.already_reserved ) %]
299
                        [% IF ( bibitemloo.already_reserved ) %]
291
                          <div class="bibmessage">You have already requested this title.</div>
300
                            You have already requested this title.
301
                        [% ELSIF ( bibitemloo.bib_available ) %]
302
                            No available items.
292
                        [% ELSE %]
303
                        [% ELSE %]
293
                          [% UNLESS ( bibitemloo.bib_available ) %]
304
                          [% UNLESS ( bibitemloo.bib_available ) %]
294
                            <div class="bibmessage">No available items.</div>
305
                            <div class="bibmessage">No available items.</div>
Lines 303-318 Link Here
303
314
304
315
305
                        [% END %]
316
                        [% END %]
306
317
                          </div>
318
                      [% END %]
307
                    </td>
319
                    </td>
308
                    [% IF ( bibitemloo.holdable ) %]
309
            <!-- HOLDABLE -->
310
                        [% UNLESS ( item_level_itypes ) %]
320
                        [% UNLESS ( item_level_itypes ) %]
311
                        <td class="itype">
321
                        <td class="itype">
312
                            [% IF ( bibitemloo.imageurl ) %]<img src="[% bibitemloo.imageurl %]" alt="" />[% END %]
322
                            [% IF ( bibitemloo.imageurl ) %]<img src="[% bibitemloo.imageurl %]" alt="" />[% END %]
313
                            [% bibitemloo.description %]
323
                            [% bibitemloo.description %]
314
                        </td>
324
                        </td>
315
                        [% END %]
325
                        [% END %]
326
                    [% IF ( bibitemloo.holdable ) %]
327
            <!-- HOLDABLE -->
316
                        [% IF showholds || showpriority %]
328
                        [% IF showholds || showpriority %]
317
                        <td class="priority">
329
                        <td class="priority">
318
                        [% IF showpriority %] [% bibitemloo.rank %] [% END %]
330
                        [% IF showpriority %] [% bibitemloo.rank %] [% END %]
Lines 337-404 Link Here
337
        <input name="expiration_date_[% bibitemloo.biblionumber %]" id="to" size="10" readonly="readonly" class="datepickerto" />
349
        <input name="expiration_date_[% bibitemloo.biblionumber %]" id="to" size="10" readonly="readonly" class="datepickerto" />
338
      <p style="margin:.3em 2em;">
350
      <p style="margin:.3em 2em;">
339
      <a href="#" style="font-size:85%;text-decoration:none;" onclick="document.getElementById('expiration_date_[% bibitemloo.biblionumber %]').value='';return false;">Clear date</a></p>
351
      <a href="#" style="font-size:85%;text-decoration:none;" onclick="document.getElementById('expiration_date_[% bibitemloo.biblionumber %]').value='';return false;">Clear date</a></p>
340
    </td>[% END %]
352
    </td>
341
353
342
                    [% IF ( bibitemloo.holdable ) %]
354
                        <td class="place_on_type" style="display:none">
343
		    <!-- HOLD ABLE -->
344
		    [% IF ( OPACItemHolds ) %]
345
		    <!-- ITEM HOLDS -->
355
		    <!-- ITEM HOLDS -->
346
                                          <td class="place_on_type" style="display:none">
356
                          <ul>
347
                                            <ul>
357
                              <li>
348
                                                <li>
358
                                  <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
349
                                                  [% UNLESS ( bibitemloo.holdable ) %]
359
                                         id="reqany_[% bibitemloo.biblionumber %]"
350
                                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
360
                                         class="selectany"
351
                                                           id="reqany_[% bibitemloo.biblionumber %]"
361
                                         value="Any"
352
                                                           class="selectany"
362
                                         checked="checked"
353
                                                           value="Any"
363
                                  />
354
                                                           disabled="disabled"
364
                                <label for="reqany_[% bibitemloo.biblionumber %]">Next available copy</label>
355
                                                    />
365
                              </li>
356
                                                  [% ELSE %]
366
                        [% IF ( bibitemloo.itemholdable ) %]
357
                                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
367
                              <li>
358
                                                           id="reqany_[% bibitemloo.biblionumber %]"
368
                                  <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
359
                                                           class="selectany"
369
                                         id="reqspecific_[% bibitemloo.biblionumber %]"
360
                                                           value="Any"
370
                                         class="selectspecific"
361
                                                           checked="checked"
371
                                         value="Specific"
362
                                                    />
372
                                  />
363
                                                  [% END %]
373
                                <label for="reqspecific_[% bibitemloo.biblionumber %]">A specific copy</label>
364
                                                  <label for="reqany_[% bibitemloo.biblionumber %]">Next available copy</label>
374
                              </li>
365
                                                </li>
375
                        [% END %]
366
                                                <li>
376
                          </ul>
367
                                                  [% UNLESS ( bibitemloo.holdable ) %]
377
                        </td>
368
                                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
378
369
                                                           id="reqspecific_[% bibitemloo.biblionumber %]"
379
                        [% UNLESS ( singleBranchMode ) %]
370
                                                           class="selectspecific"
371
                                                           disabled="disabled"
372
                                                           value="Specific"
373
                                                    />
374
                                                  [% ELSE %]
375
                                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
376
                                                           id="reqspecific_[% bibitemloo.biblionumber %]"
377
                                                           class="selectspecific"
378
                                                           value="Specific"
379
                                                    />
380
                                                  [% END %]
381
                                                  <label for="reqspecific_[% bibitemloo.biblionumber %]">A specific copy</label>
382
                                                </li>
383
                                            </ul>
384
                                          </td>
385
                                        [% END %][% END %]
386
387
                    [% UNLESS ( singleBranchMode ) %]
388
                        [% IF ( bibitemloo.holdable ) %]
389
			    [% IF ( choose_branch ) %]
380
			    [% IF ( choose_branch ) %]
390
                                          <td class="branch">
381
                        <td class="branch">
391
                         [% UNLESS ( bibitemloo.holdable ) %]
392
                            <select name="branch" id="branch_[% bibitemloo.biblionumber %]" disabled="disabled">
393
                              [% FOREACH branchChoicesLoo IN bibitemloo.branchChoicesLoop %]
394
                                [% IF ( branchChoicesLoo.selected ) %]
395
                                  <option value="[% branchChoicesLoo.value %]" selected="selected">[% branchChoicesLoo.branchname %]</option>
396
                                [% ELSE %]
397
                                  <option value="[% branchChoicesLoo.value %]">[% branchChoicesLoo.branchname %]</option>
398
                                [% END %]
399
                              [% END %]
400
                          </select>
401
                          [% ELSE %]
402
                            <select name="branch" id="branch_[% bibitemloo.biblionumber %]">
382
                            <select name="branch" id="branch_[% bibitemloo.biblionumber %]">
403
                              [% FOREACH branchChoicesLoo IN bibitemloo.branchChoicesLoop %]
383
                              [% FOREACH branchChoicesLoo IN bibitemloo.branchChoicesLoop %]
404
                                [% IF ( branchChoicesLoo.selected ) %]
384
                                [% IF ( branchChoicesLoo.selected ) %]
Lines 408-422 Link Here
408
                                [% END %]
388
                                [% END %]
409
                              [% END %]
389
                              [% END %]
410
                            </select>
390
                            </select>
411
                          [% END %]
412
                       </td>
391
                       </td>
413
			    [% END %]
392
                            [% END %]
414
		        [% END %]
393
                        [% END %]
415
                    [% END %]
394
                    [% ELSIF NOT none_available %]
395
                       <td colspan="[% extra_cols %]">&nbsp;</td>
396
                    [% END # holdable%]
416
                  </tr>
397
                  </tr>
417
398
418
                  [% IF ( OPACItemHolds ) %]
399
                    [% IF ( bibitemloo.itemholdable ) %]
419
                  [% IF ( bibitemloo.holdable ) %]
420
                    <tr class="copiesrow" id="copiesrow_[% bibitemloo.biblionumber %]">
400
                    <tr class="copiesrow" id="copiesrow_[% bibitemloo.biblionumber %]">
421
                      <td>&nbsp;</td>
401
                      <td>&nbsp;</td>
422
                      <td colspan="[% itemtable_colspan %]">
402
                      <td colspan="[% itemtable_colspan %]">
Lines 495-505 Link Here
495
                        </table>
475
                        </table>
496
                      </td>
476
                      </td>
497
                    </tr>
477
                    </tr>
498
                  [% END %]<!-- bib_available -->
478
                    [% END # itemholdable%]
499
                  [% END %]<!-- OPACItemHolds -->
479
                [% END %]<!-- bibitemloop -->
500
                [% END %]
480
              </table>
501
              </table><!-- bibitemloop -->
502
              [% END %] <!-- if message -->
503
            </div><!-- bigloop -->
481
            </div><!-- bigloop -->
504
482
505
            [% UNLESS ( message ) %]
483
            [% UNLESS ( message ) %]
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt (-11 / +7 lines)
Lines 269-286 function highlightOn() { Link Here
269
269
270
				<p>
270
				<p>
271
                                [% IF ( RequestOnOpac ) %]
271
                                [% IF ( RequestOnOpac ) %]
272
					[% UNLESS ( GROUP_RESULT.norequests ) %]
272
                                    [% UNLESS ( GROUP_RESULT.norequests ) %]
273
						[% IF ( opacuserlogin ) %]
273
                                        [% IF ( opacuserlogin ) %]
274
							[% IF ( AllowOnShelfHolds ) %]
274
                                            [% IF ( GROUP_RESULT.holdable ) %]
275
                                <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-->
275
                                <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-->
276
							[% ELSE %]
276
                                            [% END %]
277
								[% IF ( GROUP_RESULT.itemsissued ) %]
277
                                        [% END %]
278
                                    <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-->
278
                                    [% END %]
279
								[% END %]
279
                                [% END %]
280
							[% END %]
281
						[% END %]
282
					[% END %]
283
				[% END %]
284
280
285
				[% 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 ) %]
281
				[% 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 ) %]
286
                                    <a href="/cgi-bin/koha/opac-search.pl?q=callnum:[% GROUP_RESULT.classification |url %]">
282
                                    <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 623-634 $(document).ready(function(){ Link Here
623
                [% IF ( RequestOnOpac ) %]
623
                [% IF ( RequestOnOpac ) %]
624
                    [% UNLESS ( SEARCH_RESULT.norequests ) %]
624
                    [% UNLESS ( SEARCH_RESULT.norequests ) %]
625
                        [% IF ( opacuserlogin ) %]
625
                        [% IF ( opacuserlogin ) %]
626
                            [% IF ( AllowOnShelfHolds ) %]
626
                            [% IF ( SEARCH_RESULT.holdable ) %]
627
                                <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-->
627
                                <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-->
628
                            [% ELSE %]
629
                                [% IF ( SEARCH_RESULT.itemsissued ) %]
630
                                    <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-->
631
                                [% END %]
632
                            [% END %]
628
                            [% END %]
633
                        [% END %]
629
                        [% END %]
634
                    [% END %]
630
                    [% END %]
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt (-1 / +1 lines)
Lines 406-412 $(function() { Link Here
406
      [% IF ( RequestOnOpac ) %]
406
      [% IF ( RequestOnOpac ) %]
407
          [% UNLESS ( itemsloo.norequests ) %]
407
          [% UNLESS ( itemsloo.norequests ) %]
408
            [% IF ( opacuserlogin ) %]
408
            [% IF ( opacuserlogin ) %]
409
              [% IF ( AllowOnShelfHolds ) %]
409
              [% IF ( itemsloo.allow_onshelf_holds ) %]
410
                <a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% itemsloo.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue-->
410
                <a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% itemsloo.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue-->
411
              [% ELSE %]
411
              [% ELSE %]
412
                [% IF ( itemsloo.itemsissued ) %]
412
                [% IF ( itemsloo.itemsissued ) %]
(-)a/opac/opac-ISBDdetail.pl (-7 / +2 lines)
Lines 70-86 my $biblionumber = $query->param('biblionumber'); Link Here
70
$biblionumber = int($biblionumber);
70
$biblionumber = int($biblionumber);
71
71
72
# get biblionumbers stored in the cart
72
# get biblionumbers stored in the cart
73
my @cart_list;
73
if(my $cart_list = $query->cookie("bib_list")){
74
74
    my @cart_list = split(/\//, $cart_list);
75
if($query->cookie("bib_list")){
76
    my $cart_list = $query->cookie("bib_list");
77
    @cart_list = split(/\//, $cart_list);
78
    if ( grep {$_ eq $biblionumber} @cart_list) {
75
    if ( grep {$_ eq $biblionumber} @cart_list) {
79
        $template->param( incart => 1 );
76
        $template->param( incart => 1 );
80
    }
77
    }
81
}
78
}
82
79
83
$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
84
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
80
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
85
81
86
my $marcflavour      = C4::Context->preference("marcflavour");
82
my $marcflavour      = C4::Context->preference("marcflavour");
Lines 163-169 foreach ( @$reviews ) { Link Here
163
159
164
$template->param(
160
$template->param(
165
    RequestOnOpac       => C4::Context->preference("RequestOnOpac"),
161
    RequestOnOpac       => C4::Context->preference("RequestOnOpac"),
166
    AllowOnShelfHolds   => C4::Context->preference('AllowOnShelfHolds'),
167
    norequests   => $norequests,
162
    norequests   => $norequests,
168
    ISBD         => $res,
163
    ISBD         => $res,
169
    biblionumber => $biblionumber,
164
    biblionumber => $biblionumber,
(-)a/opac/opac-MARCdetail.pl (-6 / +2 lines)
Lines 83-99 $template->param( Link Here
83
);
83
);
84
84
85
# get biblionumbers stored in the cart
85
# get biblionumbers stored in the cart
86
my @cart_list;
86
if(my $cart_list = $query->cookie("bib_list")){
87
87
    my @cart_list = split(/\//, $cart_list);
88
if($query->cookie("bib_list")){
89
    my $cart_list = $query->cookie("bib_list");
90
    @cart_list = split(/\//, $cart_list);
91
    if ( grep {$_ eq $biblionumber} @cart_list) {
88
    if ( grep {$_ eq $biblionumber} @cart_list) {
92
        $template->param( incart => 1 );
89
        $template->param( incart => 1 );
93
    }
90
    }
94
}
91
}
95
92
96
$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
97
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
93
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
98
94
99
# adding the $RequestOnOpac param
95
# adding the $RequestOnOpac param
(-)a/opac/opac-detail.pl (-2 lines)
Lines 388-395 if ($session->param('busc')) { Link Here
388
}
388
}
389
389
390
390
391
392
$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
393
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
391
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
394
392
395
393
(-)a/opac/opac-reserve.pl (-18 / +26 lines)
Lines 400-405 foreach my $biblioNum (@biblionumbers) { Link Here
400
400
401
    $biblioLoopIter{itemLoop} = [];
401
    $biblioLoopIter{itemLoop} = [];
402
    my $numCopiesAvailable = 0;
402
    my $numCopiesAvailable = 0;
403
    my $numCopiesOPACAvailable = 0;
403
    foreach my $itemInfo (@{$biblioData->{itemInfos}}) {
404
    foreach my $itemInfo (@{$biblioData->{itemInfos}}) {
404
        my $itemNum = $itemInfo->{itemnumber};
405
        my $itemNum = $itemInfo->{itemnumber};
405
        my $itemLoopIter = {};
406
        my $itemLoopIter = {};
Lines 492-507 foreach my $biblioNum (@biblionumbers) { Link Here
492
493
493
        my $branch = ( C4::Context->preference('ReservesControlBranch') eq 'ItemHomeLibrary' ) ? $itemInfo->{'homebranch'} : $borr->{'branchcode'};
494
        my $branch = ( C4::Context->preference('ReservesControlBranch') eq 'ItemHomeLibrary' ) ? $itemInfo->{'homebranch'} : $borr->{'branchcode'};
494
495
495
        my $branchitemrule = GetBranchItemRule( $branch, $itemInfo->{'itype'} );
496
        my $policy_holdallowed = !$itemLoopIter->{already_reserved};
496
        my $policy_holdallowed = 1;
497
        if ($policy_holdallowed) {
497
498
            if (my $branchitemrule = GetBranchItemRule( $branch, $itemInfo->{'itype'} )) {
498
        if ( $branchitemrule->{'holdallowed'} == 0 ||
499
                $policy_holdallowed =
499
                ( $branchitemrule->{'holdallowed'} == 1 && $borr->{'branchcode'} ne $itemInfo->{'homebranch'} ) ) {
500
                  ($branchitemrule->{'holdallowed'} == 2) ||
500
            $policy_holdallowed = 0;
501
                  ($branchitemrule->{'holdallowed'} == 1
502
                      && $borr->{'branchcode'} eq $itemInfo->{'homebranch'});
503
            } else {
504
                $policy_holdallowed = 0; # No rule - not allowed
505
            }
501
        }
506
        }
502
507
        $policy_holdallowed &&=
503
        if (IsAvailableForItemLevelRequest($itemNum) and $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum) and ($itemLoopIter->{already_reserved} ne 1)) {
508
            IsAvailableForItemLevelRequest($itemInfo,$borr) &&
504
            $itemLoopIter->{available} = 1;
509
            CanItemBeReserved($borrowernumber,$itemNum);
510
511
        if ($policy_holdallowed) {
512
            if ( OPACItemHoldsAllowed( $itemInfo, $borr ) ) {
513
                $itemLoopIter->{available} = 1;
514
                $numCopiesOPACAvailable++;
515
            }
505
            $numCopiesAvailable++;
516
            $numCopiesAvailable++;
506
        }
517
        }
507
518
Lines 527-541 foreach my $biblioNum (@biblionumbers) { Link Here
527
        $numBibsAvailable++;
538
        $numBibsAvailable++;
528
        $biblioLoopIter{bib_available} = 1;
539
        $biblioLoopIter{bib_available} = 1;
529
        $biblioLoopIter{holdable} = 1;
540
        $biblioLoopIter{holdable} = 1;
530
        $anyholdable = 1;
541
        $biblioLoopIter{itemholdable} = 1 if $numCopiesOPACAvailable;
531
    }
542
    }
532
    if ($biblioLoopIter{already_reserved}) {
543
    if ($biblioLoopIter{already_reserved}) {
533
        $biblioLoopIter{holdable} = undef;
544
        $biblioLoopIter{holdable} = undef;
534
        $anyholdable = undef;
545
        $biblioLoopIter{itemholdable} = undef;
535
    }
536
    if(not CanBookBeReserved($borrowernumber,$biblioNum)){
537
        $biblioLoopIter{holdable} = undef;
538
        $anyholdable = undef;
539
    }
546
    }
540
    if(not C4::Context->preference('AllowHoldsOnPatronsPossessions') and CheckIfIssuedToPatron($borrowernumber,$biblioNum)) {
547
    if(not C4::Context->preference('AllowHoldsOnPatronsPossessions') and CheckIfIssuedToPatron($borrowernumber,$biblioNum)) {
541
        $biblioLoopIter{holdable} = undef;
548
        $biblioLoopIter{holdable} = undef;
Lines 543-549 foreach my $biblioNum (@biblionumbers) { Link Here
543
        $anyholdable = undef;
550
        $anyholdable = undef;
544
    }
551
    }
545
552
553
    $biblioLoopIter{holdable} &&= CanBookBeReserved($borrowernumber,$biblioNum);
554
546
    push @$biblioLoop, \%biblioLoopIter;
555
    push @$biblioLoop, \%biblioLoopIter;
556
557
    $anyholdable = 1 if $biblioLoopIter{holdable};
547
}
558
}
548
559
549
if ( $numBibsAvailable == 0 || !$anyholdable) {
560
if ( $numBibsAvailable == 0 || !$anyholdable) {
Lines 551-559 if ( $numBibsAvailable == 0 || !$anyholdable) { Link Here
551
}
562
}
552
563
553
my $itemTableColspan = 7;
564
my $itemTableColspan = 7;
554
if (! $template->{VARS}->{'OPACItemHolds'}) {
555
    $itemTableColspan--;
556
}
557
if (! $template->{VARS}->{'singleBranchMode'}) {
565
if (! $template->{VARS}->{'singleBranchMode'}) {
558
    $itemTableColspan--;
566
    $itemTableColspan--;
559
}
567
}
(-)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 516-523 if ($@ || $error) { Link Here
516
    exit;
518
    exit;
517
}
519
}
518
520
521
my $borrower = $borrowernumber ? GetMember( borrowernumber => $borrowernumber ) : undef;
522
519
# At this point, each server has given us a result set
523
# At this point, each server has given us a result set
520
# now we build that set for template display
524
# now we build that set for template display
525
my %allow_onshelf_holds;
521
my @sup_results_array;
526
my @sup_results_array;
522
for (my $i=0;$i<@servers;$i++) {
527
for (my $i=0;$i<@servers;$i++) {
523
    my $server = $servers[$i];
528
    my $server = $servers[$i];
Lines 532-542 for (my $i=0;$i<@servers;$i++) { Link Here
532
                # we need to set the offset parameter of searchResults to 0
537
                # we need to set the offset parameter of searchResults to 0
533
                my @group_results = searchResults( 'opac', $query_desc, $group->{'group_count'},$results_per_page, 0, $scan,
538
                my @group_results = searchResults( 'opac', $query_desc, $group->{'group_count'},$results_per_page, 0, $scan,
534
                                                   $group->{"RECORDS"});
539
                                                   $group->{"RECORDS"});
540
                if ($borrower) {
541
                    $_->{holdable} =
542
                        IsAvailableForItemLevelRequest($_, $borrower) &&
543
                        OPACItemHoldsAllowed($_, $borrower)
544
                      foreach @group_results;
545
                }
535
                push @newresults, { group_label => $group->{'group_label'}, GROUP_RESULTS => \@group_results };
546
                push @newresults, { group_label => $group->{'group_label'}, GROUP_RESULTS => \@group_results };
536
            }
547
            }
537
        } else {
548
        } else {
538
            @newresults = searchResults('opac', $query_desc, $hits, $results_per_page, $offset, $scan,
549
            @newresults = searchResults('opac', $query_desc, $hits, $results_per_page, $offset, $scan,
539
                                        $results_hashref->{$server}->{"RECORDS"});
550
                                        $results_hashref->{$server}->{"RECORDS"});
551
            if ($borrower) {
552
                $_->{holdable} =
553
                    IsAvailableForItemLevelRequest($_, $borrower) &&
554
                    OPACItemHoldsAllowed($_, $borrower)
555
                  foreach @newresults;
556
            }
540
        }
557
        }
541
558
542
        # must define a value for size if not present in DB
559
        # must define a value for size if not present in DB
(-)a/reserve/request.pl (-2 / +1 lines)
Lines 464-470 foreach my $biblionumber (@biblionumbers) { Link Here
464
            if (
464
            if (
465
                   $policy_holdallowed
465
                   $policy_holdallowed
466
                && !$item->{cantreserve}
466
                && !$item->{cantreserve}
467
                && IsAvailableForItemLevelRequest($itemnumber)
467
                && IsAvailableForItemLevelRequest($item, $borrowerinfo)
468
                && CanItemBeReserved(
468
                && CanItemBeReserved(
469
                    $borrowerinfo->{borrowernumber}, $itemnumber
469
                    $borrowerinfo->{borrowernumber}, $itemnumber
470
                )
470
                )
471
- 

Return to bug 5786