Bug 18501: (QA follow-up) Migrate and update unit tests
authorMartin Renvoize <martin.renvoize@ptfs-europe.com>
Fri, 14 Aug 2020 16:16:04 +0000 (17:16 +0100)
committerJonathan Druart <jonathan.druart@bugs.koha-community.org>
Thu, 20 Aug 2020 10:31:59 +0000 (12:31 +0200)
This patch moves the _FixAccountForLostAndFound tests from Circulation.t
to Koha/Items.t and updates then to call an item store as aposed to the
now removed _FixAccountForLostAndFound method.

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>

t/db_dependent/Circulation.t
t/db_dependent/Koha/Items.t

index 4bdae84..1dbf754 100755 (executable)
@@ -18,7 +18,7 @@
 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 );
@@ -2669,397 +2669,6 @@ subtest 'AddReturn | is_overdue' => sub {
     };
 };
 
-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;
 
@@ -3145,48 +2754,6 @@ subtest '_FixOverduesOnReturn' => sub {
     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;
 
index 975060b..68232df 100644 (file)
@@ -65,24 +65,30 @@ my $retrieved_item_1 = Koha::Items->find( $new_item_1->itemnumber );
 is( $retrieved_item_1->barcode, $new_item_1->barcode, 'Find a item by id should return the correct item' );
 
 subtest 'store' => sub {
-    plan tests => 5;
+    plan tests => 6;
 
     my $biblio = $builder->build_sample_biblio;
-    my $today = dt_from_string->set( hour => 0, minute => 0, second => 0 );
-    my $item = Koha::Item->new(
+    my $today  = dt_from_string->set( hour => 0, minute => 0, second => 0 );
+    my $item   = Koha::Item->new(
         {
             homebranch    => $library->{branchcode},
             holdingbranch => $library->{branchcode},
             biblionumber  => $biblio->biblionumber,
             location      => 'my_loc',
         }
-    )->store
-    ->get_from_storage;
-
-    is( t::lib::Dates::compare($item->replacementpricedate, $today), 0, 'replacementpricedate must have been set to today if not given');
-    is( t::lib::Dates::compare($item->datelastseen,         $today), 0, 'datelastseen must have been set to today if not given');
-    is( $item->itype, $biblio->biblioitem->itemtype, 'items.itype must have been set to biblioitem.itemtype is not given');
-    is( $item->permanent_location, $item->location, 'permanent_location must have been set to location if not given' );
+    )->store->get_from_storage;
+
+    is( t::lib::Dates::compare( $item->replacementpricedate, $today ),
+        0, 'replacementpricedate must have been set to today if not given' );
+    is( t::lib::Dates::compare( $item->datelastseen, $today ),
+        0, 'datelastseen must have been set to today if not given' );
+    is(
+        $item->itype,
+        $biblio->biblioitem->itemtype,
+        'items.itype must have been set to biblioitem.itemtype is not given'
+    );
+    is( $item->permanent_location, $item->location,
+        'permanent_location must have been set to location if not given' );
     $item->delete;
 
     subtest '*_on updates' => sub {
@@ -129,6 +135,630 @@ subtest 'store' => sub {
         }
     };
 
+    subtest '_lost_found_trigger' => sub {
+        plan tests => 6;
+
+        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' } );
+
+        $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,
+                }
+            );
+
+            C4::Circulation::AddIssue( $patron->unblessed, $item->barcode );
+
+            # Simulate item marked as lost
+            $item->itemlost(3)->store;
+            C4::Circulation::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' } );
+
+            # Simulate item marked as found
+            $item->itemlost(0)->store;
+            is( $item->{_refunded}, 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 - No Refund" );
+
+            is( $patron->account->balance,
+                -0, 'The patron balance is 0, everything was written off' );
+        };
+
+        subtest 'Full payment tests' => sub {
+
+            plan tests => 14;
+
+            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
+                }
+            );
+
+            my $issue =
+              C4::Circulation::AddIssue( $patron->unblessed, $item->barcode );
+
+            # Simulate item marked as lost
+            $item->itemlost(1)->store;
+            C4::Circulation::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;
+
+            # Pay off the debt
+            my $credit = $account->add_credit(
+                {
+                    amount    => $account->balance,
+                    type      => 'PAYMENT',
+                    interface => 'test',
+                }
+            );
+            $credit->apply(
+                { debits => [ $debts->as_list ], offset_type => 'Payment' } );
+
+            # Simulate item marked as found
+            $item->itemlost(0)->store;
+            is( $item->{_refunded}, 1, 'Refund triggered' );
+
+            my $credit_return = Koha::Account::Lines->search(
+                {
+                    itemnumber       => $item->itemnumber,
+                    credit_type_code => 'LOST_FOUND'
+                },
+                { rows => 1 }
+            )->single;
+
+            ok( $credit_return, '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 => 14;
+
+            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
+                }
+            );
+
+            my $issue =
+              C4::Circulation::AddIssue( $patron->unblessed, $item->barcode );
+
+            # Simulate item marked as lost
+            $item->itemlost(3)->store;
+            C4::Circulation::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' );
+
+            # Simulate item marked as found
+            $item->itemlost(0)->store;
+            is( $item->{_refunded}, 1, 'Refund triggered' );
+
+            my $credit_return = Koha::Account::Lines->search(
+                {
+                    itemnumber       => $item->itemnumber,
+                    credit_type_code => 'LOST_FOUND'
+                },
+                { rows => 1 }
+            )->single;
+
+            ok( $credit_return, '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 => 17;
+
+            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
+                }
+            );
+
+            my $issue =
+              C4::Circulation::AddIssue( $patron->unblessed, $item->barcode );
+
+            # Simulate item marked as lost
+            $item->itemlost(1)->store;
+            C4::Circulation::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;
+
+            # Simulate item marked as found
+            $item->itemlost(0)->store;
+            is( $item->{_refunded}, 1, 'Refund triggered' );
+
+            my $credit_return = Koha::Account::Lines->search(
+                {
+                    itemnumber       => $item->itemnumber,
+                    credit_type_code => 'LOST_FOUND'
+                },
+                { rows => 1 }
+            )->single;
+
+            ok( $credit_return, 'An account line of type LOST_FOUND is added' );
+
+            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->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 payment, existing debits and AccountAutoReconcile' =>
+          sub {
+
+            plan tests => 10;
+
+            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;
+
+            my $issue =
+              C4::Circulation::AddIssue( $patron->unblessed, $barcode );
+
+            # Simulate item marked as lost
+            $item->itemlost(1)->store;
+            C4::Circulation::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 );
+
+            # Simulate item marked as found
+            $item->itemlost(0)->store;
+            is( $item->{_refunded}, 1, 'Refund triggered' );
+
+            my $credit_return = Koha::Account::Lines->search(
+                {
+                    itemnumber       => $item->itemnumber,
+                    credit_type_code => 'LOST_FOUND'
+                },
+                { rows => 1 }
+            )->single;
+
+            ok( $credit_return, 'An account line of type LOST_FOUND is added' );
+
+            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 'Patron deleted' => sub {
+            plan tests => 1;
+
+            my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
+            my $barcode            = 'KD123456794';
+            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;
+
+            my $issue =
+              C4::Circulation::AddIssue( $patron->unblessed, $barcode );
+
+            # Simulate item marked as lost
+            $item->itemlost(1)->store;
+            C4::Circulation::LostItem( $item->itemnumber, 1 );
+
+            $issue->delete();
+            $patron->delete();
+
+            # Simulate item marked as found
+            $item->itemlost(0)->store;
+            is( $item->{_refunded}, undef, 'No refund triggered' );
+
+        };
+    };
 };
 
 subtest 'get_transfer' => sub {