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

(-)a/C4/Circulation.pm (-21 / +38 lines)
Lines 2721-2739 sub CanBookBeRenewed { Link Here
2721
        return ( 0, 'overdue');
2721
        return ( 0, 'overdue');
2722
    }
2722
    }
2723
2723
2724
    if ( $itemissue->{auto_renew}
2724
    if ( $itemissue->{auto_renew} ) {
2725
        and defined $issuing_rule->no_auto_renewal_after
2725
        if ( defined $issuing_rule->no_auto_renewal_after
2726
                and $issuing_rule->no_auto_renewal_after ne "" ) {
2726
                and $issuing_rule->no_auto_renewal_after ne "" ) {
2727
2727
            # Get issue_date and add no_auto_renewal_after
2728
        # Get issue_date and add no_auto_renewal_after
2728
            # If this is greater than today, it's too late for renewal.
2729
        # If this is greater than today, it's too late for renewal.
2729
            my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2730
        my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2730
            $maximum_renewal_date->add(
2731
        $maximum_renewal_date->add(
2731
                $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
2732
            $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
2732
            );
2733
        );
2733
            my $now = dt_from_string;
2734
        my $now = dt_from_string;
2734
            if ( $now >= $maximum_renewal_date ) {
2735
        if ( $now >= $maximum_renewal_date ) {
2735
                return ( 0, "auto_too_late" );
2736
            return ( 0, "auto_too_late" );
2736
            }
2737
        }
2738
        if ( defined $issuing_rule->no_auto_renewal_after_hard_limit
2739
                      and $issuing_rule->no_auto_renewal_after_hard_limit ne "" ) {
2740
            # If no_auto_renewal_after_hard_limit is >= today, it's also too late for renewal
2741
            if ( dt_from_string >= dt_from_string( $issuing_rule->no_auto_renewal_after_hard_limit ) ) {
2742
                return ( 0, "auto_too_late" );
2743
            }
2737
        }
2744
        }
2738
    }
2745
    }
2739
2746
Lines 3035-3042 has the item on loan. Link Here
3035
C<$itemnumber> is the number of the item to renew.
3042
C<$itemnumber> is the number of the item to renew.
3036
3043
3037
C<$GetLatestAutoRenewDate> returns the DateTime of the latest possible
3044
C<$GetLatestAutoRenewDate> returns the DateTime of the latest possible
3038
auto renew date, based on the value "No auto renewal after" of the applicable
3045
auto renew date, based on the value "No auto renewal after" and the "No auto
3039
issuing rule.
3046
renewal after (hard limit) of the applicable issuing rule.
3040
Returns undef if there is no date specify in the circ rules or if the patron, loan,
3047
Returns undef if there is no date specify in the circ rules or if the patron, loan,
3041
or item cannot be found.
3048
or item cannot be found.
3042
3049
Lines 3063-3076 sub GetLatestAutoRenewDate { Link Here
3063
    );
3070
    );
3064
3071
3065
    return unless $issuing_rule;
3072
    return unless $issuing_rule;
3066
    return if not $issuing_rule->no_auto_renewal_after
3073
    return
3067
               or $issuing_rule->no_auto_renewal_after eq '';
3074
      if ( not $issuing_rule->no_auto_renewal_after
3068
3075
            or $issuing_rule->no_auto_renewal_after eq '' )
3069
    my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
3076
      and ( not $issuing_rule->no_auto_renewal_after_hard_limit
3070
    $maximum_renewal_date->add(
3077
             or $issuing_rule->no_auto_renewal_after_hard_limit eq '' );
3071
        $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
3078
3072
    );
3079
    my $maximum_renewal_date;
3080
    if ( $issuing_rule->no_auto_renewal_after ) {
3081
        $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
3082
        $maximum_renewal_date->add(
3083
            $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
3084
        );
3085
    }
3073
3086
3087
    if ( $issuing_rule->no_auto_renewal_after_hard_limit ) {
3088
        my $dt = dt_from_string( $issuing_rule->no_auto_renewal_after_hard_limit );
3089
        $maximum_renewal_date = $dt if not $maximum_renewal_date or $maximum_renewal_date > $dt;
3090
    }
3074
    return $maximum_renewal_date;
3091
    return $maximum_renewal_date;
3075
}
3092
}
3076
3093
(-)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 869-874 CREATE TABLE `issuingrules` ( -- circulation and fine rules Link Here
869
  `norenewalbefore` int(4) default NULL, -- no renewal allowed until X days or hours before due date.
869
  `norenewalbefore` int(4) default NULL, -- no renewal allowed until X days or hours before due date.
870
  `auto_renew` BOOLEAN default FALSE, -- automatic renewal
870
  `auto_renew` BOOLEAN default FALSE, -- automatic renewal
871
  `no_auto_renewal_after` int(4) default NULL, -- no auto renewal allowed after X days or hours after the issue date
871
  `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_hard_limit` date default NULL, -- no auto renewal allowed after a given date
872
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
873
  `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
873
  `holds_per_record` SMALLINT(6) NOT NULL DEFAULT 1, -- How many holds a patron can have on a given bib
874
  `holds_per_record` SMALLINT(6) NOT NULL DEFAULT 1, -- How many holds a patron can have on a given bib
874
  `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
875
  `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 566-572 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
566
    );
566
    );
567
567
568
    subtest "too_late_renewal / no_auto_renewal_after" => sub {
568
    subtest "too_late_renewal / no_auto_renewal_after" => sub {
569
        plan tests => 8;
569
        plan tests => 14;
570
        my $item_to_auto_renew = $builder->build(
570
        my $item_to_auto_renew = $builder->build(
571
            {   source => 'Item',
571
            {   source => 'Item',
572
                value  => {
572
                value  => {
Lines 604-613 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
604
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
604
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
605
        is( $renewokay, 0,            'Do not renew, renewal is automatic' );
605
        is( $renewokay, 0,            'Do not renew, renewal is automatic' );
606
        is( $error,     'auto_renew', 'Cannot renew, renew is automatic' );
606
        is( $error,     'auto_renew', 'Cannot renew, renew is automatic' );
607
608
        $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 ) );
609
        ( $renewokay, $error ) =
610
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
611
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
612
        is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' );
613
614
        $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 ) );
615
        ( $renewokay, $error ) =
616
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
617
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
618
        is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' );
619
620
        $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 ) );
621
        ( $renewokay, $error ) =
622
          CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
623
        is( $renewokay, 0, 'Do not renew, renewal is automatic' );
624
        is( $error, 'auto_renew', 'Cannot renew, renew is automatic' );
607
    };
625
    };
608
626
609
    subtest "GetLatestAutoRenewDate" => sub {
627
    subtest "GetLatestAutoRenewDate" => sub {
610
        plan tests => 3;
628
        plan tests => 5;
611
        my $item_to_auto_renew = $builder->build(
629
        my $item_to_auto_renew = $builder->build(
612
            {   source => 'Item',
630
            {   source => 'Item',
613
                value  => {
631
                value  => {
Lines 621-643 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
621
        my $ten_days_before = dt_from_string->add( days => -10 );
639
        my $ten_days_before = dt_from_string->add( days => -10 );
622
        my $ten_days_ahead  = dt_from_string->add( days => 10 );
640
        my $ten_days_ahead  = dt_from_string->add( days => 10 );
623
        AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } );
641
        AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } );
624
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = ""');
642
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = "", no_auto_renewal_after_hard_limit = NULL');
625
        my $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
643
        my $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
626
        is( $latest_auto_renew_date, undef, 'GetLatestAutoRenewDate should return undef if no_auto_renewal_after is not defined' );
644
        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' );
627
        my $five_days_before = dt_from_string->add( days => -5 );
645
        my $five_days_before = dt_from_string->add( days => -5 );
628
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 5');
646
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 5, no_auto_renewal_after_hard_limit = NULL');
629
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
647
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
630
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
648
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
631
            $five_days_before->truncate( to => 'minute' ),
649
            $five_days_before->truncate( to => 'minute' ),
632
            'GetLatestAutoRenewDate should return -5 days if no_auto_renewal_after = 5 and date_due is 10 days before'
650
            'GetLatestAutoRenewDate should return -5 days if no_auto_renewal_after = 5 and date_due is 10 days before'
633
        );
651
        );
634
        my $five_days_ahead = dt_from_string->add( days => 5 );
652
        my $five_days_ahead = dt_from_string->add( days => 5 );
635
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 15');
653
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 15, no_auto_renewal_after_hard_limit = NULL');
636
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
654
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
637
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
655
        is( $latest_auto_renew_date->truncate( to => 'minute' ),
638
            $five_days_ahead->truncate( to => 'minute' ),
656
            $five_days_ahead->truncate( to => 'minute' ),
639
            'GetLatestAutoRenewDate should return +5 days if no_auto_renewal_after = 15 and date_due is 10 days before'
657
            'GetLatestAutoRenewDate should return +5 days if no_auto_renewal_after = 15 and date_due is 10 days before'
640
        );
658
        );
659
        my $two_days_ahead = dt_from_string->add( days => 2 );
660
        $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = "", no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => 2 ) );
661
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
662
        is( $latest_auto_renew_date->truncate( to => 'day' ),
663
            $two_days_ahead->truncate( to => 'day' ),
664
            'GetLatestAutoRenewDate should return +2 days if no_auto_renewal_after_hard_limit is defined and not no_auto_renewal_after'
665
        );
666
        $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 ) );
667
        $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} );
668
        is( $latest_auto_renew_date->truncate( to => 'day' ),
669
            $two_days_ahead->truncate( to => 'day' ),
670
            'GetLatestAutoRenewDate should return +2 days if no_auto_renewal_after_hard_limit is < no_auto_renewal_after'
671
        );
672
641
    };
673
    };
642
674
643
    # Too many renewals
675
    # Too many renewals
644
- 

Return to bug 16344