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

(-)a/Koha/Account.pm (+3 lines)
Lines 39-44 use Koha::Account::DebitTypes; Link Here
39
use Koha::Exceptions;
39
use Koha::Exceptions;
40
use Koha::Exceptions::Account;
40
use Koha::Exceptions::Account;
41
use Koha::Plugins;
41
use Koha::Plugins;
42
use Koha::Patron::Debarments;
42
43
43
=head1 NAME
44
=head1 NAME
44
45
Lines 117-122 sub pay { Link Here
117
        }
118
        }
118
    );
119
    );
119
120
121
    Koha::Patron::Debarments::del_restrictions_after_payment({ borrowernumber => $self->{patron_id} });
122
120
    # NOTE: Pay historically always applied as much credit as it could to all
123
    # NOTE: Pay historically always applied as much credit as it could to all
121
    # existing outstanding debits, whether passed specific debits or otherwise.
124
    # existing outstanding debits, whether passed specific debits or otherwise.
122
    if ( $payment->amountoutstanding ) {
125
    if ( $payment->amountoutstanding ) {
(-)a/Koha/Patron/Debarments.pm (+38 lines)
Lines 21-26 use Modern::Perl; Link Here
21
21
22
use C4::Context;
22
use C4::Context;
23
23
24
use Koha::Patron::Restriction::Types;
25
24
our ( @ISA, @EXPORT_OK );
26
our ( @ISA, @EXPORT_OK );
25
27
26
BEGIN {
28
BEGIN {
Lines 270-275 sub UpdateBorrowerDebarmentFlags { Link Here
270
    return $dbh->do( "UPDATE borrowers SET debarred = ?, debarredcomment = ? WHERE borrowernumber = ?", {}, ( $expiration, $comment, $borrowernumber ) );
272
    return $dbh->do( "UPDATE borrowers SET debarred = ?, debarredcomment = ? WHERE borrowernumber = ?", {}, ( $expiration, $comment, $borrowernumber ) );
271
}
273
}
272
274
275
=head2 del_restrictions_after_payment
276
277
my $success = del_restrictions_after_payment({
278
    borrowernumber => $borrowernumber,
279
});
280
281
Deletes any restrictions from patron by following the rules
282
defined in "Patron restrictions".
283
284
=cut
285
286
sub del_restrictions_after_payment {
287
    my ($params) = @_;
288
289
    my $borrowernumber = $params->{'borrowernumber'};
290
    return unless ( $borrowernumber );
291
292
    my $patron_restrictions = GetDebarments( { borrowernumber => $borrowernumber } );
293
    return unless ( $patron_restrictions );
294
295
    my $patron = Koha::Patrons->find( $borrowernumber );
296
    return unless ( $patron );
297
298
    my $lines = Koha::Account::Lines->search({ borrowernumber  => $borrowernumber });
299
    my $total_due = $lines->total_outstanding;
300
301
    foreach my $patron_restriction (@{ $patron_restrictions }){
302
        my $restriction = Koha::Patron::Restriction::Types->find({
303
            code => $patron_restriction->{type}
304
        });
305
        if($restriction->lift_after_payment && $total_due <= $restriction->fee_limit){
306
            DelDebarment($patron_restriction->{'borrower_debarment_id'});
307
        }
308
    }
309
}
310
273
=head2 _GetBorrowernumberByDebarmentId
311
=head2 _GetBorrowernumberByDebarmentId
274
312
275
my $borrowernumber = _GetBorrowernumberByDebarmentId( $borrower_debarment_id );
313
my $borrowernumber = _GetBorrowernumberByDebarmentId( $borrower_debarment_id );
(-)a/admin/restrictions.pl (-2 / +8 lines)
Lines 54-59 if ( $op eq 'add_form') { Link Here
54
} elsif ( $op eq 'add_validate' ) {
54
} elsif ( $op eq 'add_validate' ) {
55
55
56
    my $display_text = $input->param('display_text');
56
    my $display_text = $input->param('display_text');
57
    my $lift_after_payment = $input->param('lift_after_payment');
58
    my $fee_limit = $input->param('fee_limit');
57
    my $is_a_modif = $input->param("is_a_modif");
59
    my $is_a_modif = $input->param("is_a_modif");
58
60
59
    if ($is_a_modif) {
61
    if ($is_a_modif) {
Lines 64-76 if ( $op eq 'add_form') { Link Here
64
                display_text => $display_text,
66
                display_text => $display_text,
65
            }
67
            }
66
        );
68
        );
67
        if ($dupe->count) {
69
        if ($dupe->count && $dupe->unblessed->{code} ne $code) {
68
            push @messages, {
70
            push @messages, {
69
                type => 'error', code => 'duplicate_display_text'
71
                type => 'error', code => 'duplicate_display_text'
70
            };
72
            };
71
        } else {
73
        } else {
72
            my $restriction = Koha::Patron::Restriction::Types->find($code);
74
            my $restriction = Koha::Patron::Restriction::Types->find($code);
73
            $restriction->display_text($display_text);
75
            $restriction->display_text($display_text);
76
            $restriction->lift_after_payment($lift_after_payment);
77
            $restriction->fee_limit($fee_limit);
74
            $restriction->store;
78
            $restriction->store;
75
            push @messages, { type => 'message', code => 'update_success' };
79
            push @messages, { type => 'message', code => 'update_success' };
76
        }
80
        }
Lines 84-90 if ( $op eq 'add_form') { Link Here
84
        } else {
88
        } else {
85
            my $restriction = Koha::Patron::Restriction::Type->new({
89
            my $restriction = Koha::Patron::Restriction::Type->new({
86
                code => $code,
90
                code => $code,
87
                display_text => $display_text
91
                display_text => $display_text,
92
                lift_after_payment => $lift_after_payment,
93
                fee_limit => $fee_limit
88
            });
94
            });
89
            $restriction->store;
95
            $restriction->store;
90
            push @messages, { type => 'message', code => 'add_success' };
96
            push @messages, { type => 'message', code => 'add_success' };
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/restrictions.tt (+34 lines)
Lines 101-106 Link Here
101
                        <input type="text" value="[% restriction.display_text | html %]" name="display_text" id="display_text" size="50" maxlength="50" class="required" required="required" />
101
                        <input type="text" value="[% restriction.display_text | html %]" name="display_text" id="display_text" size="50" maxlength="50" class="required" required="required" />
102
                        <span class="required">Required</span>
102
                        <span class="required">Required</span>
103
                    </li>
103
                    </li>
104
                    <li>
105
                        <label for="lift_after_payment" class="required">Lift after payment: </label>
106
                        <select type="text" name="lift_after_payment" id="lift_after_payment" class="required" required="required" />
107
                            <option value="1" selected="selected">Yes</option>
108
                            <option value="0">No</option>
109
                        </select>
110
                        <span class="required">Required</span>
111
                    </li>
112
                    <li>
113
                        <label for="fee_limit" class="required">Fee limit: </label>
114
                        <input type="text" value="[% restriction.fee_limit | html %]" inputmode="decimal" pattern="^\d+(\.\d{2})?$" min="0" name="fee_limit" id="fee_limit" class="required" required="required" />
115
                        <span class="required">Required</span>
116
                    </li>
104
                [% ELSE %]
117
                [% ELSE %]
105
                    <li>
118
                    <li>
106
                        <label for="code" class="required">Code: </label>
119
                        <label for="code" class="required">Code: </label>
Lines 112-117 Link Here
112
                        <input type="text" name="display_text" id="display_text" size="50" maxlength="50" class="required" required="required" />
125
                        <input type="text" name="display_text" id="display_text" size="50" maxlength="50" class="required" required="required" />
113
                        <span class="required">Required</span>
126
                        <span class="required">Required</span>
114
                    </li>
127
                    </li>
128
                    <li>
129
                        <label for="lift_after_payment" class="required">Lift after payment: </label>
130
                        <select type="text" name="lift_after_payment" id="lift_after_payment" class="required" required="required" />
131
                            <option value="1" selected="selected">Yes</option>
132
                            <option value="0">No</option>
133
                        </select>
134
                        <span class="required">Required</span>
135
                    </li>
136
                    <li>
137
                        <label for="fee_limit" class="required">Fee limit: </label>
138
                        <input type="text" inputmode="decimal" pattern="^\d+(\.\d{2})?$" min="0" name="fee_limit" id="fee_limit" class="required" required="required" />
139
                        <span class="required">Required</span>
140
                    </li>
115
                [% END %]
141
                [% END %]
116
            </ol>
142
            </ol>
117
        </fieldset>
143
        </fieldset>
Lines 158-163 Link Here
158
                        <th scope="col">Code</th>
184
                        <th scope="col">Code</th>
159
                        <th scope="col">Label</th>
185
                        <th scope="col">Label</th>
160
                        <th scope="col">Default</th>
186
                        <th scope="col">Default</th>
187
                        <th scope="col">Lift after payment?</th>
188
                        <th scope="col">Fee limit</th>
161
                        <th scope="col">Actions</th>
189
                        <th scope="col">Actions</th>
162
                    </tr>
190
                    </tr>
163
                </thead>
191
                </thead>
Lines 173-178 Link Here
173
                            <td>
201
                            <td>
174
                                [% IF restriction.is_default %]Yes[% END %]
202
                                [% IF restriction.is_default %]Yes[% END %]
175
                            </td>
203
                            </td>
204
                            <td>
205
                                [% IF restriction.lift_after_payment %]Yes[% END %]
206
                            </td>
207
                            <td>
208
                                [% IF restriction.fee_limit %][% restriction.fee_limit %][% END %]
209
                            </td>
176
                            <td class="actions">
210
                            <td class="actions">
177
                                <a class="btn btn-default btn-xs" href="/cgi-bin/koha/admin/restrictions.pl?op=add_form&amp;code=[% restriction.code | uri %]"><i class="fa fa-pencil-alt"></i> Edit</a>
211
                                <a class="btn btn-default btn-xs" href="/cgi-bin/koha/admin/restrictions.pl?op=add_form&amp;code=[% restriction.code | uri %]"><i class="fa fa-pencil-alt"></i> Edit</a>
178
                                [% IF !restriction.is_system && !restriction.is_default %]
212
                                [% IF !restriction.is_system && !restriction.is_default %]
(-)a/koha-tmpl/intranet-tmpl/prog/js/restrictiontypes.js (-1 / +2 lines)
Lines 9-15 jQuery.validator.addMethod( "restrictionDisplayText", function(value){ Link Here
9
    var ex = Object.values(existing).map(function(el) {
9
    var ex = Object.values(existing).map(function(el) {
10
        return el.toLowerCase();
10
        return el.toLowerCase();
11
    });
11
    });
12
    return (value.length > 0 && ex.indexOf(value.toLowerCase()) > -1) ?
12
    var code = $('input[name="code"]').val();
13
    return (value.length > 0 && ex.indexOf(value.toLowerCase()) > -1) && existing[code] != value ?
13
        false :
14
        false :
14
        true;
15
        true;
15
}, MSG_DUPLICATE_DISPLAY_TEXT);
16
}, MSG_DUPLICATE_DISPLAY_TEXT);
(-)a/t/db_dependent/Patron/Borrower_Debarments.t (-2 / +75 lines)
Lines 5-14 use Modern::Perl; Link Here
5
use C4::Context;
5
use C4::Context;
6
use Koha::Database;
6
use Koha::Database;
7
use Koha::Patrons;
7
use Koha::Patrons;
8
use Koha::Account;
8
9
9
use t::lib::TestBuilder;
10
use t::lib::TestBuilder;
10
11
11
use Test::More tests => 34;
12
use Test::More tests => 38;
12
13
13
use_ok('Koha::Patron::Debarments');
14
use_ok('Koha::Patron::Debarments');
14
15
Lines 221-223 is( Koha::Patrons->find($borrowernumber3)->debarred, Link Here
221
    $debarreddate2, 'Koha::Patron->merge_with() transfers well debarred' );
222
    $debarreddate2, 'Koha::Patron->merge_with() transfers well debarred' );
222
is( Koha::Patrons->find($borrowernumber3)->debarredcomment,
223
is( Koha::Patrons->find($borrowernumber3)->debarredcomment,
223
    $debarredcomment2, 'Koha::Patron->merge_with() transfers well debarredcomment' );
224
    $debarredcomment2, 'Koha::Patron->merge_with() transfers well debarredcomment' );
224
- 
225
226
# Test removing debartments after payment
227
$builder->build(
228
    {
229
        source => 'RestrictionType',
230
        value  => {
231
            code               => 'TEST',
232
            display_text       => 'This is a test.',
233
            is_system          => 0,
234
            is_default         => 0,
235
            lift_after_payment => 1,
236
            fee_limit          => 5
237
        }
238
    }
239
);
240
241
$builder->build(
242
    {
243
        source => 'RestrictionType',
244
        value  => {
245
            code               => 'TEST2',
246
            display_text       => 'This too is a test.',
247
            is_system          => 0,
248
            is_default         => 0,
249
            lift_after_payment => 1,
250
            fee_limit          => 0
251
        }
252
    }
253
);
254
255
my $borrowernumber4 = Koha::Patron->new(
256
    {
257
        firstname    => 'First',
258
        surname      => 'Sur',
259
        categorycode => $patron_category->{categorycode},
260
        branchcode   => $library->{branchcode},
261
    }
262
)->store->borrowernumber;
263
264
my $account = Koha::Account->new({ patron_id => $borrowernumber4 });
265
my $line1 = $account->add_debit({ type => 'ACCOUNT', amount => 10, interface => 'commandline' });
266
267
Koha::Patron::Debarments::AddDebarment(
268
    {
269
        borrowernumber => $borrowernumber4,
270
        expiration     => '9999-06-10',
271
        type           => 'TEST',
272
        comment        => 'Test delete'
273
    }
274
);
275
276
Koha::Patron::Debarments::AddDebarment(
277
    {
278
        borrowernumber => $borrowernumber4,
279
        expiration     => '9999-10-10',
280
        type           => 'TEST2',
281
        comment        => 'Test delete again',
282
    }
283
);
284
285
$debarments = Koha::Patron::Debarments::GetDebarments({ borrowernumber => $borrowernumber4 });
286
287
is( @$debarments, 2, "GetDebarments returns 2 debarments before payment" );
288
289
$account->pay({amount => 5});
290
291
$debarments = Koha::Patron::Debarments::GetDebarments({ borrowernumber => $borrowernumber4 });
292
is( @$debarments, 1, "GetDebarments returns 1 debarment after paying half of the fee" );
293
is( @$debarments[0]->{type}, "TEST2", "Debarment left has type value 'TEST2'" );
294
295
$account->pay({amount => 5});
296
$debarments = Koha::Patron::Debarments::GetDebarments({ borrowernumber => $borrowernumber4 });
297
is( @$debarments, 0, "GetDebarments returns 0 debarments after paying all fees" );

Return to bug 16223