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

(-)a/C4/Circulation.pm (-21 / +38 lines)
Lines 2753-2771 sub CanBookBeRenewed { Link Here
2753
        return ( 0, 'overdue');
2753
        return ( 0, 'overdue');
2754
    }
2754
    }
2755
2755
2756
    if ( $itemissue->{auto_renew}
2756
    if ( $itemissue->{auto_renew} ) {
2757
        and defined $issuing_rule->no_auto_renewal_after
2757
        if ( defined $issuing_rule->no_auto_renewal_after
2758
                and $issuing_rule->no_auto_renewal_after ne "" ) {
2758
                and $issuing_rule->no_auto_renewal_after ne "" ) {
2759
2759
            # Get issue_date and add no_auto_renewal_after
2760
        # Get issue_date and add no_auto_renewal_after
2760
            # If this is greater than today, it's too late for renewal.
2761
        # If this is greater than today, it's too late for renewal.
2761
            my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2762
        my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2762
            $maximum_renewal_date->add(
2763
        $maximum_renewal_date->add(
2763
                $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
2764
            $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
2764
            );
2765
        );
2765
            my $now = dt_from_string;
2766
        my $now = dt_from_string;
2766
            if ( $now >= $maximum_renewal_date ) {
2767
        if ( $now >= $maximum_renewal_date ) {
2767
                return ( 0, "auto_too_late" );
2768
            return ( 0, "auto_too_late" );
2768
            }
2769
        }
2770
        if ( defined $issuing_rule->no_auto_renewal_after_hard_limit
2771
                      and $issuing_rule->no_auto_renewal_after_hard_limit ne "" ) {
2772
            # If no_auto_renewal_after_hard_limit is >= today, it's also too late for renewal
2773
            if ( dt_from_string >= dt_from_string( $issuing_rule->no_auto_renewal_after_hard_limit ) ) {
2774
                return ( 0, "auto_too_late" );
2775
            }
2769
        }
2776
        }
2770
    }
2777
    }
2771
2778
Lines 3069-3076 has the item on loan. Link Here
3069
C<$itemnumber> is the number of the item to renew.
3076
C<$itemnumber> is the number of the item to renew.
3070
3077
3071
C<$GetLatestAutoRenewDate> returns the DateTime of the latest possible
3078
C<$GetLatestAutoRenewDate> returns the DateTime of the latest possible
3072
auto renew date, based on the value "No auto renewal after" of the applicable
3079
auto renew date, based on the value "No auto renewal after" and the "No auto
3073
issuing rule.
3080
renewal after (hard limit) of the applicable issuing rule.
3074
Returns undef if there is no date specify in the circ rules or if the patron, loan,
3081
Returns undef if there is no date specify in the circ rules or if the patron, loan,
3075
or item cannot be found.
3082
or item cannot be found.
3076
3083
Lines 3097-3110 sub GetLatestAutoRenewDate { Link Here
3097
    );
3104
    );
3098
3105
3099
    return unless $issuing_rule;
3106
    return unless $issuing_rule;
3100
    return if not $issuing_rule->no_auto_renewal_after
3107
    return
3101
               or $issuing_rule->no_auto_renewal_after eq '';
3108
      if ( not $issuing_rule->no_auto_renewal_after
3102
3109
            or $issuing_rule->no_auto_renewal_after eq '' )
3103
    my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
3110
      and ( not $issuing_rule->no_auto_renewal_after_hard_limit
3104
    $maximum_renewal_date->add(
3111
             or $issuing_rule->no_auto_renewal_after_hard_limit eq '' );
3105
        $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
3112
3106
    );
3113
    my $maximum_renewal_date;
3114
    if ( $issuing_rule->no_auto_renewal_after ) {
3115
        $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
3116
        $maximum_renewal_date->add(
3117
            $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
3118
        );
3119
    }
3107
3120
3121
    if ( $issuing_rule->no_auto_renewal_after_hard_limit ) {
3122
        my $dt = dt_from_string( $issuing_rule->no_auto_renewal_after_hard_limit );
3123
        $maximum_renewal_date = $dt if not $maximum_renewal_date or $maximum_renewal_date > $dt;
3124
    }
3108
    return $maximum_renewal_date;
3125
    return $maximum_renewal_date;
3109
}
3126
}
3110
3127
(-)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 176-181 elsif ($op eq 'add') { Link Here
176
        norenewalbefore               => $norenewalbefore,
179
        norenewalbefore               => $norenewalbefore,
177
        auto_renew                    => $auto_renew,
180
        auto_renew                    => $auto_renew,
178
        no_auto_renewal_after         => $no_auto_renewal_after,
181
        no_auto_renewal_after         => $no_auto_renewal_after,
182
        no_auto_renewal_after_hard_limit => $no_auto_renewal_after_hard_limit,
179
        reservesallowed               => $reservesallowed,
183
        reservesallowed               => $reservesallowed,
180
        holds_per_record              => $holds_per_record,
184
        holds_per_record              => $holds_per_record,
181
        issuelength                   => $issuelength,
185
        issuelength                   => $issuelength,
Lines 503-508 while (my $row = $sth2->fetchrow_hashref) { Link Here
503
    } else {
507
    } else {
504
       $row->{'hardduedate'} = 0;
508
       $row->{'hardduedate'} = 0;
505
    }
509
    }
510
    if ($row->{no_auto_renewal_after_hard_limit}) {
511
       my $dt = eval { dt_from_string( $row->{no_auto_renewal_after_hard_limit} ) };
512
       $row->{no_auto_renewal_after_hard_limit} = eval { output_pref( { dt => $dt, dateonly => 1 } ) } if $dt;
513
    }
514
506
    push @row_loop, $row;
515
    push @row_loop, $row;
507
}
516
}
508
517
(-)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 871-876 CREATE TABLE `issuingrules` ( -- circulation and fine rules Link Here
871
  `norenewalbefore` int(4) default NULL, -- no renewal allowed until X days or hours before due date.
871
  `norenewalbefore` int(4) default NULL, -- no renewal allowed until X days or hours before due date.
872
  `auto_renew` BOOLEAN default FALSE, -- automatic renewal
872
  `auto_renew` BOOLEAN default FALSE, -- automatic renewal
873
  `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` int(4) default NULL, -- no auto renewal allowed after X days or hours after the issue date
874
  `no_auto_renewal_after_hard_limit` date default NULL, -- no auto renewal allowed after a given date
874
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
875
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
875
  `holds_per_record` SMALLINT(6) NOT NULL DEFAULT 1, -- How many holds a patron can have on a given bib
876
  `holds_per_record` SMALLINT(6) NOT NULL DEFAULT 1, -- How many holds a patron can have on a given bib
876
  `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
877
  `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 267-272 $(document).ready(function() { Link Here
267
                                [% END %]
268
                                [% END %]
268
                            </td>
269
                            </td>
269
                            <td>[% rule.no_auto_renewal_after %]</td>
270
                            <td>[% rule.no_auto_renewal_after %]</td>
271
                            <td>[% rule.no_auto_renewal_after_hard_limit %]</td>
270
							<td>[% rule.reservesallowed %]</td>
272
							<td>[% rule.reservesallowed %]</td>
271
                                                        <td>[% rule.holds_per_record %]</td>
273
                                                        <td>[% rule.holds_per_record %]</td>
272
                                                        <td>
274
                                                        <td>
Lines 354-359 $(document).ready(function() { Link Here
354
                        </select>
356
                        </select>
355
                    </td>
357
                    </td>
356
                    <td><input type="text" name="no_auto_renewal_after" id="no_auto_renewal_after" size="3" /></td>
358
                    <td><input type="text" name="no_auto_renewal_after" id="no_auto_renewal_after" size="3" /></td>
359
                    <td>
360
                        <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"/>
361
                        <div class="hint">[% INCLUDE 'date-format.inc' %]</div>
362
                    </td>
357
                    <td><input type="text" name="reservesallowed" id="reservesallowed" size="2" /></td>
363
                    <td><input type="text" name="reservesallowed" id="reservesallowed" size="2" /></td>
358
                    <td><input type="text" name="holds_per_record" id="holds_per_record" size="2" /></td>
364
                    <td><input type="text" name="holds_per_record" id="holds_per_record" size="2" /></td>
359
                    <td>
365
                    <td>
(-)a/t/db_dependent/Circulation.t (-7 / +38 lines)
Lines 579-585 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
579
    );
579
    );
580
580
581
    subtest "too_late_renewal / no_auto_renewal_after" => sub {
581
    subtest "too_late_renewal / no_auto_renewal_after" => sub {
582
        plan tests => 8;
582
        plan tests => 14;
583
        my $item_to_auto_renew = $builder->build(
583
        my $item_to_auto_renew = $builder->build(
584
            {   source => 'Item',
584
            {   source => 'Item',
585
                value  => {
585
                value  => {
Lines 617-626 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
617
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
617
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
618
        is( $renewokay, 0,            'Do not renew, renewal is automatic' );
618
        is( $renewokay, 0,            'Do not renew, renewal is automatic' );
619
        is( $error,     'auto_renew', 'Cannot renew, renew is automatic' );
619
        is( $error,     'auto_renew', 'Cannot renew, renew is automatic' );
620
621
        $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 ) );
622
        ( $renewokay, $error ) =
623
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
624
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
625
        is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' );
626
627
        $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 ) );
628
        ( $renewokay, $error ) =
629
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
630
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
631
        is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' );
632
633
        $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 ) );
634
        ( $renewokay, $error ) =
635
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
636
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
637
        is( $error, 'auto_renew', 'Cannot renew, renew is automatic' );
620
    };
638
    };
621
639
622
    subtest "GetLatestAutoRenewDate" => sub {
640
    subtest "GetLatestAutoRenewDate" => sub {
623
        plan tests => 3;
641
        plan tests => 5;
624
        my $item_to_auto_renew = $builder->build(
642
        my $item_to_auto_renew = $builder->build(
625
            {   source => 'Item',
643
            {   source => 'Item',
626
                value  => {
644
                value  => {
Lines 634-656 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
634
        my $ten_days_before = dt_from_string->add( days => -10 );
652
        my $ten_days_before = dt_from_string->add( days => -10 );
635
        my $ten_days_ahead  = dt_from_string->add( days => 10 );
653
        my $ten_days_ahead  = dt_from_string->add( days => 10 );
636
        AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } );
654
        AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } );
637
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = ""');
655
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = "", no_auto_renewal_after_hard_limit = NULL');
638
        my $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
656
        my $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
639
        is( $latest_auto_renew_date, undef, 'GetLatestAutoRenewDate should return undef if no_auto_renewal_after is not defined' );
657
        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' );
640
        my $five_days_before = dt_from_string->add( days => -5 );
658
        my $five_days_before = dt_from_string->add( days => -5 );
641
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 5');
659
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 5, no_auto_renewal_after_hard_limit = NULL');
642
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
660
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
643
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
661
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
644
            $five_days_before->truncate( to => 'minute' ),
662
            $five_days_before->truncate( to => 'minute' ),
645
            'GetLatestAutoRenewDate should return -5 days if no_auto_renewal_after = 5 and date_due is 10 days before'
663
            'GetLatestAutoRenewDate should return -5 days if no_auto_renewal_after = 5 and date_due is 10 days before'
646
        );
664
        );
647
        my $five_days_ahead = dt_from_string->add( days => 5 );
665
        my $five_days_ahead = dt_from_string->add( days => 5 );
648
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 15');
666
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 15, no_auto_renewal_after_hard_limit = NULL');
649
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
667
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
650
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
668
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
651
            $five_days_ahead->truncate( to => 'minute' ),
669
            $five_days_ahead->truncate( to => 'minute' ),
652
            'GetLatestAutoRenewDate should return +5 days if no_auto_renewal_after = 15 and date_due is 10 days before'
670
            'GetLatestAutoRenewDate should return +5 days if no_auto_renewal_after = 15 and date_due is 10 days before'
653
        );
671
        );
672
        my $two_days_ahead = dt_from_string->add( days => 2 );
673
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = "", no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => 2 ) );
674
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
675
        is( $latest_auto_renew_date->truncate( to => 'day' ),
676
            $two_days_ahead->truncate( to => 'day' ),
677
            'GetLatestAutoRenewDate should return +2 days if no_auto_renewal_after_hard_limit is defined and not no_auto_renewal_after'
678
        );
679
        $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 ) );
680
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
681
        is( $latest_auto_renew_date->truncate( to => 'day' ),
682
            $two_days_ahead->truncate( to => 'day' ),
683
            'GetLatestAutoRenewDate should return +2 days if no_auto_renewal_after_hard_limit is < no_auto_renewal_after'
684
        );
685
654
    };
686
    };
655
687
656
    # Too many renewals
688
    # Too many renewals
657
- 

Return to bug 16344