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

(-)a/C4/Circulation.pm (-20 / +35 lines)
Lines 2853-2871 sub CanBookBeRenewed { Link Here
2853
        return ( 0, 'overdue');
2853
        return ( 0, 'overdue');
2854
    }
2854
    }
2855
2855
2856
    if ( $itemissue->{auto_renew}
2856
    if ( $itemissue->{auto_renew} ) {
2857
        and defined $issuingrule->{no_auto_renewal_after}
2857
        if ( defined $issuingrule->{no_auto_renewal_after}
2858
                and $issuingrule->{no_auto_renewal_after} ne "" ) {
2858
                and $issuingrule->{no_auto_renewal_after} ne "" ) {
2859
2859
            # Get issue_date and add no_auto_renewal_after
2860
        # Get issue_date and add no_auto_renewal_after
2860
            # If this is greater than today, it's too late for renewal.
2861
        # If this is greater than today, it's too late for renewal.
2861
            my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2862
        my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2862
            $maximum_renewal_date->add(
2863
        $maximum_renewal_date->add(
2863
                $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after}
2864
            $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after}
2864
            );
2865
        );
2865
            my $now = dt_from_string;
2866
        my $now = dt_from_string;
2866
            if ( $now >= $maximum_renewal_date ) {
2867
        if ( $now >= $maximum_renewal_date ) {
2867
                return ( 0, "auto_too_late" );
2868
            return ( 0, "auto_too_late" );
2868
            }
2869
        }
2870
        if ( defined $issuingrule->{no_auto_renewal_after_hard_limit}
2871
                      and $issuingrule->{no_auto_renewal_after_hard_limit} ne "" ) {
2872
            # If no_auto_renewal_after_hard_limit is >= today, it's also too late for renewal
2873
            if ( dt_from_string >= dt_from_string( $issuingrule->{no_auto_renewal_after_hard_limit} ) ) {
2874
                return ( 0, "auto_too_late" );
2875
            }
2869
        }
2876
        }
2870
    }
2877
    }
2871
2878
Lines 3153-3160 has the item on loan. Link Here
3153
C<$itemnumber> is the number of the item to renew.
3160
C<$itemnumber> is the number of the item to renew.
3154
3161
3155
C<$GetLatestAutoRenewDate> returns the DateTime of the latest possible
3162
C<$GetLatestAutoRenewDate> returns the DateTime of the latest possible
3156
auto renew date, based on the value "No auto renewal after" of the applicable
3163
auto renew date, based on the value "No auto renewal after" and the "No auto
3157
issuing rule.
3164
renewal after (hard limit) of the applicable issuing rule.
3158
Returns undef if there is no date specify in the circ rules or if the patron, loan,
3165
Returns undef if there is no date specify in the circ rules or if the patron, loan,
3159
or item cannot be found.
3166
or item cannot be found.
3160
3167
Lines 3178-3191 sub GetLatestAutoRenewDate { Link Here
3178
3185
3179
    my $now = dt_from_string;
3186
    my $now = dt_from_string;
3180
3187
3181
    return if not $issuingrule->{no_auto_renewal_after}
3188
    return if ( not $issuingrule->{no_auto_renewal_after} or $issuingrule->{no_auto_renewal_after} eq '' )
3182
               or $issuingrule->{no_auto_renewal_after} eq '';
3189
        and   ( not $issuingrule->{no_auto_renewal_after_hard_limit} or $issuingrule->{no_auto_renewal_after_hard_limit} eq '' );
3183
3190
3184
    my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
3185
    $maximum_renewal_date->add(
3186
        $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after}
3187
    );
3188
3191
3192
    my $maximum_renewal_date;
3193
    if ( $issuingrule->{no_auto_renewal_after} ) {
3194
        $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
3195
        $maximum_renewal_date->add(
3196
            $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after}
3197
        );
3198
    }
3199
3200
    if ( $issuingrule->{no_auto_renewal_after_hard_limit} ) {
3201
        my $dt = dt_from_string( $issuingrule->{no_auto_renewal_after_hard_limit} );
3202
        $maximum_renewal_date = $dt if not $maximum_renewal_date or $maximum_renewal_date > $dt;
3203
    }
3189
    return $maximum_renewal_date;
3204
    return $maximum_renewal_date;
3190
}
3205
}
3191
3206
(-)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 $holds_per_record  = $input->param('holds_per_record');
145
    my $holds_per_record  = $input->param('holds_per_record');
143
    my $onshelfholds     = $input->param('onshelfholds') || 0;
146
    my $onshelfholds     = $input->param('onshelfholds') || 0;
Lines 175-180 elsif ($op eq 'add') { Link Here
175
        norenewalbefore               => $norenewalbefore,
178
        norenewalbefore               => $norenewalbefore,
176
        auto_renew                    => $auto_renew,
179
        auto_renew                    => $auto_renew,
177
        no_auto_renewal_after         => $no_auto_renewal_after,
180
        no_auto_renewal_after         => $no_auto_renewal_after,
181
        no_auto_renewal_after_hard_limit => $no_auto_renewal_after_hard_limit,
178
        reservesallowed               => $reservesallowed,
182
        reservesallowed               => $reservesallowed,
179
        holds_per_record              => $holds_per_record,
183
        holds_per_record              => $holds_per_record,
180
        issuelength                   => $issuelength,
184
        issuelength                   => $issuelength,
Lines 502-507 while (my $row = $sth2->fetchrow_hashref) { Link Here
502
    } else {
506
    } else {
503
       $row->{'hardduedate'} = 0;
507
       $row->{'hardduedate'} = 0;
504
    }
508
    }
509
    if ($row->{no_auto_renewal_after_hard_limit}) {
510
       my $dt = eval { dt_from_string( $row->{no_auto_renewal_after_hard_limit} ) };
511
       $row->{no_auto_renewal_after_hard_limit} = eval { output_pref( { dt => $dt, dateonly => 1 } ) } if $dt;
512
    }
513
505
    push @row_loop, $row;
514
    push @row_loop, $row;
506
}
515
}
507
516
(-)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 872-877 CREATE TABLE `issuingrules` ( -- circulation and fine rules Link Here
872
  `norenewalbefore` int(4) default NULL, -- no renewal allowed until X days or hours before due date.
872
  `norenewalbefore` int(4) default NULL, -- no renewal allowed until X days or hours before due date.
873
  `auto_renew` BOOLEAN default FALSE, -- automatic renewal
873
  `auto_renew` BOOLEAN default FALSE, -- automatic renewal
874
  `no_auto_renewal_after` int(4) default NULL, -- no auto renewal allowed after X days or hours after the issue date
874
  `no_auto_renewal_after` int(4) default NULL, -- no auto renewal allowed after X days or hours after the issue date
875
  `no_auto_renewal_after_hard_limit` date default NULL, -- no auto renewal allowed after a given date
875
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
876
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
876
  `holds_per_record` SMALLINT(6) NOT NULL DEFAULT 1, -- How many holds a patron can have on a given bib
877
  `holds_per_record` SMALLINT(6) NOT NULL DEFAULT 1, -- How many holds a patron can have on a given bib
877
  `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
878
  `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt (+6 lines)
Lines 186-191 $(document).ready(function() { Link Here
186
                <th>No renewal before</th>
186
                <th>No renewal before</th>
187
                <th>Automatic renewal</th>
187
                <th>Automatic renewal</th>
188
                <th>No automatic renewal after</th>
188
                <th>No automatic renewal after</th>
189
                <th>No automatic renewal after (hard limit)</th>
189
                <th>Holds allowed (count)</th>
190
                <th>Holds allowed (count)</th>
190
                <th>Holds per record (count)</th>
191
                <th>Holds per record (count)</th>
191
                <th>On shelf holds allowed</th>
192
                <th>On shelf holds allowed</th>
Lines 266-271 $(document).ready(function() { Link Here
266
                                [% END %]
267
                                [% END %]
267
                            </td>
268
                            </td>
268
                            <td>[% rule.no_auto_renewal_after %]</td>
269
                            <td>[% rule.no_auto_renewal_after %]</td>
270
                            <td>[% rule.no_auto_renewal_after_hard_limit %]</td>
269
							<td>[% rule.reservesallowed %]</td>
271
							<td>[% rule.reservesallowed %]</td>
270
                                                        <td>[% rule.holds_per_record %]</td>
272
                                                        <td>[% rule.holds_per_record %]</td>
271
                                                        <td>
273
                                                        <td>
Lines 342-347 $(document).ready(function() { Link Here
342
                        </select>
344
                        </select>
343
                    </td>
345
                    </td>
344
                    <td><input type="text" name="no_auto_renewal_after" id="no_auto_renewal_after" size="3" /></td>
346
                    <td><input type="text" name="no_auto_renewal_after" id="no_auto_renewal_after" size="3" /></td>
347
                    <td>
348
                        <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"/>
349
                        <div class="hint">[% INCLUDE 'date-format.inc' %]</div>
350
                    </td>
345
                    <td><input type="text" name="reservesallowed" id="reservesallowed" size="2" /></td>
351
                    <td><input type="text" name="reservesallowed" id="reservesallowed" size="2" /></td>
346
                    <td><input type="text" name="holds_per_record" id="holds_per_record" size="2" /></td>
352
                    <td><input type="text" name="holds_per_record" id="holds_per_record" size="2" /></td>
347
                    <td>
353
                    <td>
(-)a/t/db_dependent/Circulation.t (-7 / +38 lines)
Lines 551-557 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
551
    );
551
    );
552
552
553
    subtest "too_late_renewal / no_auto_renewal_after" => sub {
553
    subtest "too_late_renewal / no_auto_renewal_after" => sub {
554
        plan tests => 8;
554
        plan tests => 14;
555
        my $item_to_auto_renew = $builder->build(
555
        my $item_to_auto_renew = $builder->build(
556
            {   source => 'Item',
556
            {   source => 'Item',
557
                value  => {
557
                value  => {
Lines 589-598 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
589
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
589
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
590
        is( $renewokay, 0,            'Do not renew, renewal is automatic' );
590
        is( $renewokay, 0,            'Do not renew, renewal is automatic' );
591
        is( $error,     'auto_renew', 'Cannot renew, renew is automatic' );
591
        is( $error,     'auto_renew', 'Cannot renew, renew is automatic' );
592
593
        $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 ) );
594
        ( $renewokay, $error ) =
595
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
596
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
597
        is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' );
598
599
        $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 ) );
600
        ( $renewokay, $error ) =
601
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
602
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
603
        is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' );
604
605
        $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 ) );
606
        ( $renewokay, $error ) =
607
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
608
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
609
        is( $error, 'auto_renew', 'Cannot renew, renew is automatic' );
592
    };
610
    };
593
611
594
    subtest "GetLatestAutoRenewDate" => sub {
612
    subtest "GetLatestAutoRenewDate" => sub {
595
        plan tests => 3;
613
        plan tests => 5;
596
        my $item_to_auto_renew = $builder->build(
614
        my $item_to_auto_renew = $builder->build(
597
            {   source => 'Item',
615
            {   source => 'Item',
598
                value  => {
616
                value  => {
Lines 606-628 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
606
        my $ten_days_before = dt_from_string->add( days => -10 );
624
        my $ten_days_before = dt_from_string->add( days => -10 );
607
        my $ten_days_ahead  = dt_from_string->add( days => 10 );
625
        my $ten_days_ahead  = dt_from_string->add( days => 10 );
608
        AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } );
626
        AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } );
609
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = ""');
627
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = "", no_auto_renewal_after_hard_limit = NULL');
610
        my $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
628
        my $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
611
        is( $latest_auto_renew_date, undef, 'GetLatestAutoRenewDate should return undef if no_auto_renewal_after is not defined' );
629
        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' );
612
        my $five_days_before = dt_from_string->add( days => -5 );
630
        my $five_days_before = dt_from_string->add( days => -5 );
613
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 5');
631
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 5, no_auto_renewal_after_hard_limit = NULL');
614
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
632
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
615
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
633
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
616
            $five_days_before->truncate( to => 'minute' ),
634
            $five_days_before->truncate( to => 'minute' ),
617
            'GetLatestAutoRenewDate should return -5 days if no_auto_renewal_after = 5 and date_due is 10 days before'
635
            'GetLatestAutoRenewDate should return -5 days if no_auto_renewal_after = 5 and date_due is 10 days before'
618
        );
636
        );
619
        my $five_days_ahead = dt_from_string->add( days => 5 );
637
        my $five_days_ahead = dt_from_string->add( days => 5 );
620
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 15');
638
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 15, no_auto_renewal_after_hard_limit = NULL');
621
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
639
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
622
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
640
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
623
            $five_days_ahead->truncate( to => 'minute' ),
641
            $five_days_ahead->truncate( to => 'minute' ),
624
            'GetLatestAutoRenewDate should return +5 days if no_auto_renewal_after = 15 and date_due is 10 days before'
642
            'GetLatestAutoRenewDate should return +5 days if no_auto_renewal_after = 15 and date_due is 10 days before'
625
        );
643
        );
644
        my $two_days_ahead = dt_from_string->add( days => 2 );
645
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = "", no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => 2 ) );
646
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
647
        is( $latest_auto_renew_date->truncate( to => 'day' ),
648
            $two_days_ahead->truncate( to => 'day' ),
649
            'GetLatestAutoRenewDate should return +2 days if no_auto_renewal_after_hard_limit is defined and not no_auto_renewal_after'
650
        );
651
        $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 ) );
652
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
653
        is( $latest_auto_renew_date->truncate( to => 'day' ),
654
            $two_days_ahead->truncate( to => 'day' ),
655
            'GetLatestAutoRenewDate should return +2 days if no_auto_renewal_after_hard_limit is < no_auto_renewal_after'
656
        );
657
626
    };
658
    };
627
659
628
    # Too many renewals
660
    # Too many renewals
629
- 

Return to bug 16344