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

(-)a/C4/Circulation.pm (-19 / +34 lines)
Lines 2825-2843 sub CanBookBeRenewed { Link Here
2825
        return ( 0, 'overdue');
2825
        return ( 0, 'overdue');
2826
    }
2826
    }
2827
2827
2828
    if ( $itemissue->{auto_renew}
2828
    if ( $itemissue->{auto_renew} ) {
2829
        and defined $issuing_rule->no_auto_renewal_after
2829
        if ( defined $issuing_rule->no_auto_renewal_after
2830
                and $issuing_rule->no_auto_renewal_after ne "" ) {
2830
                and $issuing_rule->no_auto_renewal_after ne "" ) {
2831
2831
            # Get issue_date and add no_auto_renewal_after
2832
        # Get issue_date and add no_auto_renewal_after
2832
            # If this is greater than today, it's too late for renewal.
2833
        # If this is greater than today, it's too late for renewal.
2833
            my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2834
        my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2834
            $maximum_renewal_date->add(
2835
        $maximum_renewal_date->add(
2835
                $issuing_rule->{lengthunit} => $issuing_rule->no_auto_renewal_after
2836
            $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
2836
            );
2837
        );
2837
            my $now = dt_from_string;
2838
        my $now = dt_from_string;
2838
            if ( $now >= $maximum_renewal_date ) {
2839
        if ( $now >= $maximum_renewal_date ) {
2839
                return ( 0, "auto_too_late" );
2840
            return ( 0, "auto_too_late" );
2840
            }
2841
        }
2842
        if ( defined $issuing_rule->no_auto_renewal_after_hard_limit
2843
                      and $issuing_rule->no_auto_renewal_after_hard_limit ne "" ) {
2844
            # If no_auto_renewal_after_hard_limit is >= today, it's also too late for renewal
2845
            if ( dt_from_string >= dt_from_string( $issuing_rule->no_auto_renewal_after_hard_limit ) ) {
2846
                return ( 0, "auto_too_late" );
2847
            }
2841
        }
2848
        }
2842
    }
2849
    }
2843
2850
Lines 3135-3142 has the item on loan. Link Here
3135
C<$itemnumber> is the number of the item to renew.
3142
C<$itemnumber> is the number of the item to renew.
3136
3143
3137
C<$GetLatestAutoRenewDate> returns the DateTime of the latest possible
3144
C<$GetLatestAutoRenewDate> returns the DateTime of the latest possible
3138
auto renew date, based on the value "No auto renewal after" of the applicable
3145
auto renew date, based on the value "No auto renewal after" and the "No auto
3139
issuing rule.
3146
renewal after (hard limit) of the applicable issuing rule.
3140
Returns undef if there is no date specify in the circ rules or if the patron, loan,
3147
Returns undef if there is no date specify in the circ rules or if the patron, loan,
3141
or item cannot be found.
3148
or item cannot be found.
3142
3149
Lines 3164-3176 sub GetLatestAutoRenewDate { Link Here
3164
3171
3165
    return unless $issuing_rule;
3172
    return unless $issuing_rule;
3166
    return if not $issuing_rule->no_auto_renewal_after
3173
    return if not $issuing_rule->no_auto_renewal_after
3167
               or $issuing_rule->no_auto_renewal_after eq '';
3174
               or $issuing_rule->no_auto_renewal_after eq ''
3175
        and   ( not $issuing_rule->no_auto_renewal_after_hard_limit or $issuing_rule->no_auto_renewal_after_hard_limit eq '' );
3168
3176
3169
    my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
3177
    my $maximum_renewal_date;
3170
    $maximum_renewal_date->add(
3178
    if ( $issuing_rule->no_auto_renewal_after ) {
3171
        $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
3179
        $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
3172
    );
3180
        $maximum_renewal_date->add(
3181
            $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
3182
        );
3183
    }
3173
3184
3185
    if ( $issuing_rule->no_auto_renewal_after_hard_limit ) {
3186
        my $dt = dt_from_string( $issuing_rule->no_auto_renewal_after_hard_limit );
3187
        $maximum_renewal_date = $dt if not $maximum_renewal_date or $maximum_renewal_date > $dt;
3188
    }
3174
    return $maximum_renewal_date;
3189
    return $maximum_renewal_date;
3175
}
3190
}
3176
3191
(-)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 504-509 while (my $row = $sth2->fetchrow_hashref) { Link Here
504
    } else {
508
    } else {
505
       $row->{'hardduedate'} = 0;
509
       $row->{'hardduedate'} = 0;
506
    }
510
    }
511
    if ($row->{no_auto_renewal_after_hard_limit}) {
512
       my $dt = eval { dt_from_string( $row->{no_auto_renewal_after_hard_limit} ) };
513
       $row->{no_auto_renewal_after_hard_limit} = eval { output_pref( { dt => $dt, dateonly => 1 } ) } if $dt;
514
    }
515
507
    push @row_loop, $row;
516
    push @row_loop, $row;
508
}
517
}
509
518
(-)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 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 565-571 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
565
    );
565
    );
566
566
567
    subtest "too_late_renewal / no_auto_renewal_after" => sub {
567
    subtest "too_late_renewal / no_auto_renewal_after" => sub {
568
        plan tests => 8;
568
        plan tests => 14;
569
        my $item_to_auto_renew = $builder->build(
569
        my $item_to_auto_renew = $builder->build(
570
            {   source => 'Item',
570
            {   source => 'Item',
571
                value  => {
571
                value  => {
Lines 603-612 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
603
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
603
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
604
        is( $renewokay, 0,            'Do not renew, renewal is automatic' );
604
        is( $renewokay, 0,            'Do not renew, renewal is automatic' );
605
        is( $error,     'auto_renew', 'Cannot renew, renew is automatic' );
605
        is( $error,     'auto_renew', 'Cannot renew, renew is automatic' );
606
607
        $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 ) );
608
        ( $renewokay, $error ) =
609
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
610
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
611
        is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' );
612
613
        $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 ) );
614
        ( $renewokay, $error ) =
615
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
616
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
617
        is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' );
618
619
        $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 ) );
620
        ( $renewokay, $error ) =
621
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
622
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
623
        is( $error, 'auto_renew', 'Cannot renew, renew is automatic' );
606
    };
624
    };
607
625
608
    subtest "GetLatestAutoRenewDate" => sub {
626
    subtest "GetLatestAutoRenewDate" => sub {
609
        plan tests => 3;
627
        plan tests => 5;
610
        my $item_to_auto_renew = $builder->build(
628
        my $item_to_auto_renew = $builder->build(
611
            {   source => 'Item',
629
            {   source => 'Item',
612
                value  => {
630
                value  => {
Lines 620-642 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
620
        my $ten_days_before = dt_from_string->add( days => -10 );
638
        my $ten_days_before = dt_from_string->add( days => -10 );
621
        my $ten_days_ahead  = dt_from_string->add( days => 10 );
639
        my $ten_days_ahead  = dt_from_string->add( days => 10 );
622
        AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } );
640
        AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } );
623
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = ""');
641
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = "", no_auto_renewal_after_hard_limit = NULL');
624
        my $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
642
        my $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
625
        is( $latest_auto_renew_date, undef, 'GetLatestAutoRenewDate should return undef if no_auto_renewal_after is not defined' );
643
        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' );
626
        my $five_days_before = dt_from_string->add( days => -5 );
644
        my $five_days_before = dt_from_string->add( days => -5 );
627
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 5');
645
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 5, no_auto_renewal_after_hard_limit = NULL');
628
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
646
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
629
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
647
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
630
            $five_days_before->truncate( to => 'minute' ),
648
            $five_days_before->truncate( to => 'minute' ),
631
            'GetLatestAutoRenewDate should return -5 days if no_auto_renewal_after = 5 and date_due is 10 days before'
649
            'GetLatestAutoRenewDate should return -5 days if no_auto_renewal_after = 5 and date_due is 10 days before'
632
        );
650
        );
633
        my $five_days_ahead = dt_from_string->add( days => 5 );
651
        my $five_days_ahead = dt_from_string->add( days => 5 );
634
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 15');
652
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 15, no_auto_renewal_after_hard_limit = NULL');
635
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
653
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
636
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
654
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
637
            $five_days_ahead->truncate( to => 'minute' ),
655
            $five_days_ahead->truncate( to => 'minute' ),
638
            'GetLatestAutoRenewDate should return +5 days if no_auto_renewal_after = 15 and date_due is 10 days before'
656
            'GetLatestAutoRenewDate should return +5 days if no_auto_renewal_after = 15 and date_due is 10 days before'
639
        );
657
        );
658
        my $two_days_ahead = dt_from_string->add( days => 2 );
659
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = "", no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => 2 ) );
660
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
661
        is( $latest_auto_renew_date->truncate( to => 'day' ),
662
            $two_days_ahead->truncate( to => 'day' ),
663
            'GetLatestAutoRenewDate should return +2 days if no_auto_renewal_after_hard_limit is defined and not no_auto_renewal_after'
664
        );
665
        $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 ) );
666
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
667
        is( $latest_auto_renew_date->truncate( to => 'day' ),
668
            $two_days_ahead->truncate( to => 'day' ),
669
            'GetLatestAutoRenewDate should return +2 days if no_auto_renewal_after_hard_limit is < no_auto_renewal_after'
670
        );
671
640
    };
672
    };
641
673
642
    # Too many renewals
674
    # Too many renewals
643
- 

Return to bug 16344