Bug 13098: Tests for all _FixAccountForLostAndReturned use cases

This patch introduces tests for all the use cases for
_FixAccountForLostAndReturned. This includes the following scenarios
before _FixAccountForLostAndReturned is called:

- Full write off (the original issue)
- Full payment
- No payment or write off
- Partial payment and partial write off

Written off debts (L lines) are just skipped, any kind of payment is
added and then refund as a single credit (CR). Amount outstanding is set
to 0. Offsets need to be generated for paper trail of this decisions.

To test:
- Run:
  $ kshell
 k$ prove t/db_dependent/Circulation.t
=> FAIL: Tests fail because _FixAccountForLostAndReturned is not doing
the right thing :-D

Followed test plan, patch works as described
Signed-off-by: Alex Buckley <alexbuckley@catalyst.net.nz>

Signed-off-by: Josef Moravec <josef.moravec@gmail.com>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
This commit is contained in:
Tomás Cohen Arazi 2018-10-12 10:27:06 -03:00 committed by Nick Clemens
parent 9acfe17257
commit 0fb422d8f9

View file

@ -1982,54 +1982,303 @@ subtest 'AddReturn | is_overdue' => sub {
}; };
subtest '_FixAccountForLostAndReturned' => sub { subtest '_FixAccountForLostAndReturned' => sub {
plan tests => 2;
plan tests => 4;
t::lib::Mocks::mock_preference( 'WhenLostChargeReplacementFee', 1 );
t::lib::Mocks::mock_preference( 'WhenLostForgiveFine', 0 );
my $processfee_amount = 20.00;
my $replacement_amount = 99.00;
my $item_type = $builder->build_object(
{ class => 'Koha::ItemTypes',
value => {
notforloan => undef,
rentalcharge => 0,
defaultreplacecost => undef,
processfee => $processfee_amount
}
}
);
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
# Generate test biblio # Generate test biblio
my $title = 'Koha for Dummies'; my $title = 'Koha for Dummies';
my ( $biblionumber, $biblioitemnumber ) = add_biblio($title, 'Hall, Daria'); my ( $biblionumber, $biblioitemnumber ) = add_biblio( $title, 'Hall, Daria' );
my $barcode = 'KD123456789'; subtest 'Full write-off tests' => sub {
my $branchcode = $library2->{branchcode};
my ( $item_bibnum, $item_bibitemnum, $itemnumber ) = AddItem( plan tests => 10;
{
homebranch => $branchcode,
holdingbranch => $branchcode,
barcode => $barcode,
replacementprice => 99.00,
itype => $itemtype
},
$biblionumber
);
my $patron = $builder->build( { source => 'Borrower' } ); my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
my $barcode = 'KD123456789';
Koha::Account::Line->new( my ( undef, undef, $item_id ) = AddItem(
{ { homebranch => $library->branchcode,
borrowernumber => $patron->{borrowernumber}, holdingbranch => $library->branchcode,
accounttype => 'F', barcode => $barcode,
itemnumber => $itemnumber, replacementprice => $replacement_amount,
amount => 10.00, itype => $item_type->itemtype
amountoutstanding => 10.00, },
} $biblionumber
)->store(); );
my $accountline = Koha::Account::Line->new( AddIssue( $patron->unblessed, $barcode );
{
borrowernumber => $patron->{borrowernumber},
accounttype => 'L',
itemnumber => $itemnumber,
amount => 99.00,
amountoutstanding => 99.00,
}
)->store();
C4::Circulation::_FixAccountForLostAndReturned( $itemnumber, $patron->{borrowernumber} ); # Simulate item marked as lost
ModItem( { itemlost => 3 }, $biblionumber, $item_id );
LostItem( $item_id, 1 );
$accountline->_result()->discard_changes(); my $processing_fee_lines = Koha::Account::Lines->search(
{ borrowernumber => $patron->id, itemnumber => $item_id, accounttype => 'PF' } );
is( $processing_fee_lines->count, 1, 'Only one processing fee produced' );
my $processing_fee_line = $processing_fee_lines->next;
is( $processing_fee_line->amount + 0.00,
$processfee_amount, 'The right PF amount is generated' );
is( $processing_fee_line->amountoutstanding + 0.00,
$processfee_amount, 'The right PF amountoutstanding is generated' );
is( $accountline->amountoutstanding, '0.000000', 'Lost fee has no outstanding amount' ); my $lost_fee_lines = Koha::Account::Lines->search(
is( $accountline->accounttype, 'LR', 'Lost fee now has account type of LR ( Lost Returned )'); { borrowernumber => $patron->id, itemnumber => $item_id, accounttype => 'L' } );
is( $lost_fee_lines->count, 1, 'Only one lost item fee produced' );
my $lost_fee_line = $lost_fee_lines->next;
is( $lost_fee_line->amount + 0.00, $replacement_amount, 'The right L amount is generated' );
is( $lost_fee_line->amountoutstanding + 0.00,
$replacement_amount, 'The right L amountountstanding is generated' );
my $account = $patron->account;
my $debts = $account->outstanding_debits;
# Write off the debt
my $credit = $account->add_credit(
{ amount => $account->balance,
type => 'writeoff'
}
);
$credit->apply( { debits => $debts, offset_type => 'Writeoff' } );
my $credit_return_id = C4::Circulation::_FixAccountForLostAndReturned( $item_id, $patron->id );
is( $credit_return_id, undef, 'No CR account line added' );
$lost_fee_line->discard_changes; # reload from DB
is( $lost_fee_line->amountoutstanding + 0.00, 0.00, 'Lost fee has no outstanding amount' );
is( $lost_fee_line->accounttype,
'LR', 'Lost fee now has account type of LR ( Lost Returned )' );
is( $patron->account->balance, -0, 'The patron balance is 0, everything was written off' );
};
subtest 'Full payment tests' => sub {
plan tests => 12;
my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
my $barcode = 'KD123456790';
my ( undef, undef, $item_id ) = AddItem(
{ homebranch => $library->branchcode,
holdingbranch => $library->branchcode,
barcode => $barcode,
replacementprice => $replacement_amount,
itype => $item_type->itemtype
},
$biblionumber
);
AddIssue( $patron->unblessed, $barcode );
# Simulate item marked as lost
ModItem( { itemlost => 1 }, $biblionumber, $item_id );
LostItem( $item_id, 1 );
my $processing_fee_lines = Koha::Account::Lines->search(
{ borrowernumber => $patron->id, itemnumber => $item_id, accounttype => 'PF' } );
is( $processing_fee_lines->count, 1, 'Only one processing fee produced' );
my $processing_fee_line = $processing_fee_lines->next;
is( $processing_fee_line->amount + 0.00,
$processfee_amount, 'The right PF amount is generated' );
is( $processing_fee_line->amountoutstanding + 0.00,
$processfee_amount, 'The right PF amountoutstanding is generated' );
my $lost_fee_lines = Koha::Account::Lines->search(
{ borrowernumber => $patron->id, itemnumber => $item_id, accounttype => 'L' } );
is( $lost_fee_lines->count, 1, 'Only one lost item fee produced' );
my $lost_fee_line = $lost_fee_lines->next;
is( $lost_fee_line->amount + 0.00, $replacement_amount, 'The right L amount is generated' );
is( $lost_fee_line->amountoutstanding + 0.00,
$replacement_amount, 'The right L amountountstanding is generated' );
my $account = $patron->account;
my $debts = $account->outstanding_debits;
# Write off the debt
my $credit = $account->add_credit(
{ amount => $account->balance,
type => 'payment'
}
);
$credit->apply( { debits => $debts, offset_type => 'Payment' } );
my $credit_return_id = C4::Circulation::_FixAccountForLostAndReturned( $item_id, $patron->id );
my $credit_return = Koha::Account::Lines->find($credit_return_id);
is( $credit_return->accounttype, 'CR', 'An account line of type CR is added' );
is( $credit_return->amount + 0.00,
-99.00, 'The account line of type CR has an amount of -99' );
is( $credit_return->amountoutstanding + 0.00,
-99.00, 'The account line of type CR has an amountoutstanding of -99' );
$lost_fee_line->discard_changes;
is( $lost_fee_line->amountoutstanding + 0.00, 0.00, 'Lost fee has no outstanding amount' );
is( $lost_fee_line->accounttype,
'LR', 'Lost fee now has account type of LR ( Lost Returned )' );
is( $patron->account->balance,
-99, 'The patron balance is -99, a credit that equals the lost fee payment' );
};
subtest 'Test without payment or write off' => sub {
plan tests => 10;
my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
my $barcode = 'KD123456791';
my ( undef, undef, $item_id ) = AddItem(
{ homebranch => $library->branchcode,
holdingbranch => $library->branchcode,
barcode => $barcode,
replacementprice => $replacement_amount,
itype => $item_type->itemtype
},
$biblionumber
);
AddIssue( $patron->unblessed, $barcode );
# Simulate item marked as lost
ModItem( { itemlost => 3 }, $biblionumber, $item_id );
LostItem( $item_id, 1 );
my $processing_fee_lines = Koha::Account::Lines->search(
{ borrowernumber => $patron->id, itemnumber => $item_id, accounttype => 'PF' } );
is( $processing_fee_lines->count, 1, 'Only one processing fee produced' );
my $processing_fee_line = $processing_fee_lines->next;
is( $processing_fee_line->amount + 0.00,
$processfee_amount, 'The right PF amount is generated' );
is( $processing_fee_line->amountoutstanding + 0.00,
$processfee_amount, 'The right PF amountoutstanding is generated' );
my $lost_fee_lines = Koha::Account::Lines->search(
{ borrowernumber => $patron->id, itemnumber => $item_id, accounttype => 'L' } );
is( $lost_fee_lines->count, 1, 'Only one lost item fee produced' );
my $lost_fee_line = $lost_fee_lines->next;
is( $lost_fee_line->amount + 0.00, $replacement_amount, 'The right L amount is generated' );
is( $lost_fee_line->amountoutstanding + 0.00,
$replacement_amount, 'The right L amountountstanding is generated' );
my $credit_return_id = C4::Circulation::_FixAccountForLostAndReturned( $item_id, $patron->id );
is( $credit_return_id, undef, 'No CR account line added' );
$lost_fee_line->discard_changes;
is( $lost_fee_line->amountoutstanding + 0.00, 0.00, 'Lost fee has no outstanding amount' );
is( $lost_fee_line->accounttype, 'LR', 'Lost fee now has account type of LR ( Lost Returned )' );
is( $patron->account->balance, 20, 'The patron balance is 20, still owes the processing fee' );
};
subtest 'Test with partial payement and write off, and remaining debt' => sub {
plan tests => 15;
my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
my $barcode = 'KD123456792';
my ( undef, undef, $item_id ) = AddItem(
{ homebranch => $library->branchcode,
holdingbranch => $library->branchcode,
barcode => $barcode,
replacementprice => $replacement_amount,
itype => $item_type->itemtype
},
$biblionumber
);
AddIssue( $patron->unblessed, $barcode );
# Simulate item marked as lost
ModItem( { itemlost => 1 }, $biblionumber, $item_id );
LostItem( $item_id, 1 );
my $processing_fee_lines = Koha::Account::Lines->search(
{ borrowernumber => $patron->id, itemnumber => $item_id, accounttype => 'PF' } );
is( $processing_fee_lines->count, 1, 'Only one processing fee produced' );
my $processing_fee_line = $processing_fee_lines->next;
is( $processing_fee_line->amount + 0.00,
$processfee_amount, 'The right PF amount is generated' );
is( $processing_fee_line->amountoutstanding + 0.00,
$processfee_amount, 'The right PF amountoutstanding is generated' );
my $lost_fee_lines = Koha::Account::Lines->search(
{ borrowernumber => $patron->id, itemnumber => $item_id, accounttype => 'L' } );
is( $lost_fee_lines->count, 1, 'Only one lost item fee produced' );
my $lost_fee_line = $lost_fee_lines->next;
is( $lost_fee_line->amount + 0.00, $replacement_amount, 'The right L amount is generated' );
is( $lost_fee_line->amountoutstanding + 0.00,
$replacement_amount, 'The right L amountountstanding is generated' );
my $account = $patron->account;
is( $account->balance, $processfee_amount + $replacement_amount, 'Balance is PF + L' );
# Partially pay fee
my $payment_amount = 27;
my $payment = $account->add_credit(
{ amount => $payment_amount,
type => 'payment'
}
);
$payment->apply( { debits => $lost_fee_lines->reset, offset_type => 'Payment' } );
# Partially write off fee
my $write_off_amount = 25;
my $write_off = $account->add_credit(
{ amount => $write_off_amount,
type => 'writeoff'
}
);
$write_off->apply( { debits => $lost_fee_lines->reset, offset_type => 'Writeoff' } );
is( $account->balance,
$processfee_amount + $replacement_amount - $payment_amount - $write_off_amount,
'Payment and write off applied'
);
my $credit_return_id = C4::Circulation::_FixAccountForLostAndReturned( $item_id, $patron->id );
my $credit_return = Koha::Account::Lines->find($credit_return_id);
is( $account->balance, $processfee_amount - $payment_amount, 'Balance is PF - payment (CR)' );
is( $credit_return->accounttype, 'CR', 'An account line of type CR is added' );
is( $credit_return->amount + 0.00,
$payment_amount * -1,
'The account line of type CR has an amount equal to the payment'
);
is( $credit_return->amountoutstanding + 0.00,
$payment_amount * -1,
'The account line of type CR has an amountoutstanding equal to the payment'
);
$lost_fee_line->discard_changes;
is( $lost_fee_line->amountoutstanding + 0.00, 0.00, 'Lost fee has no outstanding amount' );
is( $lost_fee_line->accounttype,
'LR', 'Lost fee now has account type of LR ( Lost Returned )' );
is( $account->balance,
$processfee_amount - $payment_amount,
'The patron balance is the difference between the PF and the credit'
);
};
}; };
subtest '_FixOverduesOnReturn' => sub { subtest '_FixOverduesOnReturn' => sub {