|
Lines 20-26
Link Here
|
| 20 |
use Modern::Perl; |
20 |
use Modern::Perl; |
| 21 |
|
21 |
|
| 22 |
use Test::NoWarnings; |
22 |
use Test::NoWarnings; |
| 23 |
use Test::More tests => 16; |
23 |
use Test::More tests => 17; |
| 24 |
use Test::Exception; |
24 |
use Test::Exception; |
| 25 |
use Test::MockModule; |
25 |
use Test::MockModule; |
| 26 |
|
26 |
|
|
Lines 726-731
subtest 'adjust() tests' => sub {
Link Here
|
| 726 |
$schema->storage->txn_rollback; |
726 |
$schema->storage->txn_rollback; |
| 727 |
}; |
727 |
}; |
| 728 |
|
728 |
|
|
|
729 |
subtest 'adjust() tests (writeoff does not generate overpayment credit)' => sub { |
| 730 |
|
| 731 |
plan tests => 12; |
| 732 |
|
| 733 |
$schema->storage->txn_begin; |
| 734 |
|
| 735 |
my $patron = $builder->build_object( { class => 'Koha::Patrons' } ); |
| 736 |
my $account = $patron->account; |
| 737 |
|
| 738 |
# Scenario 1: Full writeoff then fine adjusted to 0 - no OVERPAYMENT credit |
| 739 |
my $debit_1 = Koha::Account::Line->new( |
| 740 |
{ |
| 741 |
borrowernumber => $patron->id, |
| 742 |
debit_type_code => "OVERDUE", |
| 743 |
status => "UNRETURNED", |
| 744 |
amount => 100, |
| 745 |
amountoutstanding => 100, |
| 746 |
interface => 'commandline', |
| 747 |
} |
| 748 |
)->store; |
| 749 |
|
| 750 |
my $lines_count_before = $account->lines->count; |
| 751 |
|
| 752 |
# Write off the full fine |
| 753 |
$account->pay( |
| 754 |
{ |
| 755 |
amount => 100, |
| 756 |
type => 'WRITEOFF', |
| 757 |
lines => [$debit_1], |
| 758 |
interface => 'commandline', |
| 759 |
} |
| 760 |
); |
| 761 |
$debit_1->discard_changes; |
| 762 |
is( $debit_1->amountoutstanding * 1, 0, 'Fine fully written off' ); |
| 763 |
|
| 764 |
# Simulate check-in recalculating fine to 0 (backdated or fine-free) |
| 765 |
$debit_1->adjust( { amount => 0, type => 'overdue_update', interface => 'commandline' } )->discard_changes; |
| 766 |
|
| 767 |
is( $debit_1->amount * 1, 0, 'Fine amount adjusted to 0' ); |
| 768 |
is( $debit_1->amountoutstanding * 1, 0, 'Fine amountoutstanding remains 0' ); |
| 769 |
|
| 770 |
# No new OVERPAYMENT credit should have been generated |
| 771 |
is( |
| 772 |
$account->lines->count, |
| 773 |
$lines_count_before + 1, # only the WRITEOFF credit, no OVERPAYMENT |
| 774 |
'No OVERPAYMENT credit generated when fine adjusted after writeoff' |
| 775 |
); |
| 776 |
isnt( |
| 777 |
$account->lines->last->credit_type_code, |
| 778 |
'OVERPAYMENT', |
| 779 |
'Last account line is not an OVERPAYMENT credit' |
| 780 |
); |
| 781 |
|
| 782 |
# Scenario 2: Partial payment + partial writeoff, fine drops below payment amount |
| 783 |
# => OVERPAYMENT only for the payment portion |
| 784 |
my $debit_2 = Koha::Account::Line->new( |
| 785 |
{ |
| 786 |
borrowernumber => $patron->id, |
| 787 |
debit_type_code => "OVERDUE", |
| 788 |
status => "UNRETURNED", |
| 789 |
amount => 100, |
| 790 |
amountoutstanding => 100, |
| 791 |
interface => 'commandline', |
| 792 |
} |
| 793 |
)->store; |
| 794 |
|
| 795 |
# Apply a $60 writeoff |
| 796 |
$account->pay( |
| 797 |
{ |
| 798 |
amount => 60, |
| 799 |
type => 'WRITEOFF', |
| 800 |
lines => [$debit_2], |
| 801 |
interface => 'commandline', |
| 802 |
} |
| 803 |
); |
| 804 |
$debit_2->discard_changes; |
| 805 |
is( $debit_2->amountoutstanding * 1, 40, 'Fine outstanding after writeoff' ); |
| 806 |
|
| 807 |
# Apply a $30 cash payment |
| 808 |
my $payment = $account->add_credit( { amount => 30, type => 'PAYMENT', interface => 'commandline' } ); |
| 809 |
my $debits = Koha::Account::Lines->search( { accountlines_id => $debit_2->id } ); |
| 810 |
$payment->apply( { debits => [ $debits->as_list ] } ); |
| 811 |
$debit_2->discard_changes; |
| 812 |
is( $debit_2->amountoutstanding * 1, 10, 'Fine outstanding after payment' ); |
| 813 |
|
| 814 |
my $lines_count_before_2 = $account->lines->count; |
| 815 |
|
| 816 |
# Simulate check-in recalculating fine to $0 (below the $30 payment) |
| 817 |
$debit_2->adjust( { amount => 0, type => 'overdue_update', interface => 'commandline' } )->discard_changes; |
| 818 |
|
| 819 |
is( $debit_2->amount * 1, 0, 'Fine amount adjusted to 0' ); |
| 820 |
is( $debit_2->amountoutstanding * 1, 0, 'Fine amountoutstanding remains 0' ); |
| 821 |
|
| 822 |
# OVERPAYMENT credit should be generated only for the reversible payment amount ($30) |
| 823 |
is( |
| 824 |
$account->lines->count, |
| 825 |
$lines_count_before_2 + 1, |
| 826 |
'One OVERPAYMENT credit generated (for cash payment only)' |
| 827 |
); |
| 828 |
my $overpayment = $account->lines->last; |
| 829 |
is( $overpayment->amount * 1, -30, 'OVERPAYMENT credit is for payment amount only, not writeoff' ); |
| 830 |
is( $overpayment->credit_type_code, 'OVERPAYMENT', 'Credit type is OVERPAYMENT' ); |
| 831 |
|
| 832 |
$schema->storage->txn_rollback; |
| 833 |
}; |
| 834 |
|
| 729 |
subtest 'checkout() tests' => sub { |
835 |
subtest 'checkout() tests' => sub { |
| 730 |
plan tests => 7; |
836 |
plan tests => 7; |
| 731 |
|
837 |
|
| 732 |
- |
|
|