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

(-)a/Koha/Account/Line.pm (-1 / +49 lines)
Lines 271-276 sub void { Link Here
271
271
272
}
272
}
273
273
274
=head3 cancel
275
276
  $debit_accountline->cancel();
277
278
Cancel a charge. It will mark the debit as 'cancelled' by updating its
279
status to 'CANCELLED'.
280
Charges that have been fully or partially paid cannot be cancelled.
281
282
Return self in case of success, undef otherwise
283
284
=cut
285
286
sub cancel {
287
    my ($self) = @_;
288
289
    # Make sure it is a charge we are cancelling
290
    return unless $self->is_debit;
291
292
    # Make sure it is not already cancelled
293
    return if $self->status && $self->status eq 'CANCELLED';
294
295
    # Make sure it has not be paid yet
296
    return if $self->amount != $self->amountoutstanding;
297
298
    if ( C4::Context->preference("FinesLog") ) {
299
        logaction('FINES', 'CANCEL', $self->borrowernumber, Dumper({
300
            action => 'cancel_charge',
301
            borrowernumber => $self->borrowernumber,
302
            amount => $self->amount,
303
            amountoutstanding => $self->amountoutstanding,
304
            description => $self->description,
305
            debit_type_code => $self->debit_type_code,
306
            note => $self->note,
307
            itemnumber => $self->itemnumber,
308
            manager_id => $self->manager_id,
309
        }));
310
    }
311
312
    $self->set({
313
        status => 'CANCELLED',
314
        amountoutstanding => 0,
315
        amount => 0,
316
    });
317
    $self->store();
318
319
    return $self;
320
}
321
274
=head3 reduce
322
=head3 reduce
275
323
276
  $charge_accountline->reduce({
324
  $charge_accountline->reduce({
Lines 733-739 sub adjust { Link Here
733
sub is_credit {
781
sub is_credit {
734
    my ($self) = @_;
782
    my ($self) = @_;
735
783
736
    return ( $self->amount < 0 );
784
    return defined $self->credit_type_code;
737
}
785
}
738
786
739
=head3 is_debit
787
=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 82-89 Link Here
82
          <a target="_blank" href="printinvoice.pl?action=print&amp;accountlines_id=[% account.accountlines_id | uri %]&amp;borrowernumber=[% account.borrowernumber | uri %]" class="btn btn-default btn-xs"><i class="fa fa-print"></i> Print</a>
82
          <a target="_blank" href="printinvoice.pl?action=print&amp;accountlines_id=[% account.accountlines_id | uri %]&amp;borrowernumber=[% account.borrowernumber | uri %]" class="btn btn-default btn-xs"><i class="fa fa-print"></i> Print</a>
83
        [% END %]
83
        [% END %]
84
        <a href="accountline-details.pl?accountlines_id=[% account.accountlines_id | uri %]" class="btn btn-default btn-xs"><i class="fa fa-list"></i> Details</a>
84
        <a href="accountline-details.pl?accountlines_id=[% account.accountlines_id | uri %]" class="btn btn-default btn-xs"><i class="fa fa-list"></i> Details</a>
85
        [% IF account.is_credit %]
85
        [% IF account.is_credit && account.status != 'VOID' %]
86
          <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>
86
          <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>
87
        [% END %]
88
        [% IF account.is_debit && account.amount == account.amountoutstanding && account.status != 'CANCELLED' %]
89
          <form method="post" action="/cgi-bin/koha/members/cancel-charge.pl">
90
            <input type="hidden" name="csrf_token" value="[% csrf_token | html %]">
91
            <input type="hidden" name="borrowernumber" value="[% patron.borrowernumber | html %]">
92
            <input type="hidden" name="accountlines_id" value="[% account.accountlines_id | html %]">
93
            <button type="submit" class="btn btn-default btn-xs">
94
                <i class="fa fa-ban"></i>
95
                Cancel charge
96
            </button>
97
          </form>
87
        [% END %]
98
        [% END %]
88
        [% IF CAN_user_updatecharges_payout && account.is_credit && ( account.amountoutstanding < 0 ) %]
99
        [% IF CAN_user_updatecharges_payout && account.is_credit && ( account.amountoutstanding < 0 ) %]
89
          <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>
100
          <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 203-208 foreach my $renew_result(@renew_results) { Link Here
203
    };
204
    };
204
}
205
}
205
206
207
my $csrf_token = Koha::Token->new->generate_csrf({
208
    session_id => scalar $input->cookie('CGISESSID'),
209
});
210
206
$template->param(
211
$template->param(
207
    patron              => $patron,
212
    patron              => $patron,
208
    finesview           => 1,
213
    finesview           => 1,
Lines 212-217 $template->param( Link Here
212
    payment_id          => $payment_id,
217
    payment_id          => $payment_id,
213
    change_given        => $change_given,
218
    change_given        => $change_given,
214
    renew_results       => $renew_results_display,
219
    renew_results       => $renew_results_display,
220
    csrf_token          => $csrf_token,
215
);
221
);
216
222
217
output_html_with_http_headers $input, $cookie, $template->output;
223
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 (-2 / +67 lines)
Lines 19-25 Link Here
19
19
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use Test::More tests => 12;
22
use Test::More tests => 13;
23
use Test::Exception;
23
use Test::Exception;
24
use Test::MockModule;
24
use Test::MockModule;
25
25
Lines 1037-1040 subtest "reduce() tests" => sub { Link Here
1037
    $schema->storage->txn_rollback;
1037
    $schema->storage->txn_rollback;
1038
};
1038
};
1039
1039
1040
subtest "cancel() tests" => sub {
1041
    plan tests => 9;
1042
1043
    $schema->storage->txn_begin;
1044
1045
    # Create a borrower
1046
    my $categorycode = $builder->build({ source => 'Category' })->{ categorycode };
1047
    my $branchcode   = $builder->build({ source => 'Branch' })->{ branchcode };
1048
1049
    my $borrower = Koha::Patron->new( {
1050
        cardnumber => 'dariahall',
1051
        surname => 'Hall',
1052
        firstname => 'Daria',
1053
    } );
1054
    $borrower->categorycode( $categorycode );
1055
    $borrower->branchcode( $branchcode );
1056
    $borrower->store;
1057
1058
    t::lib::Mocks::mock_userenv({ branchcode => $branchcode, borrowernumber => $borrower->borrowernumber });
1059
1060
    my $account = Koha::Account->new({ patron_id => $borrower->id });
1061
1062
    my $line1 = Koha::Account::Line->new(
1063
        {
1064
            borrowernumber    => $borrower->borrowernumber,
1065
            amount            => 10,
1066
            amountoutstanding => 10,
1067
            interface         => 'commandline',
1068
            debit_type_code   => 'OVERDUE',
1069
        }
1070
    )->store();
1071
    my $line2 = Koha::Account::Line->new(
1072
        {
1073
            borrowernumber    => $borrower->borrowernumber,
1074
            amount            => 20,
1075
            amountoutstanding => 20,
1076
            interface         => 'commandline',
1077
            debit_type_code   => 'OVERDUE',
1078
        }
1079
    )->store();
1080
1081
    my $id = $account->pay({
1082
        lines  => [$line2],
1083
        amount => 5,
1084
    });
1085
1086
    is( $account->balance(), 25, "Account balance is 25" );
1087
    is( $line1->amountoutstanding+0, 10, 'First fee has amount outstanding of 10' );
1088
    is( $line2->amountoutstanding+0, 15, 'Second fee has amount outstanding of 15' );
1089
1090
    my $ret = $line1->cancel();
1091
    is( ref($ret), 'Koha::Account::Line', 'Cancel returns the account line' );
1092
    is( $account->balance(), 15, "Account balance is 15" );
1093
    is( $line1->amount+0, 0, 'First fee has amount of 0' );
1094
    is( $line1->amountoutstanding+0, 0, 'First fee has amount outstanding of 0' );
1095
1096
    $ret = $line2->cancel();
1097
    is ($ret, undef, 'cancel returns undef when line cannot be cancelled');
1098
1099
    my $account_payment = Koha::Account::Lines->find($id);
1100
    $ret = $account_payment->cancel();
1101
    is ($ret, undef, 'payment cannot be cancelled');
1102
1103
    $schema->storage->txn_rollback;
1104
};
1105
1040
1;
1106
1;
1041
- 

Return to bug 24603