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

(-)a/C4/Circulation.pm (-9 / +8 lines)
Lines 2625-2642 sub MarkIssueReturned { Link Here
2625
        }
2625
        }
2626
2626
2627
        # Possibly remove any OVERDUES related debarment
2627
        # Possibly remove any OVERDUES related debarment
2628
        my $overdue_restrictions = $patron->restrictions->search({ type => 'OVERDUES' });
2628
        my $overdue_restrictions = $patron->restrictions->search( { type => 'OVERDUES' } );
2629
        if (C4::Context->preference('AutoRemoveOverduesRestrictions') ne 'no' && $patron->is_debarred) {
2629
        if ( C4::Context->preference('AutoRemoveOverduesRestrictions') ne 'no' && $patron->is_debarred ) {
2630
            my $remove_restrictions =
2630
            my $remove_restrictions =
2631
                C4::Context->preference('AutoRemoveOverduesRestrictions') eq 'when_no_overdue_causing_debarment' ?
2631
                C4::Context->preference('AutoRemoveOverduesRestrictions') eq 'when_no_overdue_causing_debarment'
2632
                    !$patron->has_restricting_overdues({ issue_branchcode => $issue_branchcode }) :
2632
                ? !$patron->has_restricting_overdues( { issue_branchcode => $issue_branchcode } )
2633
                    !$patron->has_overdues;
2633
                : !$patron->has_overdues;
2634
            if (
2634
            if ( $remove_restrictions && $overdue_restrictions->count ) {
2635
                $remove_restrictions && $overdue_restrictions->count
2635
                DelUniqueDebarment( { borrowernumber => $borrowernumber, type => 'OVERDUES' } );
2636
            ) {
2637
                DelUniqueDebarment({ borrowernumber => $borrowernumber, type => 'OVERDUES' });
2638
            }
2636
            }
2639
        }
2637
        }
2638
2640
    });
2639
    });
2641
2640
2642
    return $issue_id;
2641
    return $issue_id;
(-)a/Koha/Patron.pm (-18 / +21 lines)
Lines 1016-1021 sub has_overdues { Link Here
1016
}
1016
}
1017
1017
1018
1018
1019
1019
=head3 has_restricting_overdues
1020
=head3 has_restricting_overdues
1020
1021
1021
my $has_restricting_overdues = $patron->has_restricting_overdues({ issue_branchcode => $branchcode });
1022
my $has_restricting_overdues = $patron->has_restricting_overdues({ issue_branchcode => $branchcode });
Lines 1025-1031 Returns true if patron has overdues that would result in debarment. Link Here
1025
=cut
1026
=cut
1026
1027
1027
sub has_restricting_overdues {
1028
sub has_restricting_overdues {
1028
    my ($self, $params) = @_;
1029
    my ( $self, $params ) = @_;
1029
    $params //= {};
1030
    $params //= {};
1030
    my $date = dt_from_string()->truncate( to => 'day' );
1031
    my $date = dt_from_string()->truncate( to => 'day' );
1031
1032
Lines 1033-1039 sub has_restricting_overdues { Link Here
1033
    # overdue messages is set with restrictions. Then only include overdue
1034
    # overdue messages is set with restrictions. Then only include overdue
1034
    # issues older than that date when counting.
1035
    # issues older than that date when counting.
1035
    #TODO: bail out/throw exception if $params->{issue_branchcode} not set?
1036
    #TODO: bail out/throw exception if $params->{issue_branchcode} not set?
1036
    my $debarred_delay = _get_overdue_debarred_delay($params->{issue_branchcode}, $self->categorycode());
1037
    my $debarred_delay = _get_overdue_debarred_delay( $params->{issue_branchcode}, $self->categorycode() );
1037
    return 0 unless defined $debarred_delay;
1038
    return 0 unless defined $debarred_delay;
1038
1039
1039
    # Emulate the conditions in overdue_notices.pl.
1040
    # Emulate the conditions in overdue_notices.pl.
Lines 1047-1068 sub has_restricting_overdues { Link Here
1047
    # using the condition that date_due must be less then the current date truncated to days (time set to 00:00:00)
1048
    # using the condition that date_due must be less then the current date truncated to days (time set to 00:00:00)
1048
    # offset by one day in the future.
1049
    # offset by one day in the future.
1049
1050
1050
    $date->add(days => 1);
1051
    $date->add( days => 1 );
1051
1052
1052
    my $calendar;
1053
    my $calendar;
1053
    if (C4::Context->preference('OverdueNoticeCalendar')) {
1054
    if ( C4::Context->preference('OverdueNoticeCalendar') ) {
1054
        $calendar = Koha::Calendar->new( branchcode => $params->{issue_branchcode} );
1055
        $calendar = Koha::Calendar->new( branchcode => $params->{issue_branchcode} );
1055
    }
1056
    }
1056
1057
1057
    my $dtf = Koha::Database->new->schema->storage->datetime_parser;
1058
    my $dtf    = Koha::Database->new->schema->storage->datetime_parser;
1058
    my $issues = $self->_result->issues->search({ date_due => { '<' => $dtf->format_datetime($date) } });
1059
    my $issues = $self->_result->issues->search( { date_due => { '<' => $dtf->format_datetime($date) } } );
1059
    my $now = dt_from_string();
1060
    my $now    = dt_from_string();
1060
1061
1061
    while (my $issue = $issues->next) {
1062
    while ( my $issue = $issues->next ) {
1062
        my $days_between = C4::Context->preference('OverdueNoticeCalendar') ?
1063
        my $days_between =
1063
            $calendar->days_between(dt_from_string($issue->date_due), $now)->in_units('days') :
1064
            C4::Context->preference('OverdueNoticeCalendar')
1064
            $now->delta_days(dt_from_string($issue->date_due))->in_units('days');
1065
            ? $calendar->days_between( dt_from_string( $issue->date_due ), $now )->in_units('days')
1065
        if ($days_between >= $debarred_delay) {
1066
            : $now->delta_days( dt_from_string( $issue->date_due ) )->in_units('days');
1067
        if ( $days_between >= $debarred_delay ) {
1066
            return 1;
1068
            return 1;
1067
        }
1069
        }
1068
    }
1070
    }
Lines 1071-1077 sub has_restricting_overdues { Link Here
1071
1073
1072
# Fetch first delayX value from overduerules where debarredX is set, or 0 for no delay
1074
# Fetch first delayX value from overduerules where debarredX is set, or 0 for no delay
1073
sub _get_overdue_debarred_delay {
1075
sub _get_overdue_debarred_delay {
1074
    my ($branchcode, $categorycode) = @_;
1076
    my ( $branchcode, $categorycode ) = @_;
1075
    my $dbh = C4::Context->dbh();
1077
    my $dbh = C4::Context->dbh();
1076
1078
1077
    # We get default rules if there is no rule for this branch
1079
    # We get default rules if there is no rule for this branch
Lines 1080-1100 sub _get_overdue_debarred_delay { Link Here
1080
            branchcode   => $branchcode,
1082
            branchcode   => $branchcode,
1081
            categorycode => $categorycode
1083
            categorycode => $categorycode
1082
        }
1084
        }
1083
      )
1085
        )
1084
      || Koha::OverdueRules->find(
1086
        || Koha::OverdueRules->find(
1085
        {
1087
        {
1086
            branchcode   => q{},
1088
            branchcode   => q{},
1087
            categorycode => $categorycode
1089
            categorycode => $categorycode
1088
        }
1090
        }
1089
      );
1091
        );
1090
1092
1091
    if ( $rule ) {
1093
    if ($rule) {
1092
        return $rule->delay1 if $rule->debarred1;
1094
        return $rule->delay1 if $rule->debarred1;
1093
        return $rule->delay2 if $rule->debarred2;
1095
        return $rule->delay2 if $rule->debarred2;
1094
        return $rule->delay3 if $rule->debarred3;
1096
        return $rule->delay3 if $rule->debarred3;
1095
    }
1097
    }
1096
}
1098
}
1097
1099
1100
1098
=head3 track_login
1101
=head3 track_login
1099
1102
1100
    $patron->track_login;
1103
    $patron->track_login;
(-)a/installer/data/mysql/atomicupdate/bug_29145-modify_AutoRemoveOverduesRestrictions-syspref.pl (-5 / +8 lines)
Lines 1-13 Link Here
1
use Modern::Perl;
1
use Modern::Perl;
2
2
3
return {
3
return {
4
    bug_number => "29145",
4
    bug_number  => "29145",
5
    description => "Change type of AutoRemoveOverduesRestrictions system preference",
5
    description => "Change type of AutoRemoveOverduesRestrictions system preference",
6
    up => sub {
6
    up          => sub {
7
        my ($args) = @_;
7
        my ($args) = @_;
8
        my ($dbh, $out) = @$args{qw(dbh out)};
8
        my ( $dbh, $out ) = @$args{qw(dbh out)};
9
9
        # Do you stuffs here
10
        # Do you stuffs here
10
        $dbh->do(q{UPDATE `systempreferences` SET `type` = 'Choice', `options` = 'no|when_no_overdue|when_no_overdue_causing_debarment', `explanation` = 'Defines if and on what conditions OVERDUES debarments should automatically be lifted when overdue items are returned by the patron.', `value` = CASE `value` WHEN '1' THEN 'when_no_overdue' WHEN '0' THEN 'no' ELSE `value` END WHERE variable = 'AutoRemoveOverduesRestrictions'});
11
        $dbh->do(
12
            q{UPDATE `systempreferences` SET `type` = 'Choice', `options` = 'no|when_no_overdue|when_no_overdue_causing_debarment', `explanation` = 'Defines if and on what conditions OVERDUES debarments should automatically be lifted when overdue items are returned by the patron.', `value` = CASE `value` WHEN '1' THEN 'when_no_overdue' WHEN '0' THEN 'no' ELSE `value` END WHERE variable = 'AutoRemoveOverduesRestrictions'}
13
        );
11
        say $out "Type of AutoRemoveOverduesRestrictions system preference has been changed";
14
        say $out "Type of AutoRemoveOverduesRestrictions system preference has been changed";
12
    },
15
    },
13
}
16
    }
(-)a/t/db_dependent/Circulation/MarkIssueReturned.t (-26 / +42 lines)
Lines 177-188 subtest 'AutoRemoveOverduesRestrictions' => sub { Link Here
177
177
178
    $schema->storage->txn_begin;
178
    $schema->storage->txn_begin;
179
179
180
    my $dbh = C4::Context->dbh;
180
    my $dbh          = C4::Context->dbh;
181
    my $patron = $builder->build_object({ class => 'Koha::Patrons' });
181
    my $patron       = $builder->build_object( { class => 'Koha::Patrons' } );
182
    my $categorycode = $patron->categorycode;
182
    my $categorycode = $patron->categorycode;
183
    my $branchcode = $patron->branchcode;
183
    my $branchcode   = $patron->branchcode;
184
184
185
    $dbh->do(qq{
185
    $dbh->do(
186
        qq{
186
        INSERT INTO `overduerules` (
187
        INSERT INTO `overduerules` (
187
            `categorycode`,
188
            `categorycode`,
188
            `delay1`,
189
            `delay1`,
Lines 193-222 subtest 'AutoRemoveOverduesRestrictions' => sub { Link Here
193
            `debarred2`
194
            `debarred2`
194
        )
195
        )
195
        VALUES ('$categorycode', 6, 'ODUE', 0, 10, 'ODUE2', 1)
196
        VALUES ('$categorycode', 6, 'ODUE', 0, 10, 'ODUE2', 1)
196
    });
197
    }
198
    );
197
199
198
    t::lib::Mocks::mock_preference('AutoRemoveOverduesRestrictions', 'when_no_overdue');
200
    t::lib::Mocks::mock_preference( 'AutoRemoveOverduesRestrictions', 'when_no_overdue' );
199
201
200
    t::lib::Mocks::mock_userenv( { branchcode => $branchcode } );
202
    t::lib::Mocks::mock_userenv( { branchcode => $branchcode } );
201
    my $item_1 = $builder->build_sample_item;
203
    my $item_1        = $builder->build_sample_item;
202
    my $item_2 = $builder->build_sample_item;
204
    my $item_2        = $builder->build_sample_item;
203
    my $item_3 = $builder->build_sample_item;
205
    my $item_3        = $builder->build_sample_item;
204
    my $nine_days_ago = dt_from_string->subtract( days => 9 ); #->set_hour(23)->set_minute(59);
206
    my $nine_days_ago = dt_from_string->subtract( days => 9 );    
205
    my $checkout_1 = AddIssue( $patron, $item_1->barcode, $nine_days_ago ); # overdue, but would not trigger debarment
207
    my $checkout_1 =
206
    my $checkout_2 = AddIssue( $patron, $item_2->barcode, $nine_days_ago ); # overdue, but would not trigger debarment
208
        AddIssue( $patron, $item_1->barcode, $nine_days_ago );    # overdue, but would not trigger debarment
207
    my $checkout_3 = AddIssue( $patron, $item_3->barcode ); # not overdue
209
    my $checkout_2 =
210
        AddIssue( $patron, $item_2->barcode, $nine_days_ago );    # overdue, but would not trigger debarment
211
    my $checkout_3 = AddIssue( $patron, $item_3->barcode );       # not overdue
212
208
213
209
    Koha::Patron::Debarments::AddUniqueDebarment(
214
    Koha::Patron::Debarments::AddUniqueDebarment(
210
        {
215
        {
211
            borrowernumber => $patron->borrowernumber,
216
            borrowernumber => $patron->borrowernumber,
212
            type           => 'OVERDUES',
217
            type           => 'OVERDUES',
213
            comment => "OVERDUES_PROCESS simulation",
218
            comment        => "OVERDUES_PROCESS simulation",
214
        }
219
        }
215
    );
220
    );
216
221
217
    C4::Circulation::MarkIssueReturned( $patron->borrowernumber, $item_1->itemnumber );
222
    C4::Circulation::MarkIssueReturned( $patron->borrowernumber, $item_1->itemnumber );
218
223
219
    my $restrictions = $patron->restrictions;
224
    my $restrictions    = $patron->restrictions;
220
    my $THE_restriction = $restrictions->next;
225
    my $THE_restriction = $restrictions->next;
221
    is( $THE_restriction->type->code, 'OVERDUES', 'OVERDUES debarment is not removed if patron still has overdues' );
226
    is( $THE_restriction->type->code, 'OVERDUES', 'OVERDUES debarment is not removed if patron still has overdues' );
222
227
Lines 225-249 subtest 'AutoRemoveOverduesRestrictions' => sub { Link Here
225
    $restrictions = $patron->restrictions;
230
    $restrictions = $patron->restrictions;
226
    is( $restrictions->count, 0, 'OVERDUES debarment is removed if patron does not have overdues' );
231
    is( $restrictions->count, 0, 'OVERDUES debarment is removed if patron does not have overdues' );
227
232
228
    t::lib::Mocks::mock_preference('AutoRemoveOverduesRestrictions', 'when_no_overdue_causing_debarment');
233
    t::lib::Mocks::mock_preference( 'AutoRemoveOverduesRestrictions', 'when_no_overdue_causing_debarment' );
229
234
230
    my $ten_days_ago = dt_from_string->subtract( days => 10 );
235
    my $ten_days_ago = dt_from_string->subtract( days => 10 );
231
236
232
    $checkout_1 = AddIssue( $patron->unblessed, $item_1->barcode, $ten_days_ago ); # overdue and would trigger debarment
237
    $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
238
    $checkout_2 =
239
        AddIssue( $patron->unblessed, $item_2->barcode, $nine_days_ago );    # overdue, but would not trigger debarment
234
240
235
    Koha::Patron::Debarments::AddUniqueDebarment(
241
    Koha::Patron::Debarments::AddUniqueDebarment(
236
        {
242
        {
237
            borrowernumber => $patron->borrowernumber,
243
            borrowernumber => $patron->borrowernumber,
238
            type           => 'OVERDUES',
244
            type           => 'OVERDUES',
239
            comment => "OVERDUES_PROCESS simulation",
245
            comment        => "OVERDUES_PROCESS simulation",
240
        }
246
        }
241
    );
247
    );
242
248
243
    C4::Circulation::MarkIssueReturned( $patron->borrowernumber, $item_1->itemnumber );
249
    C4::Circulation::MarkIssueReturned( $patron->borrowernumber, $item_1->itemnumber );
244
250
245
    $restrictions = $patron->restrictions;
251
    $restrictions = $patron->restrictions;
246
    is($restrictions->count, 0, 'OVERDUES debarment is removed if remaining items would not result in patron debarment' );
252
    is(
253
        $restrictions->count, 0,
254
        'OVERDUES debarment is removed if remaining items would not result in patron debarment'
255
    );
247
256
248
    $checkout_1 = AddIssue( $patron->unblessed, $item_1->barcode, $ten_days_ago ); # overdue and would trigger debarment
257
    $checkout_1 = AddIssue( $patron->unblessed, $item_1->barcode, $ten_days_ago ); # overdue and would trigger debarment
249
258
Lines 251-264 subtest 'AutoRemoveOverduesRestrictions' => sub { Link Here
251
        {
260
        {
252
            borrowernumber => $patron->borrowernumber,
261
            borrowernumber => $patron->borrowernumber,
253
            type           => 'OVERDUES',
262
            type           => 'OVERDUES',
254
            comment => "OVERDUES_PROCESS simulation",
263
            comment        => "OVERDUES_PROCESS simulation",
255
        }
264
        }
256
    );
265
    );
257
266
258
    C4::Circulation::MarkIssueReturned( $patron->borrowernumber, $item_2->itemnumber );
267
    C4::Circulation::MarkIssueReturned( $patron->borrowernumber, $item_2->itemnumber );
259
268
260
    $restrictions = $patron->restrictions->search({ type => 'OVERDUES' });
269
    $restrictions = $patron->restrictions->search( { type => 'OVERDUES' } );
261
    is( $restrictions->count, 1, 'OVERDUES debarment is not removed if patron still has overdues that would trigger debarment' );
270
    is(
271
        $restrictions->count, 1,
272
        'OVERDUES debarment is not removed if patron still has overdues that would trigger debarment'
273
    );
262
274
263
    my $eleven_days_ago = dt_from_string->subtract( days => 11 );
275
    my $eleven_days_ago = dt_from_string->subtract( days => 11 );
264
276
Lines 266-272 subtest 'AutoRemoveOverduesRestrictions' => sub { Link Here
266
    $checkout_2 = AddIssue( $patron->unblessed, $item_2->barcode, $eleven_days_ago );
278
    $checkout_2 = AddIssue( $patron->unblessed, $item_2->barcode, $eleven_days_ago );
267
279
268
    # $checkout_1 should now not trigger debarment with this new rule for specific branchcode
280
    # $checkout_1 should now not trigger debarment with this new rule for specific branchcode
269
    $dbh->do(qq{
281
    $dbh->do(
282
        qq{
270
        INSERT INTO `overduerules` (
283
        INSERT INTO `overduerules` (
271
            `branchcode`,
284
            `branchcode`,
272
            `categorycode`,
285
            `categorycode`,
Lines 278-289 subtest 'AutoRemoveOverduesRestrictions' => sub { Link Here
278
            `debarred2`
291
            `debarred2`
279
        )
292
        )
280
        VALUES ('$branchcode', '$categorycode', 6, 'ODUE', 0, 11, 'ODUE2', 1)
293
        VALUES ('$branchcode', '$categorycode', 6, 'ODUE', 0, 11, 'ODUE2', 1)
281
    });
294
    }
295
    );
282
296
283
    C4::Circulation::MarkIssueReturned( $patron->borrowernumber, $item_2->itemnumber );
297
    C4::Circulation::MarkIssueReturned( $patron->borrowernumber, $item_2->itemnumber );
284
298
285
    $restrictions = $patron->restrictions;
299
    $restrictions = $patron->restrictions;
286
    is( $restrictions->count, 0, 'OVERDUES debarment is removed if remaining items would not result in patron debarment' );
300
    is(
301
        $restrictions->count, 0,
302
        'OVERDUES debarment is removed if remaining items would not result in patron debarment'
303
    );
287
304
288
    $schema->storage->txn_rollback;
305
    $schema->storage->txn_rollback;
289
};
306
};
290
- 

Return to bug 29145