use Modern::Perl;
use utf8;
-use Test::More tests => 50;
+use Test::More tests => 48;
use Test::Exception;
use Test::MockModule;
use Test::Deep qw( cmp_deeply );
};
};
-subtest '_FixAccountForLostAndFound' => sub {
-
- plan tests => 5;
-
- t::lib::Mocks::mock_preference( 'WhenLostChargeReplacementFee', 1 );
- t::lib::Mocks::mock_preference( 'WhenLostForgiveFine', 0 );
-
- my $processfee_amount = 20;
- my $replacement_amount = 99.00;
- my $item_type = $builder->build_object(
- { class => 'Koha::ItemTypes',
- value => {
- notforloan => undef,
- rentalcharge => 0,
- defaultreplacecost => undef,
- processfee => $processfee_amount,
- rentalcharge_daily => 0,
- }
- }
- );
- my $library = $builder->build_object( { class => 'Koha::Libraries' } );
-
- my $biblio = $builder->build_sample_biblio({ author => 'Hall, Daria' });
-
- subtest 'Full write-off tests' => sub {
-
- plan tests => 12;
-
- my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
- my $manager = $builder->build_object({ class => "Koha::Patrons" });
- t::lib::Mocks::mock_userenv({ patron => $manager,branchcode => $manager->branchcode });
-
- my $item = $builder->build_sample_item(
- {
- biblionumber => $biblio->biblionumber,
- library => $library->branchcode,
- replacementprice => $replacement_amount,
- itype => $item_type->itemtype,
- }
- );
-
- AddIssue( $patron->unblessed, $item->barcode );
-
- # Simulate item marked as lost
- $item->itemlost(3)->store;
- LostItem( $item->itemnumber, 1 );
-
- my $processing_fee_lines = Koha::Account::Lines->search(
- { borrowernumber => $patron->id, itemnumber => $item->itemnumber, debit_type_code => 'PROCESSING' } );
- 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,
- $processfee_amount, 'The right PROCESSING amount is generated' );
- is( $processing_fee_line->amountoutstanding + 0,
- $processfee_amount, 'The right PROCESSING amountoutstanding is generated' );
-
- my $lost_fee_lines = Koha::Account::Lines->search(
- { borrowernumber => $patron->id, itemnumber => $item->itemnumber, debit_type_code => 'LOST' } );
- 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, $replacement_amount, 'The right LOST amount is generated' );
- is( $lost_fee_line->amountoutstanding + 0,
- $replacement_amount, 'The right LOST amountoutstanding is generated' );
- is( $lost_fee_line->status,
- undef, 'The LOST status was not set' );
-
- my $account = $patron->account;
- my $debts = $account->outstanding_debits;
-
- # Write off the debt
- my $credit = $account->add_credit(
- { amount => $account->balance,
- type => 'WRITEOFF',
- interface => 'test',
- }
- );
- $credit->apply( { debits => [ $debts->as_list ], offset_type => 'Writeoff' } );
-
- my $credit_return_id = C4::Circulation::_FixAccountForLostAndFound( $item->itemnumber );
- is( $credit_return_id, undef, 'No LOST_FOUND account line added' );
-
- $lost_fee_line->discard_changes; # reload from DB
- is( $lost_fee_line->amountoutstanding + 0, 0, 'Lost fee has no outstanding amount' );
- is( $lost_fee_line->debit_type_code,
- 'LOST', 'Lost fee now still has account type of LOST' );
- is( $lost_fee_line->status, 'FOUND', "Lost fee now has account status of FOUND");
-
- is( $patron->account->balance, -0, 'The patron balance is 0, everything was written off' );
- };
-
- subtest 'Full payment tests' => sub {
-
- plan tests => 13;
-
- my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
-
- my $item = $builder->build_sample_item(
- {
- biblionumber => $biblio->biblionumber,
- library => $library->branchcode,
- replacementprice => $replacement_amount,
- itype => $item_type->itemtype
- }
- );
-
- AddIssue( $patron->unblessed, $item->barcode );
-
- # Simulate item marked as lost
- $item->itemlost(1)->store;
- LostItem( $item->itemnumber, 1 );
-
- my $processing_fee_lines = Koha::Account::Lines->search(
- { borrowernumber => $patron->id, itemnumber => $item->itemnumber, debit_type_code => 'PROCESSING' } );
- 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,
- $processfee_amount, 'The right PROCESSING amount is generated' );
- is( $processing_fee_line->amountoutstanding + 0,
- $processfee_amount, 'The right PROCESSING amountoutstanding is generated' );
-
- my $lost_fee_lines = Koha::Account::Lines->search(
- { borrowernumber => $patron->id, itemnumber => $item->itemnumber, debit_type_code => 'LOST' } );
- 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, $replacement_amount, 'The right LOST amount is generated' );
- is( $lost_fee_line->amountoutstanding + 0,
- $replacement_amount, 'The right LOST 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',
- interface => 'test',
- }
- );
- $credit->apply( { debits => [ $debts->as_list ], offset_type => 'Payment' } );
-
- my $credit_return_id = C4::Circulation::_FixAccountForLostAndFound( $item->itemnumber );
- my $credit_return = Koha::Account::Lines->find($credit_return_id);
-
- is( $credit_return->credit_type_code, 'LOST_FOUND', 'An account line of type LOST_FOUND is added' );
- is( $credit_return->amount + 0,
- -99.00, 'The account line of type LOST_FOUND has an amount of -99' );
- is( $credit_return->amountoutstanding + 0,
- -99.00, 'The account line of type LOST_FOUND has an amountoutstanding of -99' );
-
- $lost_fee_line->discard_changes;
- is( $lost_fee_line->amountoutstanding + 0, 0, 'Lost fee has no outstanding amount' );
- is( $lost_fee_line->debit_type_code,
- 'LOST', 'Lost fee now still has account type of LOST' );
- is( $lost_fee_line->status, 'FOUND', "Lost fee now has account status of FOUND");
-
- 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 => 13;
-
- my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
-
- my $item = $builder->build_sample_item(
- {
- biblionumber => $biblio->biblionumber,
- library => $library->branchcode,
- replacementprice => 23.00,
- replacementprice => $replacement_amount,
- itype => $item_type->itemtype
- }
- );
-
- AddIssue( $patron->unblessed, $item->barcode );
-
- # Simulate item marked as lost
- $item->itemlost(3)->store;
- LostItem( $item->itemnumber, 1 );
-
- my $processing_fee_lines = Koha::Account::Lines->search(
- { borrowernumber => $patron->id, itemnumber => $item->itemnumber, debit_type_code => 'PROCESSING' } );
- 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,
- $processfee_amount, 'The right PROCESSING amount is generated' );
- is( $processing_fee_line->amountoutstanding + 0,
- $processfee_amount, 'The right PROCESSING amountoutstanding is generated' );
-
- my $lost_fee_lines = Koha::Account::Lines->search(
- { borrowernumber => $patron->id, itemnumber => $item->itemnumber, debit_type_code => 'LOST' } );
- 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, $replacement_amount, 'The right LOST amount is generated' );
- is( $lost_fee_line->amountoutstanding + 0,
- $replacement_amount, 'The right LOST amountountstanding is generated' );
-
- my $credit_return_id = C4::Circulation::_FixAccountForLostAndFound( $item->itemnumber );
- my $credit_return = Koha::Account::Lines->find($credit_return_id);
-
- is( $credit_return->credit_type_code, 'LOST_FOUND', 'An account line of type LOST_FOUND is added' );
- is( $credit_return->amount + 0, -99.00, 'The account line of type LOST_FOUND has an amount of -99' );
- is( $credit_return->amountoutstanding + 0, 0, 'The account line of type LOST_FOUND has an amountoutstanding of 0' );
-
- $lost_fee_line->discard_changes;
- is( $lost_fee_line->amountoutstanding + 0, 0, 'Lost fee has no outstanding amount' );
- is( $lost_fee_line->debit_type_code,
- 'LOST', 'Lost fee now still has account type of LOST' );
- is( $lost_fee_line->status, 'FOUND', "Lost fee now has account status of FOUND");
-
- 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 => 16;
-
- my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
- my $item = $builder->build_sample_item(
- {
- biblionumber => $biblio->biblionumber,
- library => $library->branchcode,
- replacementprice => $replacement_amount,
- itype => $item_type->itemtype
- }
- );
-
- AddIssue( $patron->unblessed, $item->barcode );
-
- # Simulate item marked as lost
- $item->itemlost(1)->store;
- LostItem( $item->itemnumber, 1 );
-
- my $processing_fee_lines = Koha::Account::Lines->search(
- { borrowernumber => $patron->id, itemnumber => $item->itemnumber, debit_type_code => 'PROCESSING' } );
- 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,
- $processfee_amount, 'The right PROCESSING amount is generated' );
- is( $processing_fee_line->amountoutstanding + 0,
- $processfee_amount, 'The right PROCESSING amountoutstanding is generated' );
-
- my $lost_fee_lines = Koha::Account::Lines->search(
- { borrowernumber => $patron->id, itemnumber => $item->itemnumber, debit_type_code => 'LOST' } );
- 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, $replacement_amount, 'The right LOST amount is generated' );
- is( $lost_fee_line->amountoutstanding + 0,
- $replacement_amount, 'The right LOST amountountstanding is generated' );
-
- my $account = $patron->account;
- is( $account->balance, $processfee_amount + $replacement_amount, 'Balance is PROCESSING + L' );
-
- # Partially pay fee
- my $payment_amount = 27;
- my $payment = $account->add_credit(
- { amount => $payment_amount,
- type => 'PAYMENT',
- interface => 'test',
- }
- );
-
- $payment->apply( { debits => [ $lost_fee_line ], offset_type => 'Payment' } );
-
- # Partially write off fee
- my $write_off_amount = 25;
- my $write_off = $account->add_credit(
- { amount => $write_off_amount,
- type => 'WRITEOFF',
- interface => 'test',
- }
- );
- $write_off->apply( { debits => [ $lost_fee_line ], offset_type => 'Writeoff' } );
-
- is( $account->balance,
- $processfee_amount + $replacement_amount - $payment_amount - $write_off_amount,
- 'Payment and write off applied'
- );
-
- # Store the amountoutstanding value
- $lost_fee_line->discard_changes;
- my $outstanding = $lost_fee_line->amountoutstanding;
-
- my $credit_return_id = C4::Circulation::_FixAccountForLostAndFound( $item->itemnumber );
- my $credit_return = Koha::Account::Lines->find($credit_return_id);
-
- is( $account->balance, $processfee_amount - $payment_amount, 'Balance is PROCESSING - PAYMENT (LOST_FOUND)' );
-
- $lost_fee_line->discard_changes;
- is( $lost_fee_line->amountoutstanding + 0, 0, 'Lost fee has no outstanding amount' );
- is( $lost_fee_line->debit_type_code,
- 'LOST', 'Lost fee now still has account type of LOST' );
- is( $lost_fee_line->status, 'FOUND', "Lost fee now has account status of FOUND");
-
- is( $credit_return->credit_type_code, 'LOST_FOUND', 'An account line of type LOST_FOUND is added' );
- is( $credit_return->amount + 0,
- ($payment_amount + $outstanding ) * -1,
- 'The account line of type LOST_FOUND has an amount equal to the payment + outstanding'
- );
- is( $credit_return->amountoutstanding + 0,
- $payment_amount * -1,
- 'The account line of type LOST_FOUND has an amountoutstanding equal to the payment'
- );
-
- is( $account->balance,
- $processfee_amount - $payment_amount,
- 'The patron balance is the difference between the PROCESSING and the credit'
- );
- };
-
- subtest 'Partial payement, existing debits and AccountAutoReconcile' => sub {
-
- plan tests => 8;
-
- my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
- my $barcode = 'KD123456793';
- my $replacement_amount = 100;
- my $processfee_amount = 20;
-
- my $item_type = $builder->build_object(
- { class => 'Koha::ItemTypes',
- value => {
- notforloan => undef,
- rentalcharge => 0,
- defaultreplacecost => undef,
- processfee => 0,
- rentalcharge_daily => 0,
- }
- }
- );
- my $item = Koha::Item->new(
- {
- biblionumber => $biblio->biblionumber,
- homebranch => $library->branchcode,
- holdingbranch => $library->branchcode,
- barcode => $barcode,
- replacementprice => $replacement_amount,
- itype => $item_type->itemtype
- },
- )->store;
-
- AddIssue( $patron->unblessed, $barcode );
-
- # Simulate item marked as lost
- $item->itemlost(1)->store;
- LostItem( $item->itemnumber, 1 );
-
- my $lost_fee_lines = Koha::Account::Lines->search(
- { borrowernumber => $patron->id, itemnumber => $item->itemnumber, debit_type_code => 'LOST' } );
- 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, $replacement_amount, 'The right LOST amount is generated' );
- is( $lost_fee_line->amountoutstanding + 0,
- $replacement_amount, 'The right LOST amountountstanding is generated' );
-
- my $account = $patron->account;
- is( $account->balance, $replacement_amount, 'Balance is L' );
-
- # Partially pay fee
- my $payment_amount = 27;
- my $payment = $account->add_credit(
- { amount => $payment_amount,
- type => 'PAYMENT',
- interface => 'test',
- }
- );
- $payment->apply({ debits => [ $lost_fee_line ], offset_type => 'Payment' });
-
- is( $account->balance,
- $replacement_amount - $payment_amount,
- 'Payment applied'
- );
-
- my $manual_debit_amount = 80;
- $account->add_debit( { amount => $manual_debit_amount, type => 'OVERDUE', interface =>'test' } );
-
- is( $account->balance, $manual_debit_amount + $replacement_amount - $payment_amount, 'Manual debit applied' );
-
- t::lib::Mocks::mock_preference( 'AccountAutoReconcile', 1 );
-
- my $credit_return_id = C4::Circulation::_FixAccountForLostAndFound( $item->itemnumber );
- my $credit_return = Koha::Account::Lines->find($credit_return_id);
-
- is( $account->balance, $manual_debit_amount - $payment_amount, 'Balance is PROCESSING - payment (LOST_FOUND)' );
-
- my $manual_debit = Koha::Account::Lines->search({ borrowernumber => $patron->id, debit_type_code => 'OVERDUE', status => 'UNRETURNED' })->next;
- is( $manual_debit->amountoutstanding + 0, $manual_debit_amount - $payment_amount, 'reconcile_balance was called' );
- };
-};
-
subtest '_FixOverduesOnReturn' => sub {
plan tests => 14;
is( $accountline->status, 'RETURNED', 'Passed status has been used to set as RETURNED )');
};
-subtest '_FixAccountForLostAndFound returns undef if patron is deleted' => sub {
- plan tests => 1;
-
- my $manager = $builder->build_object({ class => "Koha::Patrons" });
- t::lib::Mocks::mock_userenv({ patron => $manager, branchcode => $manager->branchcode });
-
- my $biblio = $builder->build_sample_biblio({ author => 'Hall, Kylie' });
-
- my $branchcode = $library2->{branchcode};
-
- my $item = $builder->build_sample_item(
- {
- biblionumber => $biblio->biblionumber,
- library => $branchcode,
- replacementprice => 99.00,
- itype => $itemtype,
- }
- );
-
- my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
-
- ## Start with basic call, should just close out the open fine
- my $accountline = Koha::Account::Line->new(
- {
- borrowernumber => $patron->id,
- debit_type_code => 'LOST',
- status => undef,
- itemnumber => $item->itemnumber,
- amount => 99.00,
- amountoutstanding => 99.00,
- interface => 'test',
- }
- )->store();
-
- $patron->delete();
-
- my $return_value = C4::Circulation::_FixAccountForLostAndFound( $item->itemnumber );
-
- is( $return_value, undef, "_FixAccountForLostAndFound returns undef if patron is deleted" );
-
-};
-
subtest 'Set waiting flag' => sub {
plan tests => 11;