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

(-)a/C4/Circulation.pm (-20 / +35 lines)
Lines 2985-3003 sub CanBookBeRenewed { Link Here
2985
        return ( 0, 'overdue');
2985
        return ( 0, 'overdue');
2986
    }
2986
    }
2987
2987
2988
    if ( $itemissue->{auto_renew}
2988
    if ( $itemissue->{auto_renew} ) {
2989
        and defined $issuingrule->{no_auto_renewal_after}
2989
        if ( defined $issuingrule->{no_auto_renewal_after}
2990
                and $issuingrule->{no_auto_renewal_after} ne "" ) {
2990
                and $issuingrule->{no_auto_renewal_after} ne "" ) {
2991
2991
            # Get issue_date and add no_auto_renewal_after
2992
        # Get issue_date and add no_auto_renewal_after
2992
            # If this is greater than today, it's too late for renewal.
2993
        # If this is greater than today, it's too late for renewal.
2993
            my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2994
        my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2994
            $maximum_renewal_date->add(
2995
        $maximum_renewal_date->add(
2995
                $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after}
2996
            $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after}
2996
            );
2997
        );
2997
            my $now = dt_from_string;
2998
        my $now = dt_from_string;
2998
            if ( $now >= $maximum_renewal_date ) {
2999
        if ( $now >= $maximum_renewal_date ) {
2999
                return ( 0, "auto_too_late" );
3000
            return ( 0, "auto_too_late" );
3000
            }
3001
        }
3002
        if ( defined $issuingrule->{no_auto_renewal_after_hard_limit}
3003
                      and $issuingrule->{no_auto_renewal_after_hard_limit} ne "" ) {
3004
            # If no_auto_renewal_after_hard_limit is >= today, it's also too late for renewal
3005
            if ( dt_from_string >= dt_from_string( $issuingrule->{no_auto_renewal_after_hard_limit} ) ) {
3006
                return ( 0, "auto_too_late" );
3007
            }
3001
        }
3008
        }
3002
    }
3009
    }
3003
3010
Lines 3280-3287 has the item on loan. Link Here
3280
C<$itemnumber> is the number of the item to renew.
3287
C<$itemnumber> is the number of the item to renew.
3281
3288
3282
C<$GetLatestAutoRenewDate> returns the DateTime of the latest possible
3289
C<$GetLatestAutoRenewDate> returns the DateTime of the latest possible
3283
auto renew date, based on the value "No auto renewal after" of the applicable
3290
auto renew date, based on the value "No auto renewal after" and the "No auto
3284
issuing rule.
3291
renewal after (hard limit) of the applicable issuing rule.
3285
Returns undef if there is no date specify in the circ rules or if the patron, loan,
3292
Returns undef if there is no date specify in the circ rules or if the patron, loan,
3286
or item cannot be found.
3293
or item cannot be found.
3287
3294
Lines 3305-3318 sub GetLatestAutoRenewDate { Link Here
3305
3312
3306
    my $now = dt_from_string;
3313
    my $now = dt_from_string;
3307
3314
3308
    return if not $issuingrule->{no_auto_renewal_after}
3315
    return if ( not $issuingrule->{no_auto_renewal_after} or $issuingrule->{no_auto_renewal_after} eq '' )
3309
               or $issuingrule->{no_auto_renewal_after} eq '';
3316
        and   ( not $issuingrule->{no_auto_renewal_after_hard_limit} or $issuingrule->{no_auto_renewal_after_hard_limit} eq '' );
3310
3317
3311
    my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
3312
    $maximum_renewal_date->add(
3313
        $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after}
3314
    );
3315
3318
3319
    my $maximum_renewal_date;
3320
    if ( $issuingrule->{no_auto_renewal_after} ) {
3321
        $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
3322
        $maximum_renewal_date->add(
3323
            $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after}
3324
        );
3325
    }
3326
3327
    if ( $issuingrule->{no_auto_renewal_after_hard_limit} ) {
3328
        my $dt = dt_from_string( $issuingrule->{no_auto_renewal_after_hard_limit} );
3329
        $maximum_renewal_date = $dt if not $maximum_renewal_date or $maximum_renewal_date > $dt;
3330
    }
3316
    return $maximum_renewal_date;
3331
    return $maximum_renewal_date;
3317
}
3332
}
3318
3333
(-)a/admin/smart-rules.pl (+9 lines)
Lines 138-143 elsif ($op eq 'add') { Link Here
138
    my $auto_renew = $input->param('auto_renew') eq 'yes' ? 1 : 0;
138
    my $auto_renew = $input->param('auto_renew') eq 'yes' ? 1 : 0;
139
    my $no_auto_renewal_after = $input->param('no_auto_renewal_after');
139
    my $no_auto_renewal_after = $input->param('no_auto_renewal_after');
140
    $no_auto_renewal_after = undef if $no_auto_renewal_after =~ /^\s*$/;
140
    $no_auto_renewal_after = undef if $no_auto_renewal_after =~ /^\s*$/;
141
    my $no_auto_renewal_after_hard_limit = $input->param('no_auto_renewal_after_hard_limit') || undef;
142
    $no_auto_renewal_after_hard_limit = eval { dt_from_string( $input->param('no_auto_renewal_after_hard_limit') ) } if ( $no_auto_renewal_after_hard_limit );
143
    $no_auto_renewal_after_hard_limit = output_pref( { dt => $no_auto_renewal_after_hard_limit, dateonly => 1, dateformat => 'iso' } ) if ( $no_auto_renewal_after_hard_limit );
141
    my $reservesallowed  = $input->param('reservesallowed');
144
    my $reservesallowed  = $input->param('reservesallowed');
142
    my $onshelfholds     = $input->param('onshelfholds') || 0;
145
    my $onshelfholds     = $input->param('onshelfholds') || 0;
143
    $maxissueqty =~ s/\s//g;
146
    $maxissueqty =~ s/\s//g;
Lines 174-179 elsif ($op eq 'add') { Link Here
174
        norenewalbefore               => $norenewalbefore,
177
        norenewalbefore               => $norenewalbefore,
175
        auto_renew                    => $auto_renew,
178
        auto_renew                    => $auto_renew,
176
        no_auto_renewal_after         => $no_auto_renewal_after,
179
        no_auto_renewal_after         => $no_auto_renewal_after,
180
        no_auto_renewal_after_hard_limit => $no_auto_renewal_after_hard_limit,
177
        reservesallowed               => $reservesallowed,
181
        reservesallowed               => $reservesallowed,
178
        issuelength                   => $issuelength,
182
        issuelength                   => $issuelength,
179
        lengthunit                    => $lengthunit,
183
        lengthunit                    => $lengthunit,
Lines 516-521 while (my $row = $sth2->fetchrow_hashref) { Link Here
516
    } else {
520
    } else {
517
       $row->{'hardduedate'} = 0;
521
       $row->{'hardduedate'} = 0;
518
    }
522
    }
523
    if ($row->{no_auto_renewal_after_hard_limit}) {
524
       my $dt = eval { dt_from_string( $row->{no_auto_renewal_after_hard_limit} ) };
525
       $row->{no_auto_renewal_after_hard_limit} = eval { output_pref( { dt => $dt, dateonly => 1 } ) } if $dt;
526
    }
527
519
    push @row_loop, $row;
528
    push @row_loop, $row;
520
}
529
}
521
$sth->finish;
530
$sth->finish;
(-)a/installer/data/mysql/atomicupdate/bug_16344.sql (+1 lines)
Line 0 Link Here
1
ALTER TABLE issuingrules ADD COLUMN no_auto_renewal_after_hard_limit DATE DEFAULT NULL AFTER no_auto_renewal_after;
(-)a/installer/data/mysql/kohastructure.sql (+1 lines)
Lines 859-864 CREATE TABLE `issuingrules` ( -- circulation and fine rules Link Here
859
  `norenewalbefore` int(4) default NULL, -- no renewal allowed until X days or hours before due date.
859
  `norenewalbefore` int(4) default NULL, -- no renewal allowed until X days or hours before due date.
860
  `auto_renew` BOOLEAN default FALSE, -- automatic renewal
860
  `auto_renew` BOOLEAN default FALSE, -- automatic renewal
861
  `no_auto_renewal_after` int(4) default NULL, -- no auto renewal allowed after X days or hours after the issue date
861
  `no_auto_renewal_after` int(4) default NULL, -- no auto renewal allowed after X days or hours after the issue date
862
  `no_auto_renewal_after_hard_limit` date default NULL, -- no auto renewal allowed after a given date
862
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
863
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
863
  `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
864
  `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
864
  overduefinescap decimal(28,6) default NULL, -- the maximum amount of an overdue fine
865
  overduefinescap decimal(28,6) default NULL, -- the maximum amount of an overdue fine
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt (+6 lines)
Lines 177-182 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
177
                <th>No renewal before</th>
177
                <th>No renewal before</th>
178
                <th>Automatic renewal</th>
178
                <th>Automatic renewal</th>
179
                <th>No automatic renewal after</th>
179
                <th>No automatic renewal after</th>
180
                <th>No automatic renewal after (hard limit)</th>
180
                <th>Holds allowed (count)</th>
181
                <th>Holds allowed (count)</th>
181
                <th>On shelf holds allowed</th>
182
                <th>On shelf holds allowed</th>
182
                <th>Item level holds</th>
183
                <th>Item level holds</th>
Lines 256-261 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
256
                                [% END %]
257
                                [% END %]
257
                            </td>
258
                            </td>
258
                            <td>[% rule.no_auto_renewal_after %]</td>
259
                            <td>[% rule.no_auto_renewal_after %]</td>
260
                            <td>[% rule.no_auto_renewal_after_hard_limit %]</td>
259
							<td>[% rule.reservesallowed %]</td>
261
							<td>[% rule.reservesallowed %]</td>
260
                                                        <td>
262
                                                        <td>
261
                                                            [% IF rule.onshelfholds == 1 %]
263
                                                            [% IF rule.onshelfholds == 1 %]
Lines 331-336 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
331
                        </select>
333
                        </select>
332
                    </td>
334
                    </td>
333
                    <td><input type="text" name="no_auto_renewal_after" id="no_auto_renewal_after" size="3" /></td>
335
                    <td><input type="text" name="no_auto_renewal_after" id="no_auto_renewal_after" size="3" /></td>
336
                    <td>
337
                        <input type="text" size="10" name="no_auto_renewal_after_hard_limit" id="no_auto_renewal_after_hard_limit" value="[% no_auto_renewal_after_hard_limit %]" class="datepicker"/>
338
                        <div class="hint">[% INCLUDE 'date-format.inc' %]</div>
339
                    </td>
334
                    <td><input type="text" name="reservesallowed" id="reservesallowed" size="2" /></td>
340
                    <td><input type="text" name="reservesallowed" id="reservesallowed" size="2" /></td>
335
                    <td>
341
                    <td>
336
                        <select name="onshelfholds" id="onshelfholds">
342
                        <select name="onshelfholds" id="onshelfholds">
(-)a/t/db_dependent/Circulation.t (-7 / +38 lines)
Lines 533-539 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
533
    );
533
    );
534
534
535
    subtest "too_late_renewal / no_auto_renewal_after" => sub {
535
    subtest "too_late_renewal / no_auto_renewal_after" => sub {
536
        plan tests => 8;
536
        plan tests => 14;
537
        my $item_to_auto_renew = $builder->build(
537
        my $item_to_auto_renew = $builder->build(
538
            {   source => 'Item',
538
            {   source => 'Item',
539
                value  => {
539
                value  => {
Lines 571-580 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
571
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
571
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
572
        is( $renewokay, 0,            'Do not renew, renewal is automatic' );
572
        is( $renewokay, 0,            'Do not renew, renewal is automatic' );
573
        is( $error,     'auto_renew', 'Cannot renew, renew is automatic' );
573
        is( $error,     'auto_renew', 'Cannot renew, renew is automatic' );
574
575
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = NULL, no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => -1 ) );
576
        ( $renewokay, $error ) =
577
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
578
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
579
        is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' );
580
581
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = 15, no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => -1 ) );
582
        ( $renewokay, $error ) =
583
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
584
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
585
        is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' );
586
587
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = NULL, no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => 1 ) );
588
        ( $renewokay, $error ) =
589
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
590
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
591
        is( $error, 'auto_renew', 'Cannot renew, renew is automatic' );
574
    };
592
    };
575
593
576
    subtest "GetLatestAutoRenewDate" => sub {
594
    subtest "GetLatestAutoRenewDate" => sub {
577
        plan tests => 3;
595
        plan tests => 5;
578
        my $item_to_auto_renew = $builder->build(
596
        my $item_to_auto_renew = $builder->build(
579
            {   source => 'Item',
597
            {   source => 'Item',
580
                value  => {
598
                value  => {
Lines 588-610 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
588
        my $ten_days_before = dt_from_string->add( days => -10 );
606
        my $ten_days_before = dt_from_string->add( days => -10 );
589
        my $ten_days_ahead  = dt_from_string->add( days => 10 );
607
        my $ten_days_ahead  = dt_from_string->add( days => 10 );
590
        AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } );
608
        AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } );
591
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = ""');
609
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = "", no_auto_renewal_after_hard_limit = NULL');
592
        my $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
610
        my $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
593
        is( $latest_auto_renew_date, undef, 'GetLatestAutoRenewDate should return undef if no_auto_renewal_after is not defined' );
611
        is( $latest_auto_renew_date, undef, 'GetLatestAutoRenewDate should return undef if no_auto_renewal_after or no_auto_renewal_after_hard_limit are not defined' );
594
        my $five_days_before = dt_from_string->add( days => -5 );
612
        my $five_days_before = dt_from_string->add( days => -5 );
595
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 5');
613
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 5, no_auto_renewal_after_hard_limit = NULL');
596
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
614
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
597
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
615
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
598
            $five_days_before->truncate( to => 'minute' ),
616
            $five_days_before->truncate( to => 'minute' ),
599
            'GetLatestAutoRenewDate should return -5 days if no_auto_renewal_after = 5 and date_due is 10 days before'
617
            'GetLatestAutoRenewDate should return -5 days if no_auto_renewal_after = 5 and date_due is 10 days before'
600
        );
618
        );
601
        my $five_days_ahead = dt_from_string->add( days => 5 );
619
        my $five_days_ahead = dt_from_string->add( days => 5 );
602
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 15');
620
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 15, no_auto_renewal_after_hard_limit = NULL');
603
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
621
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
604
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
622
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
605
            $five_days_ahead->truncate( to => 'minute' ),
623
            $five_days_ahead->truncate( to => 'minute' ),
606
            'GetLatestAutoRenewDate should return +5 days if no_auto_renewal_after = 15 and date_due is 10 days before'
624
            'GetLatestAutoRenewDate should return +5 days if no_auto_renewal_after = 15 and date_due is 10 days before'
607
        );
625
        );
626
        my $two_days_ahead = dt_from_string->add( days => 2 );
627
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = "", no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => 2 ) );
628
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
629
        is( $latest_auto_renew_date->truncate( to => 'day' ),
630
            $two_days_ahead->truncate( to => 'day' ),
631
            'GetLatestAutoRenewDate should return +2 days if no_auto_renewal_after_hard_limit is defined and not no_auto_renewal_after'
632
        );
633
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 15, no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => 2 ) );
634
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
635
        is( $latest_auto_renew_date->truncate( to => 'day' ),
636
            $two_days_ahead->truncate( to => 'day' ),
637
            'GetLatestAutoRenewDate should return +2 days if no_auto_renewal_after_hard_limit is < no_auto_renewal_after'
638
        );
639
608
    };
640
    };
609
641
610
    # Too many renewals
642
    # Too many renewals
611
- 

Return to bug 16344