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

(-)a/C4/Letters.pm (-15 lines)
Lines 602-622 sub _parseletter_sth { Link Here
602
sub _parseletter {
602
sub _parseletter {
603
    my ( $letter, $table, $values ) = @_;
603
    my ( $letter, $table, $values ) = @_;
604
604
605
    if ( $table eq 'reserves' && $values->{'waitingdate'} ) {
606
        my @waitingdate = split /-/, $values->{'waitingdate'};
607
608
        $values->{'expirationdate'} = '';
609
        if( C4::Context->preference('ExpireReservesMaxPickUpDelay') &&
610
        C4::Context->preference('ReservesMaxPickUpDelay') ) {
611
            my $dt = dt_from_string();
612
            $dt->add( days => C4::Context->preference('ReservesMaxPickUpDelay') );
613
            $values->{'expirationdate'} = output_pref({ dt => $dt, dateonly => 1 });
614
        }
615
616
        $values->{'waitingdate'} = output_pref({ dt => dt_from_string( $values->{'waitingdate'} ), dateonly => 1 });
617
618
    }
619
620
    if ($letter->{content} && $letter->{content} =~ /<<today>>/) {
605
    if ($letter->{content} && $letter->{content} =~ /<<today>>/) {
621
        my $todaysdate = output_pref( DateTime->now() );
606
        my $todaysdate = output_pref( DateTime->now() );
622
        $letter->{content} =~ s/<<today>>/$todaysdate/go;
607
        $letter->{content} =~ s/<<today>>/$todaysdate/go;
(-)a/C4/Reserves.pm (-23 / +171 lines)
Lines 175-180 sub AddReserve { Link Here
175
        $waitingdate = $resdate;
175
        $waitingdate = $resdate;
176
    }
176
    }
177
177
178
    my $item = C4::Items::GetItem( $checkitem );
179
    my $lastpickupdate = GetLastPickupDate( undef, $item );
180
178
    #eval {
181
    #eval {
179
    # updates take place here
182
    # updates take place here
180
    if ( $fee > 0 ) {
183
    if ( $fee > 0 ) {
Lines 194-209 sub AddReserve { Link Here
194
    my $query = qq/
197
    my $query = qq/
195
        INSERT INTO reserves
198
        INSERT INTO reserves
196
            (borrowernumber,biblionumber,reservedate,branchcode,constrainttype,
199
            (borrowernumber,biblionumber,reservedate,branchcode,constrainttype,
197
            priority,reservenotes,itemnumber,found,waitingdate,expirationdate)
200
            priority,reservenotes,itemnumber,found,waitingdate,expirationdate,lastpickupdate)
198
        VALUES
201
        VALUES
199
             (?,?,?,?,?,
202
             (?,?,?,?,?,
200
             ?,?,?,?,?,?)
203
             ?,?,?,?,?,?,?)
201
    /;
204
    /;
202
    my $sth = $dbh->prepare($query);
205
    my $sth = $dbh->prepare($query);
203
    $sth->execute(
206
    $sth->execute(
204
        $borrowernumber, $biblionumber, $resdate, $branch,
207
        $borrowernumber, $biblionumber, $resdate, $branch,
205
        $const,          $priority,     $notes,   $checkitem,
208
        $const,          $priority,     $notes,   $checkitem,
206
        $found,          $waitingdate,	$expdate
209
        $found,          $waitingdate,  $expdate, $lastpickupdate
207
    );
210
    );
208
211
209
    # Send e-mail to librarian if syspref is active
212
    # Send e-mail to librarian if syspref is active
Lines 806-815 sub GetReservesToBranch { Link Here
806
809
807
sub GetReservesForBranch {
810
sub GetReservesForBranch {
808
    my ($frombranch) = @_;
811
    my ($frombranch) = @_;
809
    my $dbh = C4::Context->dbh;
810
812
811
    my $query = "
813
    my $dbh          = C4::Context->dbh;
812
        SELECT reserve_id,borrowernumber,reservedate,itemnumber,waitingdate
814
    my $query        = "
815
        SELECT reserve_id, borrowernumber, reservedate, itemnumber, waitingdate, lastpickupdate
813
        FROM   reserves 
816
        FROM   reserves 
814
        WHERE   priority='0'
817
        WHERE   priority='0'
815
        AND found='W'
818
        AND found='W'
Lines 874-879 sub GetReserveStatus { Link Here
874
    return ''; # empty string here will remove need for checking undef, or less log lines
877
    return ''; # empty string here will remove need for checking undef, or less log lines
875
}
878
}
876
879
880
=head2 GetLastPickupDate
881
882
  my $lastpickupdate = GetLastPickupDate($reserve, $item);
883
  my $lastpickupdate = GetLastPickupDate($reserve, $item, $borrower);
884
  my $lastpickupdate = GetLastPickupDate(undef,    $item);
885
886
Gets the last pickup date from the issuingrules for the given reserves-row and sets the
887
$reserve->{lastpickupdate}.-value.
888
If the reserves-row is not passed, function tries to figure it out from the item-row.
889
890
Calculating the last pickup date respects Calendar holidays and skips to the next open day.
891
892
@PARAM1 koha.reserves-row
893
@PARAM2 koha.items-row, If the reserve is not given, an item must be given to be
894
                        able to find a reservation
895
@PARAM3 koha.borrowers-row, OPTIONAL
896
RETURNS DateTime, depicting the last pickup date.
897
=cut
898
899
sub GetLastPickupDate {
900
    my ($reserve, $item, $borrower) = @_;
901
902
    ##Verify parameters
903
    if ( not defined $reserve and not defined $item ) {
904
        warn "C4::Reserves::GetMaxPickupDate(), is called without a reserve and a item";
905
        return;
906
    }
907
    if ( defined $reserve and not defined $item ) {
908
        $item = C4::Items::GetItem( $reserve->{itemnumber} );
909
    }
910
    unless ( defined $reserve ) {
911
        my $reserve = GetReservesFromItemnumber( $item->{itemnumber} );
912
    }
913
914
    my $date = $reserve->{waitingdate};
915
    unless ( $date ) { #It is possible that a reserve is just caught and it doesn't have a waitingdate yet.
916
        $date = DateTime->now( time_zone => C4::Context->tz() ); #So default to NOW()
917
    }
918
    else {
919
        $date = (ref $reserve->{waitingdate} eq 'DateTime') ? $reserve->{waitingdate}  :  dt_from_string($reserve->{waitingdate});
920
    }
921
    $borrower = C4::Members::GetMember( 'borrowernumber' => $reserve->{borrowernumber} ) unless $borrower;
922
923
    ##Get churning the LastPickupDate
924
    my $controlbranch = GetReservesControlBranch( $item, $borrower );
925
926
    my $issuingrule = C4::Circulation::GetIssuingRule( $borrower->{categorycode}, $item->{itype}, $controlbranch );
927
928
    my $holdspickupwait = 0;
929
    if ( defined($issuingrule)
930
        and defined $issuingrule->{holdspickupwait} ) {
931
        $holdspickupwait = $issuingrule->{holdspickupwait}
932
    }
933
    $date->add( days => $holdspickupwait );
934
935
    my $calendar = Koha::Calendar->new( branchcode => $reserve->{'branchcode'} );
936
    my $is_holiday = $calendar->is_holiday( $date );
937
938
    while ( $is_holiday ) {
939
        $date->add( days => 1 );
940
        $is_holiday = $calendar->is_holiday( $date );
941
    }
942
943
    $reserve->{lastpickupdate} = $date->ymd();
944
    return $date;
945
}
946
=head2 GetReservesControlBranch
947
948
  $branchcode = &GetReservesControlBranch($borrower, $item)
949
950
Returns the branchcode to consider to check hold rules against
951
952
=cut
953
954
sub GetReservesControlBranch {
955
    my ( $borrower, $item ) = @_;
956
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
957
    my $hbr           = C4::Context->preference('HomeOrHoldingBranch') || "homebranch";
958
    my $branchcode    = "*";
959
    if ( $controlbranch eq "ItemHomeLibrary" ) {
960
        $branchcode = $item->{$hbr};
961
    } elsif ( $controlbranch eq "PatronLibrary" ) {
962
        $branchcode = $borrower->{branchcode};
963
    }
964
    return $branchcode;
965
}
966
877
=head2 CheckReserves
967
=head2 CheckReserves
878
968
879
  ($status, $reserve, $all_reserves) = &CheckReserves($itemnumber);
969
  ($status, $reserve, $all_reserves) = &CheckReserves($itemnumber);
Lines 1018-1032 sub CancelExpiredReserves { Link Here
1018
  
1108
  
1019
    # Cancel reserves that have been waiting too long
1109
    # Cancel reserves that have been waiting too long
1020
    if ( C4::Context->preference("ExpireReservesMaxPickUpDelay") ) {
1110
    if ( C4::Context->preference("ExpireReservesMaxPickUpDelay") ) {
1021
        my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay");
1022
        my $charge = C4::Context->preference("ExpireReservesMaxPickUpDelayCharge");
1111
        my $charge = C4::Context->preference("ExpireReservesMaxPickUpDelayCharge");
1023
        my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays');
1112
        my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays');
1024
1113
1025
        my $today = dt_from_string();
1114
        my $today = dt_from_string();
1026
1115
1027
        my $query = "SELECT * FROM reserves WHERE TO_DAYS( NOW() ) - TO_DAYS( waitingdate ) > ? AND found = 'W' AND priority = 0";
1116
        my $query = "SELECT * FROM reserves WHERE NOW() > lastpickupdate AND found = 'W' AND priority = 0";
1028
        $sth = $dbh->prepare( $query );
1117
        $sth = $dbh->prepare( $query );
1029
        $sth->execute( $max_pickup_delay );
1118
        $sth->execute();
1030
1119
1031
        while ( my $res = $sth->fetchrow_hashref ) {
1120
        while ( my $res = $sth->fetchrow_hashref ) {
1032
            my $do_cancel = 1;
1121
            my $do_cancel = 1;
Lines 1284-1292 sub ModReserveStatus { Link Here
1284
    my ($itemnumber, $newstatus) = @_;
1373
    my ($itemnumber, $newstatus) = @_;
1285
    my $dbh = C4::Context->dbh;
1374
    my $dbh = C4::Context->dbh;
1286
1375
1287
    my $query = "UPDATE reserves SET found = ?, waitingdate = NOW() WHERE itemnumber = ? AND found IS NULL AND priority = 0";
1376
    my $now = dt_from_string;
1377
    my $reserve = $dbh->selectrow_hashref(q{
1378
        SELECT *
1379
        FROM reserves
1380
        WHERE itemnumber = ?
1381
            AND found IS NULL
1382
            AND priority = 0
1383
    }, {}, $itemnumber);
1384
    return unless $reserve;
1385
1386
    my $lastpickupdate = GetLastPickupDate( $reserve );
1387
    my $query = q{
1388
        UPDATE reserves
1389
        SET found = ?,
1390
            waitingdate = ?,
1391
            maxpickupdate = ?
1392
        WHERE itemnumber = ?
1393
            AND found IS NULL
1394
            AND priority = 0
1395
    };
1288
    my $sth_set = $dbh->prepare($query);
1396
    my $sth_set = $dbh->prepare($query);
1289
    $sth_set->execute( $newstatus, $itemnumber );
1397
    $sth_set->execute( $newstatus, $now, $lastpickupdate, $itemnumber );
1290
1398
1291
    if ( C4::Context->preference("ReturnToShelvingCart") && $newstatus ) {
1399
    if ( C4::Context->preference("ReturnToShelvingCart") && $newstatus ) {
1292
      CartToShelf( $itemnumber );
1400
      CartToShelf( $itemnumber );
Lines 1331-1359 sub ModReserveAffect { Link Here
1331
    # If we affect a reserve that has to be transfered, don't set to Waiting
1439
    # If we affect a reserve that has to be transfered, don't set to Waiting
1332
    my $query;
1440
    my $query;
1333
    if ($transferToDo) {
1441
    if ($transferToDo) {
1334
    $query = "
1442
        $query = "
1335
        UPDATE reserves
1443
            UPDATE reserves
1336
        SET    priority = 0,
1444
            SET    priority = 0,
1337
               itemnumber = ?,
1445
                   itemnumber = ?,
1338
               found = 'T'
1446
                   found = 'T'
1339
        WHERE borrowernumber = ?
1447
            WHERE borrowernumber = ?
1340
          AND biblionumber = ?
1448
              AND biblionumber = ?
1341
    ";
1449
        ";
1450
        $sth = $dbh->prepare($query);
1451
        $sth->execute( $itemnumber, $borrowernumber,$biblionumber);
1342
    }
1452
    }
1343
    else {
1453
    else {
1344
    # affect the reserve to Waiting as well.
1454
        # affect the reserve to Waiting as well.
1455
        my $item = C4::Items::GetItem( $itemnumber );
1456
        my $lastpickupdate = GetLastPickupDate( $request, $item );
1345
        $query = "
1457
        $query = "
1346
            UPDATE reserves
1458
            UPDATE reserves
1347
            SET     priority = 0,
1459
            SET     priority = 0,
1348
                    found = 'W',
1460
                    found = 'W',
1349
                    waitingdate = NOW(),
1461
                    waitingdate = NOW(),
1462
                    lastpickupdate = ?,
1350
                    itemnumber = ?
1463
                    itemnumber = ?
1351
            WHERE borrowernumber = ?
1464
            WHERE borrowernumber = ?
1352
              AND biblionumber = ?
1465
              AND biblionumber = ?
1353
        ";
1466
        ";
1467
        $sth = $dbh->prepare($query);
1468
        $sth->execute( $lastpickupdate, $itemnumber, $borrowernumber,$biblionumber);
1354
    }
1469
    }
1355
    $sth = $dbh->prepare($query);
1356
    $sth->execute( $itemnumber, $borrowernumber,$biblionumber);
1357
    _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ) if ( !$transferToDo && !$already_on_shelf );
1470
    _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ) if ( !$transferToDo && !$already_on_shelf );
1358
    _FixPriority( { biblionumber => $biblionumber } );
1471
    _FixPriority( { biblionumber => $biblionumber } );
1359
    if ( C4::Context->preference("ReturnToShelvingCart") ) {
1472
    if ( C4::Context->preference("ReturnToShelvingCart") ) {
Lines 1429-1434 sub GetReserveInfo { Link Here
1429
                   reserves.biblionumber,
1542
                   reserves.biblionumber,
1430
                   reserves.branchcode,
1543
                   reserves.branchcode,
1431
                   reserves.waitingdate,
1544
                   reserves.waitingdate,
1545
                   reserves.lastpickupdate,
1432
                   notificationdate,
1546
                   notificationdate,
1433
                   reminderdate,
1547
                   reminderdate,
1434
                   priority,
1548
                   priority,
Lines 1840-1845 sub _Findgroupreserve { Link Here
1840
               reserves.borrowernumber      AS borrowernumber,
1954
               reserves.borrowernumber      AS borrowernumber,
1841
               reserves.reservedate         AS reservedate,
1955
               reserves.reservedate         AS reservedate,
1842
               reserves.branchcode          AS branchcode,
1956
               reserves.branchcode          AS branchcode,
1957
               reserves.lastpickupdate       AS maxpickupdate,
1843
               reserves.cancellationdate    AS cancellationdate,
1958
               reserves.cancellationdate    AS cancellationdate,
1844
               reserves.found               AS found,
1959
               reserves.found               AS found,
1845
               reserves.reservenotes        AS reservenotes,
1960
               reserves.reservenotes        AS reservenotes,
Lines 1872-1877 sub _Findgroupreserve { Link Here
1872
               reserves.borrowernumber      AS borrowernumber,
1987
               reserves.borrowernumber      AS borrowernumber,
1873
               reserves.reservedate         AS reservedate,
1988
               reserves.reservedate         AS reservedate,
1874
               reserves.branchcode          AS branchcode,
1989
               reserves.branchcode          AS branchcode,
1990
               reserves.lastpickupdate       AS maxpickupdate,
1875
               reserves.cancellationdate    AS cancellationdate,
1991
               reserves.cancellationdate    AS cancellationdate,
1876
               reserves.found               AS found,
1992
               reserves.found               AS found,
1877
               reserves.reservenotes        AS reservenotes,
1993
               reserves.reservenotes        AS reservenotes,
Lines 1904-1909 sub _Findgroupreserve { Link Here
1904
               reserves.reservedate                AS reservedate,
2020
               reserves.reservedate                AS reservedate,
1905
               reserves.waitingdate                AS waitingdate,
2021
               reserves.waitingdate                AS waitingdate,
1906
               reserves.branchcode                 AS branchcode,
2022
               reserves.branchcode                 AS branchcode,
2023
               reserves.lastpickupdate              AS maxpickupdate,
1907
               reserves.cancellationdate           AS cancellationdate,
2024
               reserves.cancellationdate           AS cancellationdate,
1908
               reserves.found                      AS found,
2025
               reserves.found                      AS found,
1909
               reserves.reservenotes               AS reservenotes,
2026
               reserves.reservenotes               AS reservenotes,
Lines 2117-2122 sub MoveReserve { Link Here
2117
    }
2234
    }
2118
}
2235
}
2119
2236
2237
=head MoveWaitingdate
2238
2239
  #Move waitingdate two months and fifteen days forward.
2240
  my $dateDuration = DateTime::Duration->new( months => 2, days => 15 );
2241
  $reserve = MoveWaitingdate( $reserve, $dateDuration);
2242
2243
  #Move waitingdate one year and eleven days backwards.
2244
  my $dateDuration = DateTime::Duration->new( years => -1, days => -11 );
2245
  $reserve = MoveWaitingdate( $reserve, $dateDuration);
2246
2247
Moves the waitingdate and updates the lastpickupdate to match.
2248
Is intended to be used from automated tests, because under normal library
2249
operations there should be NO REASON to move the waitingdate.
2250
2251
@PARAM1 koha.reserves-row, with waitingdate set.
2252
@PARAM2 DateTime::Duration, with the desired offset.
2253
RETURNS koha.reserve-row, with keys waitingdate and lastpickupdate updated.
2254
=cut
2255
sub MoveWaitingdate {
2256
    my ($reserve, $dateDuration) = @_;
2257
2258
    my $dt = dt_from_string( $reserve->{waitingdate} );
2259
    $dt->add_duration( $dateDuration );
2260
    $reserve->{waitingdate} = $dateDuration->ymd();
2261
2262
    GetLastPickupDate( $reserve ); #Update the $reserve->{lastpickupdate}
2263
2264
    return $reserve;
2265
}
2266
2120
=head2 MergeHolds
2267
=head2 MergeHolds
2121
2268
2122
  MergeHolds($dbh,$to_biblio, $from_biblio);
2269
  MergeHolds($dbh,$to_biblio, $from_biblio);
Lines 2213-2219 sub RevertWaitingStatus { Link Here
2213
    SET
2360
    SET
2214
      priority = 1,
2361
      priority = 1,
2215
      found = NULL,
2362
      found = NULL,
2216
      waitingdate = NULL
2363
      waitingdate = NULL,
2364
      lastpickupdate = NULL,
2217
    WHERE
2365
    WHERE
2218
      reserve_id = ?
2366
      reserve_id = ?
2219
    ";
2367
    ";
(-)a/Koha/Schema/Result/Reserve.pm (+7 lines)
Lines 139-144 __PACKAGE__->table("reserves"); Link Here
139
  datetime_undef_if_invalid: 1
139
  datetime_undef_if_invalid: 1
140
  is_nullable: 1
140
  is_nullable: 1
141
141
142
=head2 lastpickupdate
143
  date_type: 'date'
144
  datetime_undef_if_invalid: 1
145
  is_nullable: 1
146
142
=cut
147
=cut
143
148
144
__PACKAGE__->add_columns(
149
__PACKAGE__->add_columns(
Lines 199-204 __PACKAGE__->add_columns( Link Here
199
    datetime_undef_if_invalid => 1,
204
    datetime_undef_if_invalid => 1,
200
    is_nullable => 1,
205
    is_nullable => 1,
201
  },
206
  },
207
  "lastpickupdate",
208
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
202
);
209
);
203
210
204
=head1 PRIMARY KEY
211
=head1 PRIMARY KEY
(-)a/admin/smart-rules.pl (-4 / +5 lines)
Lines 101-108 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, renewalperiod, norenewalbefore, auto_renew, reservesallowed, issuelength, lengthunit, hardduedate, hardduedatecompare, fine, finedays, maxsuspensiondays, firstremind, chargeperiod,rentaldiscount, overduefinescap) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
104
    my $sth_insert = $dbh->prepare('INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, renewalperiod, norenewalbefore, auto_renew, reservesallowed, holdspickupwait, issuelength, lengthunit, hardduedate, hardduedatecompare, fine, finedays, maxsuspensiondays, firstremind, chargeperiod,rentaldiscount, overduefinescap) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
105
    my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, maxsuspensiondays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, renewalperiod=?, norenewalbefore=?, auto_renew=?, reservesallowed=?, issuelength=?, lengthunit = ?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?, overduefinescap=?  WHERE branchcode=? AND categorycode=? AND itemtype=?");
105
    my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, maxsuspensiondays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, renewalperiod=?, norenewalbefore=?, auto_renew=?, reservesallowed=?, holdspickupwait=?, issuelength=?, lengthunit = ?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?, 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
Lines 120-125 elsif ($op eq 'add') { Link Here
120
    $norenewalbefore = undef if $norenewalbefore eq '0' or $norenewalbefore =~ /^\s*$/;
120
    $norenewalbefore = undef if $norenewalbefore eq '0' or $norenewalbefore =~ /^\s*$/;
121
    my $auto_renew = $input->param('auto_renew') eq 'yes' ? 1 : 0;
121
    my $auto_renew = $input->param('auto_renew') eq 'yes' ? 1 : 0;
122
    my $reservesallowed  = $input->param('reservesallowed');
122
    my $reservesallowed  = $input->param('reservesallowed');
123
    my $holdspickupwait = $input->param('holdspickupwait');
123
    $maxissueqty =~ s/\s//g;
124
    $maxissueqty =~ s/\s//g;
124
    $maxissueqty = undef if $maxissueqty !~ /^\d+/;
125
    $maxissueqty = undef if $maxissueqty !~ /^\d+/;
125
    my $issuelength  = $input->param('issuelength');
126
    my $issuelength  = $input->param('issuelength');
Lines 134-142 elsif ($op eq 'add') { Link Here
134
    $sth_search->execute($br,$bor,$cat);
135
    $sth_search->execute($br,$bor,$cat);
135
    my $res = $sth_search->fetchrow_hashref();
136
    my $res = $sth_search->fetchrow_hashref();
136
    if ($res->{total}) {
137
    if ($res->{total}) {
137
        $sth_update->execute($fine, $finedays, $maxsuspensiondays, $firstremind, $chargeperiod, $maxissueqty, $renewalsallowed, $renewalperiod, $norenewalbefore, $auto_renew, $reservesallowed, $issuelength,$lengthunit, $hardduedate,$hardduedatecompare,$rentaldiscount,$overduefinescap, $br,$bor,$cat);
138
        $sth_update->execute($fine, $finedays, $maxsuspensiondays, $firstremind, $chargeperiod, $maxissueqty, $renewalsallowed, $renewalperiod, $norenewalbefore, $auto_renew, $reservesallowed, $holdspickupwait, $issuelength,$lengthunit, $hardduedate,$hardduedatecompare,$rentaldiscount,$overduefinescap,   $br,$bor,$cat);
138
    } else {
139
    } else {
139
        $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed, $renewalperiod, $norenewalbefore, $auto_renew, $reservesallowed,$issuelength,$lengthunit,$hardduedate,$hardduedatecompare,$fine,$finedays, $maxsuspensiondays, $firstremind,$chargeperiod,$rentaldiscount,$overduefinescap);
140
        $sth_insert->execute($br,$bor,$cat,   $maxissueqty, $renewalsallowed, $renewalperiod, $norenewalbefore, $auto_renew, $reservesallowed, $holdspickupwait, $issuelength, $lengthunit, $hardduedate, $hardduedatecompare, $fine, $finedays, $maxsuspensiondays, $firstremind, $chargeperiod, $rentaldiscount, $overduefinescap);
140
    }
141
    }
141
} 
142
} 
142
elsif ($op eq "set-branch-defaults") {
143
elsif ($op eq "set-branch-defaults") {
(-)a/circ/waitingreserves.pl (-31 / +25 lines)
Lines 27-43 use C4::Branch; # GetBranchName Link Here
27
use C4::Auth;
27
use C4::Auth;
28
use C4::Dates qw/format_date/;
28
use C4::Dates qw/format_date/;
29
use C4::Circulation;
29
use C4::Circulation;
30
use C4::Reserves;
30
use C4::Members;
31
use C4::Members;
31
use C4::Biblio;
32
use C4::Biblio;
32
use C4::Items;
33
use C4::Items;
33
34
34
use Date::Calc qw(
35
  Today
36
  Add_Delta_Days
37
  Date_to_Days
38
);
39
use C4::Reserves;
35
use C4::Reserves;
40
use C4::Koha;
36
use C4::Koha;
37
use Koha::DateUtils;
41
38
42
my $input = new CGI;
39
my $input = new CGI;
43
40
Lines 86-116 my ($reservcount, $overcount); Link Here
86
my @getreserves = $all_branches ? GetReservesForBranch() : GetReservesForBranch($default);
83
my @getreserves = $all_branches ? GetReservesForBranch() : GetReservesForBranch($default);
87
# get reserves for the branch we are logged into, or for all branches
84
# get reserves for the branch we are logged into, or for all branches
88
85
89
my $today = Date_to_Days(&Today);
86
my $today = dt_from_string;
90
foreach my $num (@getreserves) {
87
foreach my $num (@getreserves) {
91
    next unless ($num->{'waitingdate'} && $num->{'waitingdate'} ne '0000-00-00');
88
    next unless ($num->{'waitingdate'} && $num->{'waitingdate'} ne '0000-00-00');
92
89
93
    my $itemnumber = $num->{'itemnumber'};
90
    my $itemnumber = $num->{'itemnumber'};
94
    my $gettitle     = GetBiblioFromItemNumber( $itemnumber );
91
    my $gettitle     = GetBiblioFromItemNumber( $itemnumber );
95
    my $borrowernum = $num->{'borrowernumber'};
92
    my $borrowernumber = $num->{'borrowernumber'};
96
    my $holdingbranch = $gettitle->{'holdingbranch'};
93
    my $holdingbranch = $gettitle->{'holdingbranch'};
97
    my $homebranch = $gettitle->{'homebranch'};
94
    my $homebranch = $gettitle->{'homebranch'};
98
95
99
    my %getreserv = (
96
    my %getreserv = (
100
        itemnumber => $itemnumber,
97
        itemnumber => $itemnumber,
101
        borrowernum => $borrowernum,
98
        borrowernum => $borrowernumber,
102
    );
99
    );
103
100
104
    # fix up item type for display
101
    # fix up item type for display
105
    $gettitle->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $gettitle->{'itype'} : $gettitle->{'itemtype'};
102
    $gettitle->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $gettitle->{'itype'} : $gettitle->{'itemtype'};
106
    my $getborrower = GetMember(borrowernumber => $num->{'borrowernumber'});
103
    my $getborrower = GetMember(borrowernumber => $num->{'borrowernumber'});
107
    my $itemtypeinfo = getitemtypeinfo( $gettitle->{'itemtype'} );  # using the fixed up itype/itemtype
104
    my $itemtypeinfo = getitemtypeinfo( $gettitle->{'itemtype'} );  # using the fixed up itype/itemtype
108
    $getreserv{'waitingdate'} = $num->{'waitingdate'};
105
109
    my ( $waiting_year, $waiting_month, $waiting_day ) = split (/-/, $num->{'waitingdate'});
106
    if ( $num->{waitingdate} ) {
110
    ( $waiting_year, $waiting_month, $waiting_day ) =
107
        my $lastpickupdate = dt_from_string($num->{lastpickupdate});
111
      Add_Delta_Days( $waiting_year, $waiting_month, $waiting_day,
108
        $getreserv{waitingdate} = $num->{waitingdate};
112
        C4::Context->preference('ReservesMaxPickUpDelay'));
109
        $getreserv{lastpickupdate} = $num->{lastpickupdate};
113
    my $calcDate = Date_to_Days( $waiting_year, $waiting_month, $waiting_day );
110
        if ( DateTime->compare( $today, $lastpickupdate ) == 1 ) {
111
            if ($cancelall) {
112
                my $res = cancel( $itemnumber, $borrowernumber, $holdingbranch, $homebranch, !$transfer_when_cancel_all );
113
                push @cancel_result, $res if $res;
114
                next;
115
            } else {
116
                push @overloop,   \%getreserv;
117
                $overcount++;
118
            }
119
        }else{
120
            push @reservloop, \%getreserv;
121
            $reservcount++;
122
        }
123
    }
114
124
115
    $getreserv{'itemtype'}       = $itemtypeinfo->{'description'};
125
    $getreserv{'itemtype'}       = $itemtypeinfo->{'description'};
116
    $getreserv{'title'}          = $gettitle->{'title'};
126
    $getreserv{'title'}          = $gettitle->{'title'};
Lines 129-154 foreach my $num (@getreserves) { Link Here
129
    $getreserv{'borrowerfirstname'} = $getborrower->{'firstname'};
139
    $getreserv{'borrowerfirstname'} = $getborrower->{'firstname'};
130
    $getreserv{'borrowerphone'}     = $getborrower->{'phone'};
140
    $getreserv{'borrowerphone'}     = $getborrower->{'phone'};
131
141
132
    my $borEmail = GetFirstValidEmailAddress( $borrowernum );
142
    my $borEmail = GetFirstValidEmailAddress( $borrowernumber );
133
143
134
    if ( $borEmail ) {
144
    if ( $borEmail ) {
135
        $getreserv{'borrowermail'}  = $borEmail;
145
        $getreserv{'borrowermail'}  = $borEmail;
136
    }
146
    }
137
138
    if ($today > $calcDate) {
139
        if ($cancelall) {
140
            my $res = cancel( $itemnumber, $borrowernum, $holdingbranch, $homebranch, !$transfer_when_cancel_all );
141
            push @cancel_result, $res if $res;
142
            next;
143
        } else {
144
            push @overloop,   \%getreserv;
145
            $overcount++;
146
        }
147
    }else{
148
        push @reservloop, \%getreserv;
149
        $reservcount++;
150
    }
151
    
152
}
147
}
153
148
154
$template->param(cancel_result => \@cancel_result) if @cancel_result;
149
$template->param(cancel_result => \@cancel_result) if @cancel_result;
Lines 158-164 $template->param( Link Here
158
    overloop    => \@overloop,
153
    overloop    => \@overloop,
159
    overcount   => $overcount,
154
    overcount   => $overcount,
160
    show_date   => format_date(C4::Dates->today('iso')),
155
    show_date   => format_date(C4::Dates->today('iso')),
161
    ReservesMaxPickUpDelay => C4::Context->preference('ReservesMaxPickUpDelay')
162
);
156
);
163
157
164
if ($cancelall) {
158
if ($cancelall) {
(-)a/installer/data/mysql/kohastructure.sql (+3 lines)
Lines 1163-1168 CREATE TABLE `issuingrules` ( -- circulation and fine rules Link Here
1163
  `norenewalbefore` int(4) default NULL, -- no renewal allowed until X days or hours before due date. In the unit set in issuingrules.lengthunit
1163
  `norenewalbefore` int(4) default NULL, -- no renewal allowed until X days or hours before due date. In the unit set in issuingrules.lengthunit
1164
  `auto_renew` BOOLEAN default FALSE, -- automatic renewal
1164
  `auto_renew` BOOLEAN default FALSE, -- automatic renewal
1165
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
1165
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
1166
  `holdspickupwait` int(11)  default NULL, -- How many open library days a hold can wait in the pickup shelf until it becomes problematic
1166
  `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
1167
  `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
1167
  overduefinescap decimal(28,6) default NULL, -- the maximum amount of an overdue fine
1168
  overduefinescap decimal(28,6) default NULL, -- the maximum amount of an overdue fine
1168
  PRIMARY KEY  (`branchcode`,`categorycode`,`itemtype`),
1169
  PRIMARY KEY  (`branchcode`,`categorycode`,`itemtype`),
Lines 1634-1639 CREATE TABLE `old_reserves` ( -- this table holds all holds/reserves that have b Link Here
1634
  `lowestPriority` tinyint(1) NOT NULL, -- has this hold been pinned to the lowest priority in the holds queue (1 for yes, 0 for no)
1635
  `lowestPriority` tinyint(1) NOT NULL, -- has this hold been pinned to the lowest priority in the holds queue (1 for yes, 0 for no)
1635
  `suspend` BOOLEAN NOT NULL DEFAULT 0, -- in this hold suspended (1 for yes, 0 for no)
1636
  `suspend` BOOLEAN NOT NULL DEFAULT 0, -- in this hold suspended (1 for yes, 0 for no)
1636
  `suspend_until` DATETIME NULL DEFAULT NULL, -- the date this hold is suspended until (NULL for infinitely)
1637
  `suspend_until` DATETIME NULL DEFAULT NULL, -- the date this hold is suspended until (NULL for infinitely)
1638
  `lastpickupdate` date NULL DEFAULT NULL, -- the last day this hold is available for pickup, until it becomes problematic
1637
  PRIMARY KEY (`reserve_id`),
1639
  PRIMARY KEY (`reserve_id`),
1638
  KEY `old_reserves_borrowernumber` (`borrowernumber`),
1640
  KEY `old_reserves_borrowernumber` (`borrowernumber`),
1639
  KEY `old_reserves_biblionumber` (`biblionumber`),
1641
  KEY `old_reserves_biblionumber` (`biblionumber`),
Lines 1836-1841 CREATE TABLE `reserves` ( -- information related to holds/reserves in Koha Link Here
1836
  `lowestPriority` tinyint(1) NOT NULL,
1838
  `lowestPriority` tinyint(1) NOT NULL,
1837
  `suspend` BOOLEAN NOT NULL DEFAULT 0,
1839
  `suspend` BOOLEAN NOT NULL DEFAULT 0,
1838
  `suspend_until` DATETIME NULL DEFAULT NULL,
1840
  `suspend_until` DATETIME NULL DEFAULT NULL,
1841
  `lastpickupdate` date NULL DEFAULT NULL, -- the last day this hold is available for pickup, until it becomes problematic
1839
  PRIMARY KEY (`reserve_id`),
1842
  PRIMARY KEY (`reserve_id`),
1840
  KEY priorityfoundidx (priority,found),
1843
  KEY priorityfoundidx (priority,found),
1841
  KEY `borrowernumber` (`borrowernumber`),
1844
  KEY `borrowernumber` (`borrowernumber`),
(-)a/installer/data/mysql/updatedatabase.pl (+31 lines)
Lines 8838-8843 if ( CheckVersion($DBversion) ) { Link Here
8838
    SetVersion($DBversion);
8838
    SetVersion($DBversion);
8839
}
8839
}
8840
8840
8841
$DBversion = "3.17.00.XXX";
8842
if ( CheckVersion($DBversion) ) {
8843
    my $maxpickupdelay = C4::Context->preference('ReservesMaxPickUpDelay') || 0; #MaxPickupDelay
8844
    #$dbh->do(q{
8845
    #    DELETE FROM systempreferences WHERE variable='ReservesMaxPickUpDelay';
8846
    #    //DELETE FROM systempreferences WHERE variable='ExpireReservesMaxPickUpDelay'; #This syspref is not needed and would be better suited to be calculated from the holdspickupwait
8847
    #    //ExpireReservesMaxPickUpDelayCharge #This could be added as a column to the issuing rules.
8848
    #});
8849
    $dbh->do(qq{
8850
        ALTER TABLE issuingrules ADD COLUMN holdspickupwait INT(11) NULL default NULL AFTER reservesallowed;
8851
    });
8852
    my $sth = $dbh->prepare(q{
8853
        UPDATE issuingrules SET holdspickupwait = ?
8854
    });
8855
    $sth->execute( $maxpickupdelay );
8856
    $dbh->do(q{
8857
        ALTER TABLE reserves ADD COLUMN lastpickupdate DATE NULL default NULL AFTER suspend_until;
8858
    });
8859
    #$sth = $dbh->prepare(q{ #THIS NOT WORKY WORKY BECAUSE OF HOLIDAYS
8860
    #    UPDATE reserves SET lastpickupdate = ADDDATE(waitingdate, INTERVAL ? DAY);
8861
    #});
8862
    #$sth->execute( $maxpickupdelay );
8863
    #TODO Make a function to migrate this value from.
8864
    $dbh->do(q{
8865
        ALTER TABLE old_reserves ADD COLUMN lastpickupdate DATE NULL default NULL AFTER suspend_until;
8866
    });
8867
    print "Upgrade to $DBversion done (8367: Add colum issuingrules.holdspickupwait and reserves.lastpickupdate. Delete the ReservesMaxPickUpDelay syspref)\n";
8868
    SetVersion($DBversion);
8869
}
8870
8871
8841
=head1 FUNCTIONS
8872
=head1 FUNCTIONS
8842
8873
8843
=head2 TableExists($table)
8874
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/js/holds.js (+3 lines)
Lines 11-16 $(document).ready(function() { Link Here
11
                        "mDataProp": "reservedate_formatted"
11
                        "mDataProp": "reservedate_formatted"
12
                    },
12
                    },
13
                    {
13
                    {
14
                        "mDataProp": "lastpickupdate_formatted"
15
                    },
16
                    {
14
                        "mDataProp": function ( oObj ) {
17
                        "mDataProp": function ( oObj ) {
15
                            title = "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber="
18
                            title = "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber="
16
                                  + oObj.biblionumber
19
                                  + oObj.biblionumber
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (-6 / +1 lines)
Lines 427-442 Circulation: Link Here
427
                  PatronLibrary: "patron's home library"
427
                  PatronLibrary: "patron's home library"
428
            - to see if the patron can place a hold on the item.    
428
            - to see if the patron can place a hold on the item.    
429
        -
429
        -
430
            - Mark a hold as problematic if it has been waiting for more than
431
            - pref: ReservesMaxPickUpDelay
432
              class: integer
433
            - days.
434
        -
435
            - pref: ExpireReservesMaxPickUpDelay
430
            - pref: ExpireReservesMaxPickUpDelay
436
              choices:
431
              choices:
437
                  yes: Allow
432
                  yes: Allow
438
                  no: "Don't allow"
433
                  no: "Don't allow"
439
            - "holds to expire automatically if they have not been picked by within the time period specified in ReservesMaxPickUpDelay"
434
            - "holds to expire automatically if they have not been picked by within the time period specified in hold pickup delay defined in the issuing rules"
440
        -
435
        -
441
            - If using ExpireReservesMaxPickUpDelay, charge a borrower who allows his or her waiting hold to expire a fee of
436
            - If using ExpireReservesMaxPickUpDelay, charge a borrower who allows his or her waiting hold to expire a fee of
442
            - pref: ExpireReservesMaxPickUpDelayCharge
437
            - pref: ExpireReservesMaxPickUpDelayCharge
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt (+4 lines)
Lines 117-122 $(document).ready(function() { Link Here
117
            <li>default (all libraries), all patron types, same item type</li>
117
            <li>default (all libraries), all patron types, same item type</li>
118
            <li>default (all libraries), all patron types, all item types</li>
118
            <li>default (all libraries), all patron types, all item types</li>
119
        </ul>
119
        </ul>
120
        <p>To get more information about how these settings affect Koha, hover your cursor over a column header.</p>
120
        <p>To modify a rule, create a new one with the same patron type and item type.</p>
121
        <p>To modify a rule, create a new one with the same patron type and item type.</p>
121
    </div>
122
    </div>
122
    <div>
123
    <div>
Lines 153-158 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
153
                <th>Max. suspension duration (day)</th>
154
                <th>Max. suspension duration (day)</th>
154
                <th>Renewals allowed (count)</th>
155
                <th>Renewals allowed (count)</th>
155
                <th>Renewal period</th>
156
                <th>Renewal period</th>
157
                <th>Holds wait for pickup (day)</th>
156
                <th>No renewal before</th>
158
                <th>No renewal before</th>
157
                <th>Automatic renewal</th>
159
                <th>Automatic renewal</th>
158
                <th>Holds allowed (count)</th>
160
                <th>Holds allowed (count)</th>
Lines 209-214 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
209
                            <td>[% rule.maxsuspensiondays %]</td>
211
                            <td>[% rule.maxsuspensiondays %]</td>
210
							<td>[% rule.renewalsallowed %]</td>
212
							<td>[% rule.renewalsallowed %]</td>
211
                            <td>[% rule.renewalperiod %]</td>
213
                            <td>[% rule.renewalperiod %]</td>
214
                            <td>[% rule.holdspickupwait %]</td>
212
                            <td>[% rule.norenewalbefore %]</td>
215
                            <td>[% rule.norenewalbefore %]</td>
213
                            <td>
216
                            <td>
214
                                [% IF ( rule.auto_renew ) %]
217
                                [% IF ( rule.auto_renew ) %]
Lines 267-272 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
267
                    <td><input type="text" name="maxsuspensiondays" id="maxsuspensiondays" size="3" /> </td>
270
                    <td><input type="text" name="maxsuspensiondays" id="maxsuspensiondays" size="3" /> </td>
268
                    <td><input type="text" name="renewalsallowed" id="renewalsallowed" size="2" /></td>
271
                    <td><input type="text" name="renewalsallowed" id="renewalsallowed" size="2" /></td>
269
                    <td><input type="text" name="renewalperiod" id="renewalperiod" size="3" /></td>
272
                    <td><input type="text" name="renewalperiod" id="renewalperiod" size="3" /></td>
273
                    <td><input type="text" name="holdspickupwait" id="holdspickupwait" size="2" /></td>
270
                    <td><input type="text" name="norenewalbefore" id="norenewalbefore" size="3" /></td>
274
                    <td><input type="text" name="norenewalbefore" id="norenewalbefore" size="3" /></td>
271
                    <td>
275
                    <td>
272
                        <select name="auto_renew" id="auto_renew">
276
                        <select name="auto_renew" id="auto_renew">
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+1 lines)
Lines 776-781 No patron matched <span class="ex">[% message %]</span> Link Here
776
            <thead>
776
            <thead>
777
                <tr>
777
                <tr>
778
                    <th>Hold date</th>
778
                    <th>Hold date</th>
779
                    <th>Last pickup date</th>
779
                    <th>Title</th>
780
                    <th>Title</th>
780
                    <th>Call number</th>
781
                    <th>Call number</th>
781
                    <th>Barcode</th>
782
                    <th>Barcode</th>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt (-4 / +4 lines)
Lines 77-83 Link Here
77
            [% IF ( reserveloop ) %]
77
            [% IF ( reserveloop ) %]
78
               <table id="holdst">
78
               <table id="holdst">
79
               <thead><tr>
79
               <thead><tr>
80
                    <th class="title-string">Available since</th>
80
                    <th class="title-string">Available since-until</th>
81
                    <th class="anti-the">Title</th>
81
                    <th class="anti-the">Title</th>
82
                    <th>Patron</th>
82
                    <th>Patron</th>
83
                    <th>Location</th>
83
                    <th>Location</th>
Lines 87-93 Link Here
87
               </tr></thead>
87
               </tr></thead>
88
               <tbody>[% FOREACH reserveloo IN reserveloop %]
88
               <tbody>[% FOREACH reserveloo IN reserveloop %]
89
                <tr>
89
                <tr>
90
                    <td><span title="[% reserveloo.waitingdate %]">[% reserveloo.waitingdate | $KohaDates %]</span></td>
90
                    <td><span title="[% reserveloo.waitingdate %]">[% reserveloo.waitingdate | $KohaDates %] - [% reserveloo.lastpickupdate | $KohaDates %]</span></td>
91
                    <td>[% INCLUDE 'biblio-default-view.inc' biblionumber = reserveloo.biblionumber %]
91
                    <td>[% INCLUDE 'biblio-default-view.inc' biblionumber = reserveloo.biblionumber %]
92
                        [% reserveloo.title |html %] [% reserveloo.subtitle |html %]
92
                        [% reserveloo.title |html %] [% reserveloo.subtitle |html %]
93
                        </a>
93
                        </a>
Lines 137-143 Link Here
137
               <br/>
137
               <br/>
138
               <table id="holdso">
138
               <table id="holdso">
139
               <thead><tr>
139
               <thead><tr>
140
                    <th class="title-string">Available since</th>
140
                    <th class="title-string">Available since-until</th>
141
                    <th class="anti-the">Title</th>
141
                    <th class="anti-the">Title</th>
142
                    <th>Patron</th>
142
                    <th>Patron</th>
143
                    <th>Location</th>
143
                    <th>Location</th>
Lines 147-153 Link Here
147
               </tr></thead>
147
               </tr></thead>
148
               <tbody>[% FOREACH overloo IN overloop %]
148
               <tbody>[% FOREACH overloo IN overloop %]
149
                    <tr>
149
                    <tr>
150
                        <td><p><span title="[% overloo.waitingdate %]">[% overloo.waitingdate | $KohaDates %]</span></p></td>
150
                        <td><p><span title="[% overloo.waitingdate %]">[% overloo.waitingdate | $KohaDates %] - [% overloo.lastpickupdate | $KohaDates %]</span></p></td>
151
                        <td>[% INCLUDE 'biblio-default-view.inc' biblionumber = overloo.biblionumber %][% overloo.title |html %] [% overloo.subtitle |html %]
151
                        <td>[% INCLUDE 'biblio-default-view.inc' biblionumber = overloo.biblionumber %][% overloo.title |html %] [% overloo.subtitle |html %]
152
                        </a>
152
                        </a>
153
                            [% UNLESS ( item_level_itypes ) %][% IF ( overloo.itemtype ) %]&nbsp; (<b>[% overloo.itemtype %]</b>)[% END %][% END %]
153
                            [% UNLESS ( item_level_itypes ) %][% IF ( overloo.itemtype ) %]&nbsp; (<b>[% overloo.itemtype %]</b>)[% END %][% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/smart-rules.tt (+1 lines)
Lines 57-62 Link Here
57
</li>
57
</li>
58
    <li>Next decide if the patron can renew this item type and if so, enter how many times they can renew it in the 'Renewals Allowed' box</li>
58
    <li>Next decide if the patron can renew this item type and if so, enter how many times they can renew it in the 'Renewals Allowed' box</li>
59
    <li>If you're allowing renewals you can control how long the renewal loan period will be (in the units you have chosen) in the 'Renewal period' box</li>
59
    <li>If you're allowing renewals you can control how long the renewal loan period will be (in the units you have chosen) in the 'Renewal period' box</li>
60
    <li><i>Holds wait for pickup (day)</i> - After a hold is caught and put waiting for pickup, the hold will wait for this many days until it becomes problematic. Set it to 0 or less to disable the expiration of waiting holds. This value respects the Calendar holidays, skipping the last pickup date to the next available open library day.</li>
60
    <li>If you're allowing renewals you can control how soon before the due date patrons can renew their materials with the 'No renewals before' box.
61
    <li>If you're allowing renewals you can control how soon before the due date patrons can renew their materials with the 'No renewals before' box.
61
    <ul><li>Items can be renewed at any time if this value is left blank. Otherwise items can only be renewed if the item is before the number in units (days/hours) entered in this box.</li></ul></li>
62
    <ul><li>Items can be renewed at any time if this value is left blank. Otherwise items can only be renewed if the item is before the number in units (days/hours) entered in this box.</li></ul></li>
62
    <li>If the patron can place holds on this item type, enter the total numbers of items (of this type) that can be put on hold in the 'Holds Allowed' field</li>
63
    <li>If the patron can place holds on this item type, enter the total numbers of items (of this type) that can be put on hold in the 'Holds Allowed' field</li>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/help/circ/waitingreserves.tt (-1 / +1 lines)
Lines 4-10 Link Here
4
4
5
<p>This report will show all of the holds that are waiting for patrons to pick them up.</p>
5
<p>This report will show all of the holds that are waiting for patrons to pick them up.</p>
6
6
7
<p>Items that have been on the hold shelf longer than you normally allow (based on the ReservesMaxPickUpDelay preference value) will appear on the 'Holds Over' tab, they will not automatically be cancelled unless you have set the cron job to do that for you, but you can cancel all holds using the button at the top of the list.</p>
7
<p>Items that have been on the hold shelf longer than you normally allow (based on the holds pickup delay defined in the issuing rules) will appear on the 'Holds Over' tab, they will not automatically be cancelled.</p>
8
8
9
<p><strong>See the full documentation for Holds Awaiting Pickup in the <a href="http://manual.koha-community.org/[% helpVersion %]/en/circreports.html#holdspickup">manual</a> (online).</strong></p>
9
<p><strong>See the full documentation for Holds Awaiting Pickup in the <a href="http://manual.koha-community.org/[% helpVersion %]/en/circreports.html#holdspickup">manual</a> (online).</strong></p>
10
10
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt (+1 lines)
Lines 522-527 function validate1(date) { Link Here
522
            <thead>
522
            <thead>
523
                <tr>
523
                <tr>
524
                    <th>Hold date</th>
524
                    <th>Hold date</th>
525
                    <th>Last pickup date</th>
525
                    <th>Title</th>
526
                    <th>Title</th>
526
                    <th>Call number</th>
527
                    <th>Call number</th>
527
                    <th>Barcode</th>
528
                    <th>Barcode</th>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt (-1 / +1 lines)
Lines 560-566 Link Here
560
                                                [% IF ( RESERVE.wait ) %]
560
                                                [% IF ( RESERVE.wait ) %]
561
                                                    [% IF ( RESERVE.atdestination ) %]
561
                                                    [% IF ( RESERVE.atdestination ) %]
562
                                                        [% IF ( RESERVE.found ) %]
562
                                                        [% IF ( RESERVE.found ) %]
563
                                                            Item waiting at <b> [% RESERVE.wbrname %]</b>[% IF ( RESERVE.waitingdate ) %] since [% RESERVE.waitingdate | $KohaDates %][% END %]
563
                                                            Item waiting at <b> [% RESERVE.wbrname %]</b>[% IF ( RESERVE.waitingdate ) %] since [% RESERVE.waitingdate | $KohaDates %] until [% RESERVE.lastpickupdate | $KohaDates %][% END %]
564
                                                            <input type="hidden" name="pickup" value="[% RESERVE.wbrcd %]" />
564
                                                            <input type="hidden" name="pickup" value="[% RESERVE.wbrcd %]" />
565
                                                        [% ELSE %]
565
                                                        [% ELSE %]
566
                                                            Item waiting to be pulled from <b> [% RESERVE.wbrname %]</b>
566
                                                            Item waiting to be pulled from <b> [% RESERVE.wbrname %]</b>
(-)a/svc/holds (-2 / +6 lines)
Lines 47-53 my $branch = C4::Context->userenv->{'branch'}; Link Here
47
my $schema = Koha::Database->new()->schema();
47
my $schema = Koha::Database->new()->schema();
48
48
49
my @sort_columns =
49
my @sort_columns =
50
  qw/reservedate title itemcallnumber barcode expirationdate priority/;
50
  qw/reservedate lastpickupdate title itemcallnumber barcode expirationdate priority/;
51
51
52
my $borrowernumber    = $input->param('borrowernumber');
52
my $borrowernumber    = $input->param('borrowernumber');
53
my $offset            = $input->param('iDisplayStart');
53
my $offset            = $input->param('iDisplayStart');
Lines 81-86 while ( my $h = $holds_rs->next() ) { Link Here
81
        author         => $h->biblio()->author(),
81
        author         => $h->biblio()->author(),
82
        reserve_id     => $h->reserve_id(),
82
        reserve_id     => $h->reserve_id(),
83
        reservedate    => $h->reservedate(),
83
        reservedate    => $h->reservedate(),
84
        lastpickupdate => $h->lastpickupdate(),
84
        expirationdate => $h->expirationdate(),
85
        expirationdate => $h->expirationdate(),
85
        suspend        => $h->suspend(),
86
        suspend        => $h->suspend(),
86
        suspend_until  => $h->suspend_until(),
87
        suspend_until  => $h->suspend_until(),
Lines 97-102 while ( my $h = $holds_rs->next() ) { Link Here
97
            { dt => dt_from_string( $h->reservedate() ), dateonly => 1 }
98
            { dt => dt_from_string( $h->reservedate() ), dateonly => 1 }
98
          )
99
          )
99
        : q{},
100
        : q{},
101
        lastpickupdate_formatted => $h->lastpickupdate() ? output_pref(
102
            { dt => dt_from_string( $h->lastpickupdate() ), dateonly => 1 }
103
          )
104
        : q{},
100
        suspend_until_formatted => $h->suspend_until() ? output_pref(
105
        suspend_until_formatted => $h->suspend_until() ? output_pref(
101
            { dt => dt_from_string( $h->suspend_until() ), dateonly => 1 }
106
            { dt => dt_from_string( $h->suspend_until() ), dateonly => 1 }
102
          )
107
          )
103
- 

Return to bug 8367