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

(-)a/Koha/Account.pm (+3 lines)
Lines 36-41 use Koha::Account::DebitTypes; Link Here
36
use Koha::Exceptions;
36
use Koha::Exceptions;
37
use Koha::Exceptions::Account;
37
use Koha::Exceptions::Account;
38
use Koha::Plugins;
38
use Koha::Plugins;
39
use Koha::Patron::Debarments;
39
40
40
=head1 NAME
41
=head1 NAME
41
42
Lines 102-107 sub pay { Link Here
102
        }
103
        }
103
    );
104
    );
104
105
106
    Koha::Patron::Debarments::del_restrictions_after_payment({ borrowernumber => $self->{patron_id} });
107
105
    # NOTE: Pay historically always applied as much credit as it could to all
108
    # NOTE: Pay historically always applied as much credit as it could to all
106
    # existing outstanding debits, whether passed specific debits or otherwise.
109
    # existing outstanding debits, whether passed specific debits or otherwise.
107
    if ( $payment->amountoutstanding ) {
110
    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 61-73 if ( $op eq 'add_form') { Link Here
61
        my $dupe = Koha::Patron::Restriction::Types->find({
63
        my $dupe = Koha::Patron::Restriction::Types->find({
62
            display_text => $display_text
64
            display_text => $display_text
63
        });
65
        });
64
        if ($dupe) {
66
        if ($dupe && $dupe->unblessed->{code} ne $code) {
65
            push @messages, {
67
            push @messages, {
66
                type => 'error', code => 'duplicate_display_text'
68
                type => 'error', code => 'duplicate_display_text'
67
            };
69
            };
68
        } else {
70
        } else {
69
            my $restriction = Koha::Patron::Restriction::Types->find($code);
71
            my $restriction = Koha::Patron::Restriction::Types->find($code);
70
            $restriction->display_text($display_text);
72
            $restriction->display_text($display_text);
73
            $restriction->lift_after_payment($lift_after_payment);
74
            $restriction->fee_limit($fee_limit);
71
            $restriction->store;
75
            $restriction->store;
72
            push @messages, { type => 'message', code => 'update_success' };
76
            push @messages, { type => 'message', code => 'update_success' };
73
        }
77
        }
Lines 81-87 if ( $op eq 'add_form') { Link Here
81
        } else {
85
        } else {
82
            my $restriction = Koha::Patron::Restriction::Type->new({
86
            my $restriction = Koha::Patron::Restriction::Type->new({
83
                code => $code,
87
                code => $code,
84
                display_text => $display_text
88
                display_text => $display_text,
89
                lift_after_payment => $lift_after_payment,
90
                fee_limit => $fee_limit
85
            });
91
            });
86
            $restriction->store;
92
            $restriction->store;
87
            push @messages, { type => 'message', code => 'add_success' };
93
            push @messages, { type => 'message', code => 'add_success' };
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/restrictions.tt (+34 lines)
Lines 117-122 Link Here
117
                        <input type="text" value="[% restriction.display_text | html %]" name="display_text" id="display_text" size="50" maxlength="50" class="required" required="required" />
117
                        <input type="text" value="[% restriction.display_text | html %]" name="display_text" id="display_text" size="50" maxlength="50" class="required" required="required" />
118
                        <span class="required">Required</span>
118
                        <span class="required">Required</span>
119
                    </li>
119
                    </li>
120
                    <li>
121
                        <label for="lift_after_payment" class="required">Lift after payment: </label>
122
                        <select type="text" name="lift_after_payment" id="lift_after_payment" class="required" required="required" />
123
                            <option value="1" selected="selected">Yes</option>
124
                            <option value="0">No</option>
125
                        </select>
126
                        <span class="required">Required</span>
127
                    </li>
128
                    <li>
129
                        <label for="fee_limit" class="required">Fee limit: </label>
130
                        <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" />
131
                        <span class="required">Required</span>
132
                    </li>
120
                [% ELSE %]
133
                [% ELSE %]
121
                    <li>
134
                    <li>
122
                        <label for="code" class="required">Code: </label>
135
                        <label for="code" class="required">Code: </label>
Lines 128-133 Link Here
128
                        <input type="text" name="display_text" id="display_text" size="50" maxlength="50" class="required" required="required" />
141
                        <input type="text" name="display_text" id="display_text" size="50" maxlength="50" class="required" required="required" />
129
                        <span class="required">Required</span>
142
                        <span class="required">Required</span>
130
                    </li>
143
                    </li>
144
                    <li>
145
                        <label for="lift_after_payment" class="required">Lift after payment: </label>
146
                        <select type="text" name="lift_after_payment" id="lift_after_payment" class="required" required="required" />
147
                            <option value="1" selected="selected">Yes</option>
148
                            <option value="0">No</option>
149
                        </select>
150
                        <span class="required">Required</span>
151
                    </li>
152
                    <li>
153
                        <label for="fee_limit" class="required">Fee limit: </label>
154
                        <input type="text" inputmode="decimal" pattern="^\d+(\.\d{2})?$" min="0" name="fee_limit" id="fee_limit" class="required" required="required" />
155
                        <span class="required">Required</span>
156
                    </li>
131
                [% END %]
157
                [% END %]
132
            </ol>
158
            </ol>
133
        </fieldset>
159
        </fieldset>
Lines 174-179 Link Here
174
                        <th scope="col">Code</th>
200
                        <th scope="col">Code</th>
175
                        <th scope="col">Label</th>
201
                        <th scope="col">Label</th>
176
                        <th scope="col">Default</th>
202
                        <th scope="col">Default</th>
203
                        <th scope="col">Lift after payment?</th>
204
                        <th scope="col">Fee limit</th>
177
                        <th scope="col">Actions</th>
205
                        <th scope="col">Actions</th>
178
                    </tr>
206
                    </tr>
179
                </thead>
207
                </thead>
Lines 189-194 Link Here
189
                            <td>
217
                            <td>
190
                                [% IF restriction.is_default %]Yes[% END %]
218
                                [% IF restriction.is_default %]Yes[% END %]
191
                            </td>
219
                            </td>
220
                            <td>
221
                                [% IF restriction.lift_after_payment %]Yes[% END %]
222
                            </td>
223
                            <td>
224
                                [% IF restriction.fee_limit %][% restriction.fee_limit %][% END %]
225
                            </td>
192
                            <td class="actions">
226
                            <td class="actions">
193
                                <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"></i> Edit</a>
227
                                <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"></i> Edit</a>
194
                                [% IF !restriction.is_system && !restriction.is_default %]
228
                                [% 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