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

(-)a/C4/Circulation.pm (-20 / +35 lines)
Lines 2851-2869 sub CanBookBeRenewed { Link Here
2851
        return ( 0, 'overdue');
2851
        return ( 0, 'overdue');
2852
    }
2852
    }
2853
2853
2854
    if ( $itemissue->{auto_renew}
2854
    if ( $itemissue->{auto_renew} ) {
2855
        and defined $issuingrule->{no_auto_renewal_after}
2855
        if ( defined $issuingrule->{no_auto_renewal_after}
2856
                and $issuingrule->{no_auto_renewal_after} ne "" ) {
2856
                and $issuingrule->{no_auto_renewal_after} ne "" ) {
2857
2857
            # Get issue_date and add no_auto_renewal_after
2858
        # Get issue_date and add no_auto_renewal_after
2858
            # If this is greater than today, it's too late for renewal.
2859
        # If this is greater than today, it's too late for renewal.
2859
            my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2860
        my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2860
            $maximum_renewal_date->add(
2861
        $maximum_renewal_date->add(
2861
                $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after}
2862
            $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after}
2862
            );
2863
        );
2863
            my $now = dt_from_string;
2864
        my $now = dt_from_string;
2864
            if ( $now >= $maximum_renewal_date ) {
2865
        if ( $now >= $maximum_renewal_date ) {
2865
                return ( 0, "auto_too_late" );
2866
            return ( 0, "auto_too_late" );
2866
            }
2867
        }
2868
        if ( defined $issuingrule->{no_auto_renewal_after_hard_limit}
2869
                      and $issuingrule->{no_auto_renewal_after_hard_limit} ne "" ) {
2870
            # If no_auto_renewal_after_hard_limit is >= today, it's also too late for renewal
2871
            if ( dt_from_string >= dt_from_string( $issuingrule->{no_auto_renewal_after_hard_limit} ) ) {
2872
                return ( 0, "auto_too_late" );
2873
            }
2867
        }
2874
        }
2868
    }
2875
    }
2869
2876
Lines 3151-3158 has the item on loan. Link Here
3151
C<$itemnumber> is the number of the item to renew.
3158
C<$itemnumber> is the number of the item to renew.
3152
3159
3153
C<$GetLatestAutoRenewDate> returns the DateTime of the latest possible
3160
C<$GetLatestAutoRenewDate> returns the DateTime of the latest possible
3154
auto renew date, based on the value "No auto renewal after" of the applicable
3161
auto renew date, based on the value "No auto renewal after" and the "No auto
3155
issuing rule.
3162
renewal after (hard limit) of the applicable issuing rule.
3156
Returns undef if there is no date specify in the circ rules or if the patron, loan,
3163
Returns undef if there is no date specify in the circ rules or if the patron, loan,
3157
or item cannot be found.
3164
or item cannot be found.
3158
3165
Lines 3176-3189 sub GetLatestAutoRenewDate { Link Here
3176
3183
3177
    my $now = dt_from_string;
3184
    my $now = dt_from_string;
3178
3185
3179
    return if not $issuingrule->{no_auto_renewal_after}
3186
    return if ( not $issuingrule->{no_auto_renewal_after} or $issuingrule->{no_auto_renewal_after} eq '' )
3180
               or $issuingrule->{no_auto_renewal_after} eq '';
3187
        and   ( not $issuingrule->{no_auto_renewal_after_hard_limit} or $issuingrule->{no_auto_renewal_after_hard_limit} eq '' );
3181
3188
3182
    my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
3183
    $maximum_renewal_date->add(
3184
        $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after}
3185
    );
3186
3189
3190
    my $maximum_renewal_date;
3191
    if ( $issuingrule->{no_auto_renewal_after} ) {
3192
        $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
3193
        $maximum_renewal_date->add(
3194
            $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after}
3195
        );
3196
    }
3197
3198
    if ( $issuingrule->{no_auto_renewal_after_hard_limit} ) {
3199
        my $dt = dt_from_string( $issuingrule->{no_auto_renewal_after_hard_limit} );
3200
        $maximum_renewal_date = $dt if not $maximum_renewal_date or $maximum_renewal_date > $dt;
3201
    }
3187
    return $maximum_renewal_date;
3202
    return $maximum_renewal_date;
3188
}
3203
}
3189
3204
(-)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 870-875 CREATE TABLE `issuingrules` ( -- circulation and fine rules Link Here
870
  `norenewalbefore` int(4) default NULL, -- no renewal allowed until X days or hours before due date.
870
  `norenewalbefore` int(4) default NULL, -- no renewal allowed until X days or hours before due date.
871
  `auto_renew` BOOLEAN default FALSE, -- automatic renewal
871
  `auto_renew` BOOLEAN default FALSE, -- automatic renewal
872
  `no_auto_renewal_after` int(4) default NULL, -- no auto renewal allowed after X days or hours after the issue date
872
  `no_auto_renewal_after` int(4) default NULL, -- no auto renewal allowed after X days or hours after the issue date
873
  `no_auto_renewal_after_hard_limit` date default NULL, -- no auto renewal allowed after a given date
873
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
874
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
874
  `holds_per_record` SMALLINT(6) NOT NULL DEFAULT 1, -- How many holds a patron can have on a given bib
875
  `holds_per_record` SMALLINT(6) NOT NULL DEFAULT 1, -- How many holds a patron can have on a given bib
875
  `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
876
  `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