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

(-)a/C4/SIP/ILS.pm (-2 / +6 lines)
Lines 271-280 sub pay_fee { Link Here
271
        $trans->screen_msg('Invalid patron barcode.');
271
        $trans->screen_msg('Invalid patron barcode.');
272
        return $trans;
272
        return $trans;
273
    }
273
    }
274
    my $ok = $trans->pay( $patron->{borrowernumber}, $fee_amt, $pay_type, $fee_id, $is_writeoff, $disallow_overpayment );
274
    my $trans_result = $trans->pay( $patron->{borrowernumber}, $fee_amt, $pay_type, $fee_id, $is_writeoff, $disallow_overpayment );
275
    my $ok = $trans_result->{ok};
275
    $trans->ok($ok);
276
    $trans->ok($ok);
276
277
277
    return $trans;
278
    return {
279
        status       => $trans,
280
        pay_response => $trans_result->{pay_response}
281
    };
278
}
282
}
279
283
280
sub add_hold {
284
sub add_hold {
(-)a/C4/SIP/ILS/Transaction/FeePayment.pm (-6 / +14 lines)
Lines 57-69 sub pay { Link Here
57
    my $account = Koha::Account->new( { patron_id => $borrowernumber } );
57
    my $account = Koha::Account->new( { patron_id => $borrowernumber } );
58
58
59
    if ($disallow_overpayment) {
59
    if ($disallow_overpayment) {
60
        return 0 if $account->balance < $amt;
60
        return { ok => 0 } if $account->balance < $amt;
61
    }
61
    }
62
62
63
    if ($fee_id) {
63
    if ($fee_id) {
64
        my $fee = Koha::Account::Lines->find($fee_id);
64
        my $fee = Koha::Account::Lines->find($fee_id);
65
        if ( $fee ) {
65
        if ( $fee ) {
66
            $account->pay(
66
            my $pay_response = $account->pay(
67
                {
67
                {
68
                    amount       => $amt,
68
                    amount       => $amt,
69
                    type         => $type,
69
                    type         => $type,
Lines 72-85 sub pay { Link Here
72
                    interface    => C4::Context->interface
72
                    interface    => C4::Context->interface
73
                }
73
                }
74
            );
74
            );
75
            return 1;
75
            return {
76
                ok           => 1,
77
                pay_response => $pay_response
78
            };
76
        }
79
        }
77
        else {
80
        else {
78
            return 0;
81
            return {
82
                ok => 0
83
            };
79
        }
84
        }
80
    }
85
    }
81
    else {
86
    else {
82
        $account->pay(
87
        my $pay_response = $account->pay(
83
            {
88
            {
84
                amount       => $amt,
89
                amount       => $amt,
85
                type         => $type,
90
                type         => $type,
Lines 87-93 sub pay { Link Here
87
                interface    => C4::Context->interface
92
                interface    => C4::Context->interface
88
            }
93
            }
89
        );
94
        );
90
        return 1;
95
        return {
96
            ok           => 1,
97
            pay_response => $pay_response
98
        };
91
    }
99
    }
92
}
100
}
93
101
(-)a/C4/SIP/Sip/MsgType.pm (-1 / +41 lines)
Lines 20-25 use CGI qw ( -utf8 ); Link Here
20
use C4::Auth qw(&check_api_auth);
20
use C4::Auth qw(&check_api_auth);
21
21
22
use Koha::Patron::Attributes;
22
use Koha::Patron::Attributes;
23
use Koha::Items;
23
24
24
use UNIVERSAL::can;
25
use UNIVERSAL::can;
25
26
Lines 1103-1109 sub handle_fee_paid { Link Here
1103
1104
1104
    $ils->check_inst_id( $inst_id, "handle_fee_paid" );
1105
    $ils->check_inst_id( $inst_id, "handle_fee_paid" );
1105
1106
1106
    $status = $ils->pay_fee( $patron_id, $patron_pwd, $fee_amt, $fee_type, $pay_type, $fee_id, $trans_id, $currency, $is_writeoff, $disallow_overpayment );
1107
    my $pay_result = $ils->pay_fee( $patron_id, $patron_pwd, $fee_amt, $fee_type, $pay_type, $fee_id, $trans_id, $currency, $is_writeoff, $disallow_overpayment );
1108
    $status = $pay_result->{status};
1109
    my $pay_response = $pay_result->{pay_response};
1110
1111
    my $failmap = {
1112
        "no_item" => "No matching item could be found",
1113
        "no_checkout" => "Item is not checked out",
1114
        "too_soon" => "Cannot yet be renewed",
1115
        "too_many" => "Renewed the maximum number of times",
1116
        "auto_too_soon" => "Scheduled for automatic renewal and cannot yet be renewed",
1117
        "auto_too_late" => "Scheduled for automatic renewal and cannot yet be any more",
1118
        "auto_account_expired" => "Scheduled for automatic renewal and cannot be renewed because the patron's account has expired",
1119
        "auto_renew" => "Scheduled for automatic renewal",
1120
        "auto_too_much_oweing" => "Scheduled for automatic renewal",
1121
        "on_reserve" => "On hold for another patron",
1122
        "patron_restricted" => "Patron is currently restricted",
1123
        "item_denied_renewal" => "Item is not allowed renewal",
1124
        "onsite_checkout" => "Item is an onsite checkout"
1125
    };
1126
    my @success = ();
1127
    my @fail = ();
1128
    foreach my $result( @{$pay_response->{renew_result}} ) {
1129
        my $item = Koha::Items->find({ itemnumber => $result->{itemnumber} });
1130
        if ($result->{success}) {
1131
            push @success, '"' . $item->biblio->title . '"';
1132
        } else {
1133
            push @fail, '"' . $item->biblio->title . '" : ' . $failmap->{$result->{error}};
1134
        }
1135
    }
1136
1137
    my $msg = "";
1138
    if (scalar @success > 0) {
1139
        $msg.="The following items were renewed: " . join(", ", @success) . ". ";
1140
    }
1141
    if (scalar @fail > 0) {
1142
        $msg.="The following items were not renewed: " . join(", ", @fail) . ".";
1143
    }
1144
    if (length $msg > 0) {
1145
        $status->screen_msg($status->screen_msg . " $msg");
1146
    }
1107
1147
1108
    $resp .= ( $status->ok ? 'Y' : 'N' ) . timestamp;
1148
    $resp .= ( $status->ok ? 'Y' : 'N' ) . timestamp;
1109
    $resp .= add_field( FID_INST_ID,   $inst_id, $server );
1149
    $resp .= add_field( FID_INST_ID,   $inst_id, $server );
(-)a/Koha/Account.pm (-53 / +17 lines)
Lines 96-105 sub pay { Link Here
96
        && !defined($cash_register) );
96
        && !defined($cash_register) );
97
97
98
    my @fines_paid; # List of account lines paid on with this payment
98
    my @fines_paid; # List of account lines paid on with this payment
99
    # Item numbers that have had a fine paid where the line has a accounttype
99
100
    # of OVERDUE and a status of UNRETURNED. We might want to try and renew
100
    # The outcome of any attempted item renewals as a result of fines being
101
    # these items.
101
    # paid off
102
    my $overdue_unreturned = {};
102
    my $renew_outcomes = [];
103
103
104
    my $balance_remaining = $amount; # Set it now so we can adjust the amount if necessary
104
    my $balance_remaining = $amount; # Set it now so we can adjust the amount if necessary
105
    $balance_remaining ||= 0;
105
    $balance_remaining ||= 0;
Lines 118-133 sub pay { Link Here
118
        $fine->amountoutstanding($new_amountoutstanding)->store();
118
        $fine->amountoutstanding($new_amountoutstanding)->store();
119
        $balance_remaining = $balance_remaining - $amount_to_pay;
119
        $balance_remaining = $balance_remaining - $amount_to_pay;
120
120
121
        # If we need to make a note of the item associated with this line,
121
        # Attempt to renew the item associated with this debit if
122
        # in order that we can potentially renew it, do so.
122
        # appropriate
123
        if (
123
        if ($fine->renewable) {
124
            $new_amountoutstanding == 0 &&
124
            # We're ignoring the definition of $interface above, by all
125
            $fine->accounttype &&
125
            # accounts we can't rely on C4::Context::interface, so here
126
            $fine->accounttype eq 'OVERDUE' &&
126
            # we're only using what we've been explicitly passed
127
            $fine->status &&
127
            my $outcome = $fine->renew_item($params->{interface});
128
            $fine->status eq 'UNRETURNED'
128
            push @{$renew_outcomes}, $outcome if $outcome;
129
        ) {
130
            $overdue_unreturned->{$fine->itemnumber} = $fine;
131
        }
129
        }
132
130
133
        # Same logic exists in Koha::Account::Line::apply
131
        # Same logic exists in Koha::Account::Line::apply
Lines 192-205 sub pay { Link Here
192
190
193
        # If we need to make a note of the item associated with this line,
191
        # If we need to make a note of the item associated with this line,
194
        # in order that we can potentially renew it, do so.
192
        # in order that we can potentially renew it, do so.
195
        if (
193
        my $amt = $old_amountoutstanding - $amount_to_pay;
196
            $old_amountoutstanding - $amount_to_pay == 0 &&
194
        if ($fine->renewable) {
197
            $fine->accounttype &&
195
            my $outcome = $fine->renew_item;
198
            $fine->accounttype eq 'OVERDUE' &&
196
            push @{$renew_outcomes}, $outcome;
199
            $fine->status &&
200
            $fine->status eq 'UNRETURNED'
201
        ) {
202
            $overdue_unreturned->{$fine->itemnumber} = $fine;
203
        }
197
        }
204
198
205
        if (   $fine->amountoutstanding == 0
199
        if (   $fine->amountoutstanding == 0
Lines 282-317 sub pay { Link Here
282
        }
276
        }
283
    );
277
    );
284
278
285
    # If we have overdue unreturned items that have had payments made
286
    # against them, check whether the balance on those items is now zero
287
    # and, if the syspref is set, renew them
288
    # Same logic exists in Koha::Account::Line::apply
289
    if (
290
        C4::Context->preference('RenewAccruingItemWhenPaid') &&
291
        keys %{$overdue_unreturned}
292
    ) {
293
        foreach my $itemnumber (keys %{$overdue_unreturned}) {
294
            # Only do something if this item has no fines left on it
295
            my $fine = C4::Overdues::GetFine( $itemnumber, $self->{patron_id} );
296
            next if $fine && $fine > 0;
297
298
            my ( $renew_ok, $error ) =
299
                C4::Circulation::CanBookBeRenewed(
300
                    $self->{patron_id}, $itemnumber
301
                );
302
            if ( $renew_ok ) {
303
                C4::Circulation::AddRenewal(
304
                    $self->{patron_id},
305
                    $itemnumber,
306
                    $library_id,
307
                    undef,
308
                    undef,
309
                    1
310
                );
311
            }
312
        }
313
    }
314
315
    if ( C4::Context->preference("FinesLog") ) {
279
    if ( C4::Context->preference("FinesLog") ) {
316
        logaction(
280
        logaction(
317
            "FINES", 'CREATE',
281
            "FINES", 'CREATE',
Lines 359-365 sub pay { Link Here
359
        }
323
        }
360
    }
324
    }
361
325
362
    return $payment->id;
326
    return { payment_id => $payment->id, renew_result => $renew_outcomes };
363
}
327
}
364
328
365
=head3 add_credit
329
=head3 add_credit
(-)a/Koha/Account/Line.pm (-46 / +96 lines)
Lines 218-228 sub apply { Link Here
218
218
219
    my $schema = Koha::Database->new->schema;
219
    my $schema = Koha::Database->new->schema;
220
220
221
    # Item numbers that have had a fine paid where the line has a accounttype
222
    # of OVERDUE and a status of UNRETURNED. We might want to try and renew
223
    # these items.
224
    my $overdue_unreturned = {};
225
226
    $schema->txn_do( sub {
221
    $schema->txn_do( sub {
227
        for my $debit ( @{$debits} ) {
222
        for my $debit ( @{$debits} ) {
228
223
Lines 255-271 sub apply { Link Here
255
            $self->amountoutstanding( $available_credit * -1 )->store;
250
            $self->amountoutstanding( $available_credit * -1 )->store;
256
            $debit->amountoutstanding( $owed - $amount_to_cancel )->store;
251
            $debit->amountoutstanding( $owed - $amount_to_cancel )->store;
257
252
258
            # If we need to make a note of the item associated with this line,
253
            # Attempt to renew the item associated with this debit if
259
            # in order that we can potentially renew it, do so.
254
            # appropriate
260
            # Same logic existing in Koha::Account::pay
255
            if ($debit->renewable) {
261
            if (
256
                $debit->renew_item($params->{interface});
262
                $debit->amountoutstanding == 0 &&
263
                $debit->accounttype &&
264
                $debit->accounttype eq 'OVERDUE' &&
265
                $debit->status &&
266
                $debit->status eq 'UNRETURNED'
267
            ) {
268
                $overdue_unreturned->{$debit->itemnumber} = $debit;
269
            }
257
            }
270
258
271
            # Same logic exists in Koha::Account::pay
259
            # Same logic exists in Koha::Account::pay
Lines 280-315 sub apply { Link Here
280
        }
268
        }
281
    });
269
    });
282
270
283
    # If we have overdue unreturned items that have had payments made
284
    # against them, check whether the balance on those items is now zero
285
    # and, if the syspref is set, renew them
286
    # Same logic existing in Koha::Account::pay
287
    if (
288
        C4::Context->preference('RenewAccruingItemWhenPaid') &&
289
        keys %{$overdue_unreturned}
290
    ) {
291
        foreach my $itemnumber (keys %{$overdue_unreturned}) {
292
            # Only do something if this item has no fines left on it
293
            my $fine = C4::Overdues::GetFine( $itemnumber, $self->borrowernumber );
294
            next if $fine && $fine > 0;
295
296
            my ( $renew_ok, $error ) =
297
                C4::Circulation::CanBookBeRenewed(
298
                    $self->borrowernumber, $itemnumber
299
                );
300
            if ( $renew_ok ) {
301
                C4::Circulation::AddRenewal(
302
                    $self->borrowernumber,
303
                    $itemnumber,
304
                    $overdue_unreturned->{$itemnumber}->{branchcode},
305
                    undef,
306
                    undef,
307
                    1
308
                );
309
            }
310
        }
311
    }
312
313
    return $available_credit;
271
    return $available_credit;
314
}
272
}
315
273
Lines 481-486 sub to_api_mapping { Link Here
481
        manager_id        => 'user_id',
439
        manager_id        => 'user_id',
482
        note              => 'internal_note',
440
        note              => 'internal_note',
483
    };
441
    };
442
443
=head3 renewable
444
445
    my $bool = $line->renewable;
446
447
=cut
448
449
sub renewable {
450
    my ($self) = @_;
451
452
    return (
453
        $self->amountoutstanding == 0 &&
454
        $self->accounttype &&
455
        $self->accounttype eq 'OVERDUE' &&
456
        $self->status &&
457
        $self->status eq 'UNRETURNED'
458
    ) ? 1 : 0;
459
}
460
461
=head3 renew_item
462
463
    my $renew_result = $line->renew_item;
464
465
Conditionally attempt to renew an item and return the outcome. This is
466
as a consequence of the fine on an item being fully paid off
467
468
=cut
469
470
sub renew_item {
471
    my ($self, $params) = @_;
472
473
    my $outcome = {};
474
475
    # We want to reject the call to renew if any of these apply:
476
    # - The RenewAccruingItemWhenPaid syspref is off
477
    # - The line item doesn't have an item attached to it
478
    # - The line item doesn't have a patron attached to it
479
    #
480
    # - The RenewAccruingItemInOpac syspref is off
481
    # AND
482
    # - There is an interface param passed and it's value is 'opac'
483
484
    if (
485
        !C4::Context->preference('RenewAccruingItemWhenPaid') ||
486
        !$self->item ||
487
        !$self->patron ||
488
        (
489
            !C4::Context->preference('RenewAccruingItemInOpac') &&
490
            $params->{interface} &&
491
            $params->{interface} eq 'opac'
492
        )
493
    ) {
494
        return;
495
    }
496
497
    my $itemnumber = $self->item->itemnumber;
498
    my $borrowernumber = $self->patron->borrowernumber;
499
    # Only do something if this item has no fines left on it
500
    my $fine = C4::Overdues::GetFine($itemnumber, $borrowernumber);
501
    if ($fine && $fine > 0) {
502
        return {
503
            itemnumber => $itemnumber,
504
            error      => 'has_fine',
505
            success    => 0
506
        };
507
    }
508
    my ( $can_renew, $error ) = C4::Circulation::CanBookBeRenewed(
509
        $borrowernumber,
510
        $itemnumber
511
    );
512
    if ( $can_renew ) {
513
        my $due_date = C4::Circulation::AddRenewal(
514
            $borrowernumber,
515
            $itemnumber,
516
            $self->{branchcode},
517
            undef,
518
            undef,
519
            1
520
        );
521
        return {
522
            itemnumber => $itemnumber,
523
            due_date   => $due_date,
524
            success    => 1
525
        };
526
    } else {
527
        return {
528
            itemnumber => $itemnumber,
529
            error      => $error,
530
            success    => 0
531
        };
532
    }
533
484
}
534
}
485
535
486
=head2 Internal methods
536
=head2 Internal methods
(-)a/Koha/REST/V1/Patrons/Account.pm (-1 / +1 lines)
Lines 130-136 sub add_credit { Link Here
130
        my $outstanding_credit = $credit->amountoutstanding;
130
        my $outstanding_credit = $credit->amountoutstanding;
131
        if ($debits) {
131
        if ($debits) {
132
            # pay them!
132
            # pay them!
133
            $outstanding_credit = $credit->apply({ debits => [ $debits->as_list ], offset_type => 'payment' });
133
            $outstanding_credit = $credit->apply({ debits => [ $debits->as_list ], offset_type => 'payment' })->{outstanding_amount};
134
        }
134
        }
135
135
136
        if ($outstanding_credit) {
136
        if ($outstanding_credit) {
(-)a/installer/data/mysql/atomicupdate/bug_23051_add_RenewAccruingItemInOpac_syspref.perl (+8 lines)
Line 0 Link Here
1
$DBversion = 'XXX'; # will be replaced by the RM
2
if( CheckVersion( $DBversion ) ) {
3
4
    $dbh->do( q| INSERT IGNORE INTO systempreferences (variable, value, explanation, options, type) VALUES ('RenewAccruingItemInOpac', '0', 'If enabled, when the fines on an item accruing is paid off in the OPAC via a payment plugin, attempt to renew that item. If the syspref "RenewalPeriodBase" is set to "due date", renewed items may still be overdue', '', 'YesNo'); | );
5
6
    SetVersion( $DBversion );
7
    print "Upgrade to $DBversion done (Bug 23051 - Add RenewAccruingItemInOpac syspref)\n";
8
}
(-)a/installer/data/mysql/atomicupdate/bug_23051_add_RenewAccruingItemWhenPaid_syspref.perl (-1 / +1 lines)
Lines 1-7 Link Here
1
$DBversion = 'XXX'; # will be replaced by the RM
1
$DBversion = 'XXX'; # will be replaced by the RM
2
if( CheckVersion( $DBversion ) ) {
2
if( CheckVersion( $DBversion ) ) {
3
3
4
    $dbh->do( q| INSERT IGNORE INTO systempreferences (variable, value, explanation, options, type) VALUES ('RenewAccruingItemWhenPaid', '0', 'If enabled, when the fines on an item accruing is paid off, attempt to renew that item', '', 'YesNo'); | );
4
    $dbh->do( q| INSERT IGNORE INTO systempreferences (variable, value, explanation, options, type) VALUES ('RenewAccruingItemWhenPaid', '0', 'If enabled, when the fines on an item accruing is paid off, attempt to renew that item. If the syspref "RenewalPeriodBase" is set to "due date", renewed items may still be overdue', '', 'YesNo'); | );
5
5
6
    SetVersion( $DBversion );
6
    SetVersion( $DBversion );
7
    print "Upgrade to $DBversion done (Bug 23051 - Add RenewAccruingItemWhenPaid syspref)\n";
7
    print "Upgrade to $DBversion done (Bug 23051 - Add RenewAccruingItemWhenPaid syspref)\n";
(-)a/installer/data/mysql/sysprefs.sql (-1 / +2 lines)
Lines 513-519 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
513
('RandomizeHoldsQueueWeight','0',NULL,'if ON, the holds queue in circulation will be randomized, either based on all location codes, or by the location codes specified in StaticHoldsQueueWeight','YesNo'),
513
('RandomizeHoldsQueueWeight','0',NULL,'if ON, the holds queue in circulation will be randomized, either based on all location codes, or by the location codes specified in StaticHoldsQueueWeight','YesNo'),
514
('RecordLocalUseOnReturn','0',NULL,'If ON, statistically record returns of unissued items as local use, instead of return','YesNo'),
514
('RecordLocalUseOnReturn','0',NULL,'If ON, statistically record returns of unissued items as local use, instead of return','YesNo'),
515
('RefundLostOnReturnControl','CheckinLibrary','CheckinLibrary|ItemHomeBranch|ItemHoldingBranch','If a lost item is returned, choose which branch to pick rules for refunding.','Choice'),
515
('RefundLostOnReturnControl','CheckinLibrary','CheckinLibrary|ItemHomeBranch|ItemHoldingBranch','If a lost item is returned, choose which branch to pick rules for refunding.','Choice'),
516
('RenewAccruingItemWhenPaid','0','','If enabled, when the fines on an item accruing is paid off, attempt to renew that item','YesNo'),
516
('RenewAccruingItemWhenPaid','0','','If enabled, when the fines on an item accruing is paid off, attempt to renew that item. If the syspref "RenewalPeriodBase" is set to "due date", renewed items may still be overdue','YesNo'),
517
('RenewAccruingItemInOpac','0','','If enabled, when the fines on an item accruing is paid off in the OPAC via a payment plugin, attempt to renew that item. If the syspref "RenewalPeriodBase" is set to "due date", renewed items may still be overdue','YesNo'),
517
('RenewalLog','0','','If ON, log information about renewals','YesNo'),
518
('RenewalLog','0','','If ON, log information about renewals','YesNo'),
518
('RenewalPeriodBase','date_due','date_due|now','Set whether the renewal date should be counted from the date_due or from the moment the Patron asks for renewal ','Choice'),
519
('RenewalPeriodBase','date_due','date_due|now','Set whether the renewal date should be counted from the date_due or from the moment the Patron asks for renewal ','Choice'),
519
('RenewalSendNotice','0','',NULL,'YesNo'),
520
('RenewalSendNotice','0','',NULL,'YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/renew_results.inc (+12 lines)
Line 0 Link Here
1
[% IF renew_results && renew_results.size > 0 %]
2
    <div class="alert">
3
		The fines on the following items were paid off, renewal results are displayed below:
4
		[% FOREACH result IN renew_results %]
5
			[% IF result.success %]
6
				<p>[% INCLUDE 'biblio-title.inc' biblio=result.item.biblio %] ( [% result.item.barcode | html %] ): Renewed - due [% result.info | html %]</p>
7
			[% ELSE %]
8
				<p>[% INCLUDE 'biblio-title.inc' biblio=result.item.biblio %] ( [% result.item.barcode | html %] ): Not renewed - [% INCLUDE 'renew_strings.inc' error=result.info %]</p>
9
			[% END %]
10
		[% END %]
11
    </div>
12
[% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/renew_strings.inc (+32 lines)
Line 0 Link Here
1
[% SWITCH error %]
2
[% CASE 'no_item' %]
3
    No matching item could be found
4
[% CASE 'no_checkout' %]
5
    Item is not checked out
6
[% CASE 'too_soon' %]
7
    Cannot yet be renewed
8
[% CASE 'too_many' %]
9
    Renewed the maximum number of times
10
[% CASE 'auto_too_soon' %]
11
    Scheduled for automatic renewal and cannot yet be renewed
12
[% CASE 'auto_too_late' %]
13
    Scheduled for automatic renewal and cannot yet be any more
14
[% CASE 'auto_account_expired' %]
15
    Scheduled for automatic renewal and cannot be renewed because the patron's account has expired
16
[% CASE 'auto_renew' %]
17
    Scheduled for automatic renewal
18
[% CASE 'auto_too_much_oweing' %]
19
    Scheduled for automatic renewal
20
[% CASE 'on_reserve' %]
21
    On hold for another patron
22
[% CASE 'patron_restricted' %]
23
    Patron is currently restricted
24
[% CASE 'item_denied_renewal' %]
25
    Item is not allowed renewal
26
[% CASE 'onsite_checkout' %]
27
    Item is an onsite checkout
28
[% CASE 'has_fine' %]
29
    Item has an outstanding fine
30
[% CASE %]
31
    Unknown error
32
[% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (-1 / +8 lines)
Lines 491-497 Circulation: Link Here
491
              choices:
491
              choices:
492
                  yes: Renew
492
                  yes: Renew
493
                  no: "Don't renew"
493
                  no: "Don't renew"
494
            - the item automatically.
494
            - the item automatically. If the syspref "RenewalPeriodBase" is set to "due date", renewed items may still be overdue.
495
        -
496
            - If a patron pays off all fines on an overdue item that is accruing fines in the OPAC via a payment plugin
497
            - pref: RenewAccruingItemInOpac
498
              choices:
499
                  yes: Renew
500
                  no: "Don't renew"
501
            - the item automatically. If the syspref "RenewalPeriodBase" is set to "due date", renewed items may still be overdue.
495
        -
502
        -
496
            - pref: ItemsDeniedRenewal
503
            - pref: ItemsDeniedRenewal
497
              type: textarea
504
              type: textarea
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/boraccount.tt (+1 lines)
Lines 39-44 Link Here
39
    <li><a href="/cgi-bin/koha/members/mancredit.pl?borrowernumber=[% patron.borrowernumber | uri %]" >Create manual credit</a></li>
39
    <li><a href="/cgi-bin/koha/members/mancredit.pl?borrowernumber=[% patron.borrowernumber | uri %]" >Create manual credit</a></li>
40
</ul>
40
</ul>
41
<div class="tabs-container">
41
<div class="tabs-container">
42
[% INCLUDE 'renew_results.inc' renew_results=renew_results %]
42
<!-- The table with the account items -->
43
<!-- The table with the account items -->
43
<table id="table_account_fines">
44
<table id="table_account_fines">
44
    <thead>
45
    <thead>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/pay.tt (+1 lines)
Lines 40-45 Link Here
40
    <form action="/cgi-bin/koha/members/pay.pl" method="post" id="pay-fines-form">
40
    <form action="/cgi-bin/koha/members/pay.pl" method="post" id="pay-fines-form">
41
    <input type="hidden" name="borrowernumber" id="borrowernumber" value="[% patron.borrowernumber | html %]" />
41
    <input type="hidden" name="borrowernumber" id="borrowernumber" value="[% patron.borrowernumber | html %]" />
42
<p><span class="checkall"><a id="CheckAll" href="#"><i class="fa fa-check"></i> Select all</a></span> | <span class="clearall"><a id="CheckNone" href="#"><i class="fa fa-remove"></i> Clear all</a></span></p>
42
<p><span class="checkall"><a id="CheckAll" href="#"><i class="fa fa-check"></i> Select all</a></span> | <span class="clearall"><a id="CheckNone" href="#"><i class="fa fa-remove"></i> Clear all</a></span></p>
43
[% INCLUDE 'renew_results.inc' renew_results=renew_results %]
43
<table id="finest">
44
<table id="finest">
44
<thead>
45
<thead>
45
<tr>
46
<tr>
(-)a/members/boraccount.pl (+20 lines)
Lines 23-28 Link Here
23
# along with Koha; if not, see <http://www.gnu.org/licenses>.
23
# along with Koha; if not, see <http://www.gnu.org/licenses>.
24
24
25
use Modern::Perl;
25
use Modern::Perl;
26
use URI::Escape;
26
27
27
use C4::Auth;
28
use C4::Auth;
28
use C4::Output;
29
use C4::Output;
Lines 31-36 use C4::Members; Link Here
31
use C4::Accounts;
32
use C4::Accounts;
32
use Koha::Patrons;
33
use Koha::Patrons;
33
use Koha::Patron::Categories;
34
use Koha::Patron::Categories;
35
use Koha::Items;
34
36
35
my $input=new CGI;
37
my $input=new CGI;
36
38
Lines 51-56 my $borrowernumber = $input->param('borrowernumber'); Link Here
51
my $payment_id     = $input->param('payment_id');
53
my $payment_id     = $input->param('payment_id');
52
my $change_given   = $input->param('change_given');
54
my $change_given   = $input->param('change_given');
53
my $action         = $input->param('action') || '';
55
my $action         = $input->param('action') || '';
56
my @renew_results  = $input->param('renew_result');
54
57
55
my $logged_in_user = Koha::Patrons->find( $loggedinuser ) or die "Not logged in";
58
my $logged_in_user = Koha::Patrons->find( $loggedinuser ) or die "Not logged in";
56
my $patron = Koha::Patrons->find( $borrowernumber );
59
my $patron = Koha::Patrons->find( $borrowernumber );
Lines 80-85 if($total <= 0){ Link Here
80
        $totalcredit = 1;
83
        $totalcredit = 1;
81
}
84
}
82
85
86
# Populate an arrayref with everything we need to display any
87
# renew errors that occurred based on what we were passed
88
my $renew_results_display = [];
89
foreach my $renew_result(@renew_results) {
90
    my ($itemnumber, $success, $info) = split(/,/, $renew_result);
91
    my $item = Koha::Items->find($itemnumber);
92
    if ($success) {
93
        $info = uri_unescape($info);
94
    }
95
    push @{$renew_results_display}, {
96
        item    => $item,
97
        success => $success,
98
        info    => $info
99
    };
100
}
101
83
$template->param(
102
$template->param(
84
    patron              => $patron,
103
    patron              => $patron,
85
    finesview           => 1,
104
    finesview           => 1,
Lines 88-93 $template->param( Link Here
88
    accounts            => \@accountlines,
107
    accounts            => \@accountlines,
89
    payment_id          => $payment_id,
108
    payment_id          => $payment_id,
90
    change_given        => $change_given,
109
    change_given        => $change_given,
110
    renew_results       => $renew_results_display,
91
);
111
);
92
112
93
output_html_with_http_headers $input, $cookie, $template->output;
113
output_html_with_http_headers $input, $cookie, $template->output;
(-)a/members/pay.pl (+19 lines)
Lines 39-44 use C4::Stats; Link Here
39
use C4::Koha;
39
use C4::Koha;
40
use C4::Overdues;
40
use C4::Overdues;
41
use Koha::Patrons;
41
use Koha::Patrons;
42
use Koha::Items;
42
43
43
use Koha::Patron::Categories;
44
use Koha::Patron::Categories;
44
use URI::Escape;
45
use URI::Escape;
Lines 65-70 if ( !$borrowernumber ) { Link Here
65
66
66
my $payment_id = $input->param('payment_id');
67
my $payment_id = $input->param('payment_id');
67
our $change_given = $input->param('change_given');
68
our $change_given = $input->param('change_given');
69
our @renew_results = $input->multi_param('renew_result');
68
70
69
# get borrower details
71
# get borrower details
70
my $logged_in_user = Koha::Patrons->find( $loggedinuser ) or die "Not logged in";
72
my $logged_in_user = Koha::Patrons->find( $loggedinuser ) or die "Not logged in";
Lines 135-144 for (@names) { Link Here
135
    }
137
    }
136
}
138
}
137
139
140
# Populate an arrayref with everything we need to display any
141
# renew results that occurred based on what we were passed
142
my $renew_results_display = [];
143
foreach my $renew_result(@renew_results) {
144
    my ($itemnumber, $success, $info) = split(/,/, $renew_result);
145
    my $item = Koha::Items->find($itemnumber);
146
    if ($success) {
147
        $info = uri_unescape($info);
148
    }
149
    push @{$renew_results_display}, {
150
        item => $item,
151
        success => $success,
152
        info => $info
153
    };
154
}
155
138
$template->param(
156
$template->param(
139
    finesview  => 1,
157
    finesview  => 1,
140
    payment_id => $payment_id,
158
    payment_id => $payment_id,
141
    change_given => $change_given,
159
    change_given => $change_given,
160
    renew_results => $renew_results_display
142
);
161
);
143
162
144
add_accounts_to_template();
163
add_accounts_to_template();
(-)a/members/paycollect.pl (-7 / +29 lines)
Lines 34-39 use Koha::Patron::Categories; Link Here
34
use Koha::AuthorisedValues;
34
use Koha::AuthorisedValues;
35
use Koha::Account;
35
use Koha::Account;
36
use Koha::Token;
36
use Koha::Token;
37
use Koha::DateUtils;
37
38
38
my $input = CGI->new();
39
my $input = CGI->new();
39
40
Lines 171-179 if ( $total_paid and $total_paid ne '0.00' ) { Link Here
171
                token  => scalar $input->param('csrf_token'),
172
                token  => scalar $input->param('csrf_token'),
172
            });
173
            });
173
174
175
        my $url;
176
        my $pay_result;
174
        if ($pay_individual) {
177
        if ($pay_individual) {
175
            my $line = Koha::Account::Lines->find($accountlines_id);
178
            my $line = Koha::Account::Lines->find($accountlines_id);
176
            $payment_id = $account->pay(
179
            $pay_result = $account->pay(
177
                {
180
                {
178
                    lines        => [$line],
181
                    lines        => [$line],
179
                    amount       => $total_paid,
182
                    amount       => $total_paid,
Lines 184-191 if ( $total_paid and $total_paid ne '0.00' ) { Link Here
184
                    cash_register => $registerid
187
                    cash_register => $registerid
185
                }
188
                }
186
            );
189
            );
187
            print $input->redirect(
190
            $payment_id = $pay_result->{payment_id};
188
                "/cgi-bin/koha/members/pay.pl?borrowernumber=$borrowernumber&payment_id=$payment_id&change_given=$change_given");
191
192
            $url = "/cgi-bin/koha/members/pay.pl";
189
        } else {
193
        } else {
190
            if ($selected_accts) {
194
            if ($selected_accts) {
191
                if ( $total_paid > $total_due ) {
195
                if ( $total_paid > $total_due ) {
Lines 196-202 if ( $total_paid and $total_paid ne '0.00' ) { Link Here
196
                } else {
200
                } else {
197
                    my $note = $input->param('selected_accts_notes');
201
                    my $note = $input->param('selected_accts_notes');
198
202
199
                    $payment_id = $account->pay(
203
                    $pay_result = $account->pay(
200
                        {
204
                        {
201
                            type         => $type,
205
                            type         => $type,
202
                            amount       => $total_paid,
206
                            amount       => $total_paid,
Lines 207-218 if ( $total_paid and $total_paid ne '0.00' ) { Link Here
207
                            payment_type => $payment_type,
211
                            payment_type => $payment_type,
208
                            cash_register => $registerid
212
                            cash_register => $registerid
209
                        }
213
                        }
210
                      );
214
                    );
211
                }
215
                }
216
                $payment_id = $pay_result->{payment_id};
212
            }
217
            }
213
            else {
218
            else {
214
                my $note = $input->param('selected_accts_notes');
219
                my $note = $input->param('selected_accts_notes');
215
                $payment_id = $account->pay(
220
                $pay_result = $payment_id = $account->pay(
216
                    {
221
                    {
217
                        amount       => $total_paid,
222
                        amount       => $total_paid,
218
                        library_id   => $library_id,
223
                        library_id   => $library_id,
Lines 224-232 if ( $total_paid and $total_paid ne '0.00' ) { Link Here
224
                    }
229
                    }
225
                );
230
                );
226
            }
231
            }
232
            $payment_id = $pay_result->{payment_id};
227
233
228
            print $input->redirect("/cgi-bin/koha/members/boraccount.pl?borrowernumber=$borrowernumber&payment_id=$payment_id&change_given=$change_given");
234
            $url = "/cgi-bin/koha/members/boraccount.pl";
235
        }
236
        # It's possible renewals took place, parse any renew results
237
        # and pass on
238
        my @renew_result = ();
239
        foreach my $ren( @{$pay_result->{renew_result}} ) {
240
            my $str = "renew_result=$ren->{itemnumber},$ren->{success},";
241
            my $app = $ren->{success} ?
242
                uri_escape(
243
                    output_pref({ dt => $ren->{due_date}, as_due_date => 1 })
244
                ) : $ren->{error};
245
                push @renew_result, "${str}${app}";
229
        }
246
        }
247
        my $append = scalar @renew_result ? '&' . join('&', @renew_result) : '';
248
249
        $url .= "?borrowernumber=$borrowernumber&payment_id=$payment_id&change_given=${change_given}${append}";
250
251
        print $input->redirect($url);
230
    }
252
    }
231
} else {
253
} else {
232
    $total_paid = '0.00';    #TODO not right with pay_individual
254
    $total_paid = '0.00';    #TODO not right with pay_individual
(-)a/t/db_dependent/Accounts.t (-8 / +8 lines)
Lines 214-220 subtest "Koha::Account::pay tests" => sub { Link Here
214
    my $borrowernumber = $borrower->borrowernumber;
214
    my $borrowernumber = $borrower->borrowernumber;
215
    my $data = '20.00';
215
    my $data = '20.00';
216
    my $payment_note = '$20.00 payment note';
216
    my $payment_note = '$20.00 payment note';
217
    my $id = $account->pay( { amount => $data, note => $payment_note, payment_type => "TEST_TYPE" } );
217
    my $id = $account->pay( { amount => $data, note => $payment_note, payment_type => "TEST_TYPE" } )->{payment_id};
218
218
219
    my $accountline = Koha::Account::Lines->find( $id );
219
    my $accountline = Koha::Account::Lines->find( $id );
220
    is( $accountline->payment_type, "TEST_TYPE", "Payment type passed into pay is set in account line correctly" );
220
    is( $accountline->payment_type, "TEST_TYPE", "Payment type passed into pay is set in account line correctly" );
Lines 294-300 subtest "Koha::Account::pay tests" => sub { Link Here
294
    is($note,'$200.00 payment note', '$200.00 payment note is registered');
294
    is($note,'$200.00 payment note', '$200.00 payment note is registered');
295
295
296
    my $line3 = $account->add_debit({ type => 'ACCOUNT', amount => 42, interface => 'commandline' });
296
    my $line3 = $account->add_debit({ type => 'ACCOUNT', amount => 42, interface => 'commandline' });
297
    my $payment_id = $account->pay( { lines => [$line3], amount => 42 } );
297
    my $payment_id = $account->pay( { lines => [$line3], amount => 42 } )->{payment_id};
298
    my $payment = Koha::Account::Lines->find( $payment_id );
298
    my $payment = Koha::Account::Lines->find( $payment_id );
299
    is( $payment->amount(), '-42.000000', "Payment paid the specified fine" );
299
    is( $payment->amount(), '-42.000000', "Payment paid the specified fine" );
300
    $line3 = Koha::Account::Lines->find( $line3->id );
300
    $line3 = Koha::Account::Lines->find( $line3->id );
Lines 376-382 subtest "Koha::Account::pay writeoff tests" => sub { Link Here
376
            amount => 42,
376
            amount => 42,
377
            type   => 'WRITEOFF',
377
            type   => 'WRITEOFF',
378
        }
378
        }
379
    );
379
    )->{payment_id};
380
380
381
    $line->_result->discard_changes();
381
    $line->_result->discard_changes();
382
382
Lines 1111-1117 subtest "Koha::Account::Offset credit & debit tests" => sub { Link Here
1111
            lines  => [$line1, $line2],
1111
            lines  => [$line1, $line2],
1112
            amount => 30,
1112
            amount => 30,
1113
        }
1113
        }
1114
    );
1114
    )->{payment_id};
1115
1115
1116
    # Test debit and credit methods for Koha::Account::Offset
1116
    # Test debit and credit methods for Koha::Account::Offset
1117
    my $account_offset = Koha::Account::Offsets->find( { credit_id => $id, debit_id => $line1->id } );
1117
    my $account_offset = Koha::Account::Offsets->find( { credit_id => $id, debit_id => $line1->id } );
Lines 1177-1191 subtest "Payment notice tests" => sub { Link Here
1177
    $letter->store();
1177
    $letter->store();
1178
1178
1179
    t::lib::Mocks::mock_preference('UseEmailReceipts', '0');
1179
    t::lib::Mocks::mock_preference('UseEmailReceipts', '0');
1180
    my $id = $account->pay( { amount => 1 } );
1180
    my $id = $account->pay( { amount => 1 } )->{payment_id};
1181
    is( Koha::Notice::Messages->search()->count(), 0, 'Notice for payment not sent if UseEmailReceipts is disabled' );
1181
    is( Koha::Notice::Messages->search()->count(), 0, 'Notice for payment not sent if UseEmailReceipts is disabled' );
1182
1182
1183
    $id = $account->pay( { amount => 1, type => 'WRITEOFF' } );
1183
    $id = $account->pay( { amount => 1, type => 'WRITEOFF' } )->{payment_id};
1184
    is( Koha::Notice::Messages->search()->count(), 0, 'Notice for writeoff not sent if UseEmailReceipts is disabled' );
1184
    is( Koha::Notice::Messages->search()->count(), 0, 'Notice for writeoff not sent if UseEmailReceipts is disabled' );
1185
1185
1186
    t::lib::Mocks::mock_preference('UseEmailReceipts', '1');
1186
    t::lib::Mocks::mock_preference('UseEmailReceipts', '1');
1187
1187
1188
    $id = $account->pay( { amount => 12, library_id => $branchcode } );
1188
    $id = $account->pay( { amount => 12, library_id => $branchcode } )->{payment_id};
1189
    my $notice = Koha::Notice::Messages->search()->next();
1189
    my $notice = Koha::Notice::Messages->search()->next();
1190
    is( $notice->subject, 'Account payment', 'Notice subject is correct for payment' );
1190
    is( $notice->subject, 'Account payment', 'Notice subject is correct for payment' );
1191
    is( $notice->letter_code, 'ACCOUNT_PAYMENT', 'Notice letter code is correct for payment' );
1191
    is( $notice->letter_code, 'ACCOUNT_PAYMENT', 'Notice letter code is correct for payment' );
Lines 1196-1202 subtest "Payment notice tests" => sub { Link Here
1196
    $letter->content('[%- USE Price -%]A writeoff of [% credit.amount * -1 | $Price %] has been applied to your account. Your [% branch.branchcode %]');
1196
    $letter->content('[%- USE Price -%]A writeoff of [% credit.amount * -1 | $Price %] has been applied to your account. Your [% branch.branchcode %]');
1197
    $letter->store();
1197
    $letter->store();
1198
1198
1199
    $id = $account->pay( { amount => 13, type => 'WRITEOFF', library_id => $branchcode  } );
1199
    $id = $account->pay( { amount => 13, type => 'WRITEOFF', library_id => $branchcode  } )->{payment_id};
1200
    $notice = Koha::Notice::Messages->search()->next();
1200
    $notice = Koha::Notice::Messages->search()->next();
1201
    is( $notice->subject, 'Account writeoff', 'Notice subject is correct for payment' );
1201
    is( $notice->subject, 'Account writeoff', 'Notice subject is correct for payment' );
1202
    is( $notice->letter_code, 'ACCOUNT_WRITEOFF', 'Notice letter code is correct for writeoff' );
1202
    is( $notice->letter_code, 'ACCOUNT_WRITEOFF', 'Notice letter code is correct for writeoff' );
(-)a/t/db_dependent/Koha/Account.t (-3 / +3 lines)
Lines 19-25 Link Here
19
19
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use Test::More tests => 11;
22
use Test::More tests => 12;
23
use Test::MockModule;
23
use Test::MockModule;
24
use Test::Exception;
24
use Test::Exception;
25
25
Lines 685-696 subtest 'pay() tests' => sub { Link Here
685
    my $context = Test::MockModule->new('C4::Context');
685
    my $context = Test::MockModule->new('C4::Context');
686
    $context->mock( 'userenv', { branch => $library->id } );
686
    $context->mock( 'userenv', { branch => $library->id } );
687
687
688
    my $credit_1_id = $account->pay({ amount => 200 });
688
    my $credit_1_id = $account->pay({ amount => 200 })->{payment_id};
689
    my $credit_1    = Koha::Account::Lines->find( $credit_1_id );
689
    my $credit_1    = Koha::Account::Lines->find( $credit_1_id );
690
690
691
    is( $credit_1->branchcode, undef, 'No branchcode is set if library_id was not passed' );
691
    is( $credit_1->branchcode, undef, 'No branchcode is set if library_id was not passed' );
692
692
693
    my $credit_2_id = $account->pay({ amount => 150, library_id => $library->id });
693
    my $credit_2_id = $account->pay({ amount => 150, library_id => $library->id })->{payment_id};
694
    my $credit_2    = Koha::Account::Lines->find( $credit_2_id );
694
    my $credit_2    = Koha::Account::Lines->find( $credit_2_id );
695
695
696
    is( $credit_2->branchcode, $library->id, 'branchcode set because library_id was passed' );
696
    is( $credit_2->branchcode, $library->id, 'branchcode set because library_id was passed' );
(-)a/t/db_dependent/Koha/Account/Lines.t (-4 / +78 lines)
Lines 19-25 Link Here
19
19
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use Test::More tests => 9;
22
use Test::More tests => 10;
23
use Test::Exception;
23
use Test::Exception;
24
use Test::MockModule;
24
use Test::MockModule;
25
25
Lines 365-371 subtest 'apply() tests' => sub { Link Here
365
    my $module = new Test::MockModule('C4::Circulation');
365
    my $module = new Test::MockModule('C4::Circulation');
366
    $module->mock('AddRenewal', sub { $called = 1; });
366
    $module->mock('AddRenewal', sub { $called = 1; });
367
    my $credit_renew = $account->add_credit({ amount => 100, user_id => $patron->id, interface => 'commandline' });
367
    my $credit_renew = $account->add_credit({ amount => 100, user_id => $patron->id, interface => 'commandline' });
368
    my $debits_renew = Koha::Account::Lines->search({ accountlines_id => $accountline->id });
368
    my $debits_renew = Koha::Account::Lines->search({ accountlines_id => $accountline->id })->as_list;
369
    $credit_renew->apply( { debits => $debits_renew, offset_type => 'Manual Credit' } );
369
    $credit_renew->apply( { debits => $debits_renew, offset_type => 'Manual Credit' } );
370
370
371
    is( $called, 1, 'RenewAccruingItemWhenPaid causes C4::Circulation::AddRenew to be called when appropriate' );
371
    is( $called, 1, 'RenewAccruingItemWhenPaid causes C4::Circulation::AddRenew to be called when appropriate' );
Lines 415-420 subtest 'Keep account info when related patron, staff or item is deleted' => sub Link Here
415
    $schema->storage->txn_rollback;
415
    $schema->storage->txn_rollback;
416
};
416
};
417
417
418
subtest 'Renewal related tests' => sub {
419
420
    plan tests => 7;
421
422
    $schema->storage->txn_begin;
423
424
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
425
    my $staff = $builder->build_object( { class => 'Koha::Patrons' } );
426
    my $item = $builder->build_object({ class => 'Koha::Items' });
427
    my $issue = $builder->build_object(
428
        {
429
            class => 'Koha::Checkouts',
430
            value => {
431
                itemnumber      => $item->itemnumber,
432
                onsite_checkout => 0,
433
                renewals        => 99,
434
                auto_renew      => 0
435
            }
436
        }
437
    );
438
    my $line = Koha::Account::Line->new(
439
    {
440
        borrowernumber    => $patron->borrowernumber,
441
        manager_id        => $staff->borrowernumber,
442
        itemnumber        => $item->itemnumber,
443
        accounttype       => "OVERDUE",
444
        status            => "UNRETURNED",
445
        amountoutstanding => 0,
446
        interface         => 'commandline',
447
    })->store;
448
449
    is( $line->renewable, 1, "Item is returned as renewable when it meets the conditions" );
450
    $line->amountoutstanding(5);
451
    is( $line->renewable, 0, "Item is returned as unrenewable when it has outstanding fine" );
452
    $line->amountoutstanding(0);
453
    $line->accounttype("VOID");
454
    is( $line->renewable, 0, "Item is returned as unrenewable when it has the wrong account type" );
455
    $line->accounttype("OVERDUE");
456
    $line->status("RETURNED");
457
    is( $line->renewable, 0, "Item is returned as unrenewable when it has the wrong account status" );
458
459
460
    t::lib::Mocks::mock_preference( 'RenewAccruingItemWhenPaid', 0 );
461
    is ($line->renew_item, 0, 'Attempt to renew fails when syspref is not set');
462
    t::lib::Mocks::mock_preference( 'RenewAccruingItemWhenPaid', 1 );
463
    is_deeply(
464
        $line->renew_item,
465
        {
466
            itemnumber => $item->itemnumber,
467
            error      => 'too_many',
468
            success    => 0
469
        },
470
        'Attempt to renew fails when CanBookBeRenewed returns false'
471
    );
472
    $issue->delete;
473
    $issue = $builder->build_object(
474
        {
475
            class => 'Koha::Checkouts',
476
            value => {
477
                itemnumber      => $item->itemnumber,
478
                onsite_checkout => 0,
479
                renewals        => 0,
480
                auto_renew      => 0
481
            }
482
        }
483
    );
484
    my $called = 0;
485
    my $module = new Test::MockModule('C4::Circulation');
486
    $module->mock('AddRenewal', sub { $called = 1; });
487
    $line->renew_item;
488
    is( $called, 1, 'Attempt to renew succeeds when conditions are met' );
489
490
    $schema->storage->txn_rollback;
491
};
492
418
subtest 'adjust() tests' => sub {
493
subtest 'adjust() tests' => sub {
419
494
420
    plan tests => 29;
495
    plan tests => 29;
Lines 617-623 subtest "void() tests" => sub { Link Here
617
            lines  => [$line1, $line2],
692
            lines  => [$line1, $line2],
618
            amount => 30,
693
            amount => 30,
619
        }
694
        }
620
    );
695
    )->{payment_id};
621
696
622
    my $account_payment = Koha::Account::Lines->find( $id );
697
    my $account_payment = Koha::Account::Lines->find( $id );
623
698
624
- 

Return to bug 23051