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

(-)a/C4/Circulation.pm (-14 / +10 lines)
Lines 2631-2653 sub MarkIssueReturned { Link Here
2631
            $item->last_returned_by( $patron->borrowernumber )->store;
2631
            $item->last_returned_by( $patron->borrowernumber )->store;
2632
        }
2632
        }
2633
2633
2634
        # The reason this is here, and not in Koha::Patron->has_overdues() is
2635
        # to make sure it will not cause any side effects elsewhere, since this
2636
        # is only relevant for removal of debarments.
2637
        my $has_overdue_ignore_unrestricted = C4::Context->preference('AutoRemoveOverduesRestrictions') eq 'when_no_overdue_causing_debarment';
2638
2639
        # Possibly remove any OVERDUES related debarment
2634
        # Possibly remove any OVERDUES related debarment
2640
        my $overdue_restrictions = $patron->restrictions->search({ type => 'OVERDUES' });
2635
        my $overdue_restrictions = $patron->restrictions->search({ type => 'OVERDUES' });
2641
        if ( C4::Context->preference('AutoRemoveOverduesRestrictions' ne 'no')
2636
        if (C4::Context->preference('AutoRemoveOverduesRestrictions') ne 'no' && $patron->is_debarred) {
2642
          && $patron->debarred
2637
            my $remove_restrictions =
2643
          && $overdue_restrictions->count
2638
                C4::Context->preference('AutoRemoveOverduesRestrictions') eq 'when_no_overdue_causing_debarment' ?
2644
          && !$patron->has_overdues({
2639
                    !$patron->has_debarring_overdues({ issue_branchcode => $issue_branchcode }) :
2645
              ignore_unrestricted => $has_overdue_ignore_unrestricted,
2640
                    !$patron->has_overdues;
2646
              issue_branch => $issue->{'branchcode'} })
2641
            if (
2647
        ) {
2642
                $remove_restrictions && $overdue_restrictions->count
2648
            DelUniqueDebarment({ borrowernumber => $borrowernumber, type => 'OVERDUES' });
2643
            ) {
2644
                DelUniqueDebarment({ borrowernumber => $borrowernumber, type => 'OVERDUES' });
2645
            }
2649
        }
2646
        }
2650
2651
    });
2647
    });
2652
2648
2653
    return $issue_id;
2649
    return $issue_id;
(-)a/Koha/Patron.pm (-9 / +43 lines)
Lines 993-1016 Returns the number of patron's overdues Link Here
993
=cut
993
=cut
994
994
995
sub has_overdues {
995
sub has_overdues {
996
    my ($self, $params) = @_;
996
    my ($self) = @_;
997
    my $date = dt_from_string();
997
    my $date = dt_from_string();
998
    my $dtf = Koha::Database->new->schema->storage->datetime_parser;
999
    return $self->_result->issues->search({ date_due => { '<' => $dtf->format_datetime($date) } })->count;
1000
}
1001
1002
sub has_debarring_overdues {
1003
    my ($self, $params) = @_;
1004
    $params //= {};
1005
    my $date = dt_from_string()->truncate( to => 'day' );
998
1006
999
    # If ignoring unrestricted overdues, calculate which delay value for
1007
    # If ignoring unrestricted overdues, calculate which delay value for
1000
    # overdue messages is set with restrictions. Then only include overdue
1008
    # overdue messages is set with restrictions. Then only include overdue
1001
    # issues older than that date when counting.
1009
    # issues older than that date when counting.
1002
    if($params->{ignore_unrestricted}) {
1010
    #TODO: bail out/throw exception if $params->{issue_branchcode} not set?
1003
        my $branchcode = $params->{issue_branchcode};
1011
    my $debarred_delay = _get_overdue_debarred_delay($params->{issue_branchcode}, $self->categorycode());
1004
        my $date_offset = _get_overdue_restrict_delay($params->{issue_branchcode}, $self->categorycode());
1012
    return 0 unless defined $debarred_delay;
1005
        $date->subtract(days => $date_offset);
1013
1014
    # Emulate the conditions in overdue_notices.pl.
1015
    # The overdue_notices-script effectively truncates both issues.date_due and current date
1016
    # to days when selecting overdue issues.
1017
    # Hours and minutes for issues.date_due is usually set to 23 and 59 respectively, though can theoretically
1018
    # be set to any other value (truncated to minutes, except if CalcDateDue gets a $startdate)
1019
    #
1020
    # No matter what time of day date_due is set to, overdue_notices.pl will select all issues that are due
1021
    # the current date or later. We can emulate this query by instead of truncating both to days in the SQL-query,
1022
    # using the condition that date_due must be less then the current date truncated to days (time set to 00:00:00)
1023
    # offset by one day in the future.
1024
1025
    $date->add(days => 1);
1026
1027
    my $calendar;
1028
    if (C4::Context->preference('OverdueNoticeCalendar')) {
1029
        $calendar = Koha::Calendar->new( branchcode => $params->{issue_branchcode} );
1006
    }
1030
    }
1007
1031
1008
    my $dtf = Koha::Database->new->schema->storage->datetime_parser;
1032
    my $dtf = Koha::Database->new->schema->storage->datetime_parser;
1009
    return $self->_result->issues->search({ date_due => { '<' => $dtf->format_datetime( $date )} })->count;
1033
    my $issues = $self->_result->issues->search({ date_due => { '<' => $dtf->format_datetime($date) } });
1034
    my $now = dt_from_string();
1035
1036
    while (my $issue = $issues->next) {
1037
        my $days_between = C4::Context->preference('OverdueNoticeCalendar') ?
1038
            $calendar->days_between(dt_from_string($issue->date_due), $now)->in_units('days') :
1039
            $now->delta_days(dt_from_string($issue->date_due))->in_units('days');
1040
        if ($days_between >= $debarred_delay) {
1041
            return 1;
1042
        }
1043
    }
1044
    return 0;
1010
}
1045
}
1011
1046
1012
# Fetch first delayX value from overduerules where debarredX is set, or 0 for no delay
1047
# Fetch first delayX value from overduerules where debarredX is set, or 0 for no delay
1013
sub _get_overdue_restrict_delay {
1048
sub _get_overdue_debarred_delay {
1014
    my ($branchcode, $categorycode) = @_;
1049
    my ($branchcode, $categorycode) = @_;
1015
    my $dbh = C4::Context->dbh();
1050
    my $dbh = C4::Context->dbh();
1016
1051
Lines 1032-1039 sub _get_overdue_restrict_delay { Link Here
1032
        return $overdue_rules->{"delay2"} if($overdue_rules->{"debarred2"});
1067
        return $overdue_rules->{"delay2"} if($overdue_rules->{"debarred2"});
1033
        return $overdue_rules->{"delay3"} if($overdue_rules->{"debarred3"});
1068
        return $overdue_rules->{"delay3"} if($overdue_rules->{"debarred3"});
1034
    }
1069
    }
1035
1070
    return undef;
1036
    return 0;
1037
}
1071
}
1038
1072
1039
=head3 track_login
1073
=head3 track_login
(-)a/t/db_dependent/Circulation/MarkIssueReturned.t (-12 / +13 lines)
Lines 201-209 subtest 'AutoRemoveOverduesRestrictions' => sub { Link Here
201
    my $item_1 = $builder->build_sample_item;
201
    my $item_1 = $builder->build_sample_item;
202
    my $item_2 = $builder->build_sample_item;
202
    my $item_2 = $builder->build_sample_item;
203
    my $item_3 = $builder->build_sample_item;
203
    my $item_3 = $builder->build_sample_item;
204
    my $five_days_ago = dt_from_string->subtract( days => 5 );
204
    my $nine_days_ago = dt_from_string->subtract( days => 9 ); #->set_hour(23)->set_minute(59);
205
    my $checkout_1 = AddIssue( $patron->unblessed, $item_1->barcode, $five_days_ago ); # overdue, but would not trigger debarment
205
    my $checkout_1 = AddIssue( $patron->unblessed, $item_1->barcode, $nine_days_ago ); # overdue, but would not trigger debarment
206
    my $checkout_2 = AddIssue( $patron->unblessed, $item_2->barcode, $five_days_ago ); # overdue, but would not trigger debarment
206
    my $checkout_2 = AddIssue( $patron->unblessed, $item_2->barcode, $nine_days_ago ); # overdue, but would not trigger debarment
207
    my $checkout_3 = AddIssue( $patron->unblessed, $item_3->barcode ); # not overdue
207
    my $checkout_3 = AddIssue( $patron->unblessed, $item_3->barcode ); # not overdue
208
208
209
    Koha::Patron::Debarments::AddUniqueDebarment(
209
    Koha::Patron::Debarments::AddUniqueDebarment(
Lines 227-236 subtest 'AutoRemoveOverduesRestrictions' => sub { Link Here
227
227
228
    t::lib::Mocks::mock_preference('AutoRemoveOverduesRestrictions', 'when_no_overdue_causing_debarment');
228
    t::lib::Mocks::mock_preference('AutoRemoveOverduesRestrictions', 'when_no_overdue_causing_debarment');
229
229
230
    my $eleven_days_ago = dt_from_string->subtract( days => 11 );
230
    my $ten_days_ago = dt_from_string->subtract( days => 10 );
231
232
    $checkout_1 = AddIssue( $patron->unblessed, $item_1->barcode, $ten_days_ago ); # overdue and would trigger debarment
233
    $checkout_2 = AddIssue( $patron->unblessed, $item_2->barcode, $nine_days_ago ); # overdue, but would not trigger debarment
231
234
232
    $checkout_1 = AddIssue( $patron->unblessed, $item_1->barcode, $eleven_days_ago ); # overdue and would trigger debarment
235
    print STDERR "DUEDATE: " . $nine_days_ago->stringify . "\n";
233
    $checkout_2 = AddIssue( $patron->unblessed, $item_2->barcode, $five_days_ago ); # overdue, but would not trigger debarment
234
236
235
    Koha::Patron::Debarments::AddUniqueDebarment(
237
    Koha::Patron::Debarments::AddUniqueDebarment(
236
        {
238
        {
Lines 245-251 subtest 'AutoRemoveOverduesRestrictions' => sub { Link Here
245
    $debarments = Koha::Patron::Debarments::GetDebarments({ borrowernumber => $patron->borrowernumber });
247
    $debarments = Koha::Patron::Debarments::GetDebarments({ borrowernumber => $patron->borrowernumber });
246
    is( scalar @$debarments, 0, 'OVERDUES debarment is removed if remaning items would not result in patron debarment' );
248
    is( scalar @$debarments, 0, 'OVERDUES debarment is removed if remaning items would not result in patron debarment' );
247
249
248
    $checkout_1 = AddIssue( $patron->unblessed, $item_1->barcode, $eleven_days_ago ); # overdue and would trigger debarment
250
    $checkout_1 = AddIssue( $patron->unblessed, $item_1->barcode, $ten_days_ago ); # overdue and would trigger debarment
249
251
250
    Koha::Patron::Debarments::AddUniqueDebarment(
252
    Koha::Patron::Debarments::AddUniqueDebarment(
251
        {
253
        {
Lines 260-271 subtest 'AutoRemoveOverduesRestrictions' => sub { Link Here
260
    $debarments = Koha::Patron::Debarments::GetDebarments({ borrowernumber => $patron->borrowernumber });
262
    $debarments = Koha::Patron::Debarments::GetDebarments({ borrowernumber => $patron->borrowernumber });
261
    is( $debarments->[0]->{type}, 'OVERDUES', 'OVERDUES debarment is not removed if patron still has overdues that would trigger debarment' );
263
    is( $debarments->[0]->{type}, 'OVERDUES', 'OVERDUES debarment is not removed if patron still has overdues that would trigger debarment' );
262
264
263
    my $thirteen_days_ago = dt_from_string->subtract( days => 13 );
265
    my $eleven_days_ago = dt_from_string->subtract( days => 11 );
264
266
265
    # overdue and would trigger debarment
267
    # overdue and would trigger debarment
266
    $checkout_2 = AddIssue( $patron->unblessed, $item_2->barcode, $thirteen_days_ago );
268
    $checkout_2 = AddIssue( $patron->unblessed, $item_2->barcode, $eleven_days_ago );
267
269
268
    # $chechout_1 should now not trigger debarment with this new rule for specific branchcode
270
    # $checkout_1 should now not trigger debarment with this new rule for specific branchcode
269
    $dbh->do(qq{
271
    $dbh->do(qq{
270
        INSERT INTO `overduerules` (
272
        INSERT INTO `overduerules` (
271
            `branchcode`,
273
            `branchcode`,
Lines 277-283 subtest 'AutoRemoveOverduesRestrictions' => sub { Link Here
277
            `letter2`,
279
            `letter2`,
278
            `debarred2`
280
            `debarred2`
279
        )
281
        )
280
        VALUES ('$branchcode', '$categorycode', 6, 'ODUE', 0, 12, 'ODUE2', 1)
282
        VALUES ('$branchcode', '$categorycode', 6, 'ODUE', 0, 11, 'ODUE2', 1)
281
    });
283
    });
282
284
283
    C4::Circulation::MarkIssueReturned( $patron->borrowernumber, $item_2->itemnumber );
285
    C4::Circulation::MarkIssueReturned( $patron->borrowernumber, $item_2->itemnumber );
284
- 

Return to bug 29145