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

(-)a/Koha/Account/Line.pm (-1 / +49 lines)
Lines 285-290 sub void { Link Here
285
285
286
}
286
}
287
287
288
=head3 cancel
289
290
  $debit_accountline->cancel();
291
292
Cancel a charge. It will mark the debit as 'cancelled' by updating its
293
status to 'CANCELLED'.
294
Charges that have been fully or partially paid cannot be cancelled.
295
296
Return self in case of success, undef otherwise
297
298
=cut
299
300
sub cancel {
301
    my ($self) = @_;
302
303
    # Make sure it is a charge we are cancelling
304
    return unless $self->is_debit;
305
306
    # Make sure it is not already cancelled
307
    return if $self->status && $self->status eq 'CANCELLED';
308
309
    # Make sure it has not be paid yet
310
    return if $self->amount != $self->amountoutstanding;
311
312
    if ( C4::Context->preference("FinesLog") ) {
313
        logaction('FINES', 'CANCEL', $self->borrowernumber, Dumper({
314
            action => 'cancel_charge',
315
            borrowernumber => $self->borrowernumber,
316
            amount => $self->amount,
317
            amountoutstanding => $self->amountoutstanding,
318
            description => $self->description,
319
            debit_type_code => $self->debit_type_code,
320
            note => $self->note,
321
            itemnumber => $self->itemnumber,
322
            manager_id => $self->manager_id,
323
        }));
324
    }
325
326
    $self->set({
327
        status => 'CANCELLED',
328
        amountoutstanding => 0,
329
        amount => 0,
330
    });
331
    $self->store();
332
333
    return $self;
334
}
335
288
=head3 reduce
336
=head3 reduce
289
337
290
  $charge_accountline->reduce({
338
  $charge_accountline->reduce({
Lines 755-761 sub adjust { Link Here
755
sub is_credit {
803
sub is_credit {
756
    my ($self) = @_;
804
    my ($self) = @_;
757
805
758
    return ( $self->amount < 0 );
806
    return defined $self->credit_type_code;
759
}
807
}
760
808
761
=head3 is_debit
809
=head3 is_debit
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/accounts.inc (+1 lines)
Lines 55-60 Link Here
55
        [%- CASE 'FORGIVEN'   -%]<span> (Forgiven)</span>
55
        [%- CASE 'FORGIVEN'   -%]<span> (Forgiven)</span>
56
        [%- CASE 'VOID'       -%]<span> (Voided)</span>
56
        [%- CASE 'VOID'       -%]<span> (Voided)</span>
57
        [%- CASE 'LOST'       -%]<span> (Lost)</span>
57
        [%- CASE 'LOST'       -%]<span> (Lost)</span>
58
        [%- CASE 'CANCELLED'  -%]<span> (Cancelled)</span>
58
        [%- CASE              -%]
59
        [%- CASE              -%]
59
    [%- END -%]
60
    [%- END -%]
60
[%- END -%]
61
[%- END -%]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/boraccount.tt (-2 / +13 lines)
Lines 89-96 Link Here
89
        [% IF account.is_debit && account.amountoutstanding > 0 %]
89
        [% IF account.is_debit && account.amountoutstanding > 0 %]
90
            <a class="btn btn-default btn-xs" href="/cgi-bin/koha/members/paycollect.pl?borrowernumber=[% account.borrowernumber | html %]&pay_individual=1&debit_type_code=[% account.debit_type_code | html %]&amount=[% account.amount | html %]&amountoutstanding=[% account.amountoutstanding | html %]&description=[% account.description | html %]&itemnumber=[% account.itemnumber | html %]&accountlines_id=[% account.accountlines_id | html %]">Pay</a>
90
            <a class="btn btn-default btn-xs" href="/cgi-bin/koha/members/paycollect.pl?borrowernumber=[% account.borrowernumber | html %]&pay_individual=1&debit_type_code=[% account.debit_type_code | html %]&amount=[% account.amount | html %]&amountoutstanding=[% account.amountoutstanding | html %]&description=[% account.description | html %]&itemnumber=[% account.itemnumber | html %]&accountlines_id=[% account.accountlines_id | html %]">Pay</a>
91
        [% END %]
91
        [% END %]
92
        [% IF account.is_credit %]
92
        [% IF account.is_credit && account.status != 'VOID' %]
93
          <a href="boraccount.pl?action=void&amp;accountlines_id=[% account.accountlines_id | uri %]&amp;borrowernumber=[% account.borrowernumber | uri %]" class="btn btn-default btn-xs void"><i class="fa fa-ban"></i> Void</a>
93
          <a href="boraccount.pl?action=void&amp;accountlines_id=[% account.accountlines_id | uri %]&amp;borrowernumber=[% account.borrowernumber | uri %]" class="btn btn-default btn-xs void"><i class="fa fa-ban"></i> Void payment</a>
94
        [% END %]
95
        [% IF account.is_debit && account.amount == account.amountoutstanding && account.status != 'CANCELLED' %]
96
          <form method="post" action="/cgi-bin/koha/members/cancel-charge.pl">
97
            <input type="hidden" name="csrf_token" value="[% csrf_token | html %]">
98
            <input type="hidden" name="borrowernumber" value="[% patron.borrowernumber | html %]">
99
            <input type="hidden" name="accountlines_id" value="[% account.accountlines_id | html %]">
100
            <button type="submit" class="btn btn-default btn-xs">
101
                <i class="fa fa-ban"></i>
102
                Cancel charge
103
            </button>
104
          </form>
94
        [% END %]
105
        [% END %]
95
        [% IF CAN_user_updatecharges_payout && account.is_credit && ( account.amountoutstanding < 0 ) %]
106
        [% IF CAN_user_updatecharges_payout && account.is_credit && ( account.amountoutstanding < 0 ) %]
96
          <button type="button" data-toggle="modal" data-target="#issuePayoutModal" data-account="[%- PROCESS account_type_description account=account -%]" data-accountline="[% account.accountlines_id | html %]" data-amount="[% account.amountoutstanding | $Price %]" class="btn btn-default btn-xs"><i class="fa fa-money"></i> Issue payout</button>
107
          <button type="button" data-toggle="modal" data-target="#issuePayoutModal" data-account="[%- PROCESS account_type_description account=account -%]" data-accountline="[% account.accountlines_id | html %]" data-amount="[% account.amountoutstanding | $Price %]" class="btn btn-default btn-xs"><i class="fa fa-money"></i> Issue payout</button>
(-)a/members/boraccount.pl (+6 lines)
Lines 34-39 use Koha::Cash::Registers; Link Here
34
use Koha::Patrons;
34
use Koha::Patrons;
35
use Koha::Patron::Categories;
35
use Koha::Patron::Categories;
36
use Koha::Items;
36
use Koha::Items;
37
use Koha::Token;
37
38
38
my $input=new CGI;
39
my $input=new CGI;
39
40
Lines 202-207 foreach my $renew_result(@renew_results) { Link Here
202
    };
203
    };
203
}
204
}
204
205
206
my $csrf_token = Koha::Token->new->generate_csrf({
207
    session_id => scalar $input->cookie('CGISESSID'),
208
});
209
205
$template->param(
210
$template->param(
206
    patron              => $patron,
211
    patron              => $patron,
207
    finesview           => 1,
212
    finesview           => 1,
Lines 211-216 $template->param( Link Here
211
    payment_id          => $payment_id,
216
    payment_id          => $payment_id,
212
    change_given        => $change_given,
217
    change_given        => $change_given,
213
    renew_results       => $renew_results_display,
218
    renew_results       => $renew_results_display,
219
    csrf_token          => $csrf_token,
214
);
220
);
215
221
216
output_html_with_http_headers $input, $cookie, $template->output;
222
output_html_with_http_headers $input, $cookie, $template->output;
(-)a/members/cancel-charge.pl (+48 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use CGI;
21
22
use C4::Auth;
23
use Koha::Token;
24
25
my $cgi = CGI->new;
26
27
my $authnotrequired = 0;
28
my $flags = { updatecharges => 'remaining_permissions' };
29
my $type = 'intranet';
30
my ($user, $cookie) = C4::Auth::checkauth($cgi, $authnotrequired, $flags, $type);
31
32
my $csrf_token_is_valid = Koha::Token->new->check_csrf( {
33
    session_id => scalar $cgi->cookie('CGISESSID'),
34
    token  => scalar $cgi->param('csrf_token'),
35
});
36
unless ($csrf_token_is_valid) {
37
    print $cgi->header('text/plain', '403 Forbidden');
38
    print 'Wrong CSRF token';
39
    exit;
40
}
41
42
my $borrowernumber = $cgi->param('borrowernumber');
43
my $accountlines_id = $cgi->param('accountlines_id');
44
45
my $line = Koha::Account::Lines->find($accountlines_id);
46
$line->cancel();
47
48
print $cgi->redirect('/cgi-bin/koha/members/boraccount.pl?borrowernumber=' . $borrowernumber);
(-)a/t/db_dependent/Koha/Account/Line.t (-1 / +66 lines)
Lines 1076-1079 subtest "reduce() tests" => sub { Link Here
1076
    $schema->storage->txn_rollback;
1076
    $schema->storage->txn_rollback;
1077
};
1077
};
1078
1078
1079
subtest "cancel() tests" => sub {
1080
    plan tests => 9;
1081
1082
    $schema->storage->txn_begin;
1083
1084
    # Create a borrower
1085
    my $categorycode = $builder->build({ source => 'Category' })->{ categorycode };
1086
    my $branchcode   = $builder->build({ source => 'Branch' })->{ branchcode };
1087
1088
    my $borrower = Koha::Patron->new( {
1089
        cardnumber => 'dariahall',
1090
        surname => 'Hall',
1091
        firstname => 'Daria',
1092
    } );
1093
    $borrower->categorycode( $categorycode );
1094
    $borrower->branchcode( $branchcode );
1095
    $borrower->store;
1096
1097
    t::lib::Mocks::mock_userenv({ branchcode => $branchcode, borrowernumber => $borrower->borrowernumber });
1098
1099
    my $account = Koha::Account->new({ patron_id => $borrower->id });
1100
1101
    my $line1 = Koha::Account::Line->new(
1102
        {
1103
            borrowernumber    => $borrower->borrowernumber,
1104
            amount            => 10,
1105
            amountoutstanding => 10,
1106
            interface         => 'commandline',
1107
            debit_type_code   => 'OVERDUE',
1108
        }
1109
    )->store();
1110
    my $line2 = Koha::Account::Line->new(
1111
        {
1112
            borrowernumber    => $borrower->borrowernumber,
1113
            amount            => 20,
1114
            amountoutstanding => 20,
1115
            interface         => 'commandline',
1116
            debit_type_code   => 'OVERDUE',
1117
        }
1118
    )->store();
1119
1120
    my $id = $account->pay({
1121
        lines  => [$line2],
1122
        amount => 5,
1123
    });
1124
1125
    is( $account->balance(), 25, "Account balance is 25" );
1126
    is( $line1->amountoutstanding+0, 10, 'First fee has amount outstanding of 10' );
1127
    is( $line2->amountoutstanding+0, 15, 'Second fee has amount outstanding of 15' );
1128
1129
    my $ret = $line1->cancel();
1130
    is( ref($ret), 'Koha::Account::Line', 'Cancel returns the account line' );
1131
    is( $account->balance(), 15, "Account balance is 15" );
1132
    is( $line1->amount+0, 0, 'First fee has amount of 0' );
1133
    is( $line1->amountoutstanding+0, 0, 'First fee has amount outstanding of 0' );
1134
1135
    $ret = $line2->cancel();
1136
    is ($ret, undef, 'cancel returns undef when line cannot be cancelled');
1137
1138
    my $account_payment = Koha::Account::Lines->find($id);
1139
    $ret = $account_payment->cancel();
1140
    is ($ret, undef, 'payment cannot be cancelled');
1141
1142
    $schema->storage->txn_rollback;
1143
};
1144
1079
1;
1145
1;
1080
- 

Return to bug 24603