From 4e3fa45ab1c575affef3df8f68e5145f523a0122 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Thu, 28 Jun 2018 15:52:01 -0300 Subject: [PATCH] Bug 20997: ->apply should be applied to Koha::Account::Lines This patch makes ->apply get passed an object set class instead of single account lines. The change is fully covered by tests. Signed-off-by: Tomas Cohen Arazi --- Koha/Account/Line.pm | 55 +++++++++++++++-------------- t/db_dependent/Koha/Account/Lines.t | 45 +++++++++++++++++++---- 2 files changed, 67 insertions(+), 33 deletions(-) diff --git a/Koha/Account/Line.pm b/Koha/Account/Line.pm index 4d281cb2f7..2c5431dee1 100644 --- a/Koha/Account/Line.pm +++ b/Koha/Account/Line.pm @@ -128,14 +128,14 @@ sub void { =head3 apply - my $outstanding_amount = $credit->apply({ debit => $debit, [ offset_type => $offset_type ] }); + my $outstanding_amount = $credit->apply({ debits => $debits, [ offset_type => $offset_type ] }); =cut sub apply { my ( $self, $params ) = @_; - my $debit = $params->{debit}; + my $debits = $params->{debits}; my $offset_type = $params->{offset_type} // 'credit_applied'; unless ( $self->is_credit ) { @@ -144,12 +144,6 @@ sub apply { ); } - unless ( $debit->is_debit ) { - Koha::Exceptions::Account::IsNotDebit->throw( - error => 'Account line ' . $debit->id . 'is not a debit' - ); - } - my $available_credit = $self->amountoutstanding * -1; unless ( $available_credit > 0 ) { @@ -161,30 +155,37 @@ sub apply { my $schema = Koha::Database->new->schema; $schema->txn_do( sub { + foreach my $debit ( @{ $debits } ) { - my $amount_to_cancel; - my $owed = $debit->amountoutstanding; - - if ( $available_credit >= $owed ) { - $amount_to_cancel = $owed; - } - else { # $available_credit < $debit->amountoutstanding - $amount_to_cancel = $available_credit; - } + unless ( $debit->is_debit ) { + Koha::Exceptions::Account::IsNotDebit->throw( + error => 'Account line ' . $debit->id . 'is not a debit' + ); + } + my $amount_to_cancel; + my $owed = $debit->amountoutstanding; - # record the account offset - Koha::Account::Offset->new( - { credit_id => $self->id, - debit_id => $debit->id, - amount => $amount_to_cancel, - type => $offset_type, + if ( $available_credit >= $owed ) { + $amount_to_cancel = $owed; + } + else { # $available_credit < $debit->amountoutstanding + $amount_to_cancel = $available_credit; } - )->store(); - $available_credit -= $amount_to_cancel; + # record the account offset + Koha::Account::Offset->new( + { credit_id => $self->id, + debit_id => $debit->id, + amount => $amount_to_cancel, + type => $offset_type, + } + )->store(); + + $available_credit -= $amount_to_cancel; - $self->amountoutstanding( $available_credit * -1 )->store; - $debit->amountoutstanding( $owed - $amount_to_cancel )->store; + $self->amountoutstanding( $available_credit * -1 )->store; + $debit->amountoutstanding( $owed - $amount_to_cancel )->store; + } }); return $available_credit; diff --git a/t/db_dependent/Koha/Account/Lines.t b/t/db_dependent/Koha/Account/Lines.t index 1f1958a1a1..cfd4f20d67 100755 --- a/t/db_dependent/Koha/Account/Lines.t +++ b/t/db_dependent/Koha/Account/Lines.t @@ -94,7 +94,7 @@ subtest 'is_credit() and is_debit() tests' => sub { subtest 'apply() tests' => sub { - plan tests => 12; + plan tests => 24; $schema->storage->txn_begin; @@ -122,7 +122,7 @@ subtest 'apply() tests' => sub { $credit->discard_changes; $debit_1->discard_changes; - my $remaining_credit = $credit->apply( { debit => $debit_1, offset_type => 'Manual Credit' } ); + my $remaining_credit = $credit->apply( { debits => [ $debit_1 ], offset_type => 'Manual Credit' } ); is( $remaining_credit, 90, 'Remaining credit is correctly calculated' ); $credit->discard_changes; is( $credit->amountoutstanding * -1, $remaining_credit, 'Remaining credit correctly stored' ); @@ -137,28 +137,61 @@ subtest 'apply() tests' => sub { is( $THE_offest->amount * 1, 10, 'Amount was calculated correctly (less than the available credit)' ); is( $THE_offest->type, 'Manual Credit', 'Passed type stored correctly' ); - $remaining_credit = $credit->apply( { debit => $debit_2, offset_type => 'Manual Credit' } ); + $remaining_credit = $credit->apply( { debits => [ $debit_2 ] } ); is( $remaining_credit, 0, 'No remaining credit left' ); $credit->discard_changes; is( $credit->amountoutstanding * 1, 0, 'No outstanding credit' ); $debit_2->discard_changes; is( $debit_2->amountoutstanding * 1, 10, 'Outstanding amount decremented correctly' ); + $offsets = Koha::Account::Offsets->search( { credit_id => $credit->id, debit_id => $debit_2->id } ); + is( $offsets->count, 1, 'Only one offset is generated' ); + $THE_offest = $offsets->next; + is( $THE_offest->amount * 1, 10, 'Amount was calculated correctly (less than the available credit)' ); + is( $THE_offest->type, 'credit_applied', 'Defaults to credit_applied offset type' ); + throws_ok - { $debit_1->apply({ debit => $credit }); } + { $debit_1->apply({ debits => [ $credit ] }); } 'Koha::Exceptions::Account::IsNotCredit', '->apply() can only be used with credits'; throws_ok - { $credit->apply({ debit => $credit }); } + { $credit->apply({ debits => [ $credit ] }); } 'Koha::Exceptions::Account::IsNotDebit', '->apply() can only be applied to credits'; throws_ok - { $credit->apply({ debit => $debit_1 }); } + { $credit->apply({ debits => [ $debit_1 ] }); } 'Koha::Exceptions::Account::NoAvailableCredit', '->apply() can only be used with outstanding credits'; + my $credit_2 = $account->add_credit({ amount => 20 }); + my $debit_3 = Koha::Account::Line->new( + { borrowernumber => $patron->id, + accounttype => "F", + amount => 100, + amountoutstanding => 100 + } + )->store; + + my $debits = Koha::Account::Lines->search({ id => { -in => [ $debit_1->id, $debit_2->id, $debit_3->id, $credit->id ] } }); + throws_ok { + $credit_2->apply( { debits => $debits, offset_type => 'Manual Credit' } ); } + 'Koha::Exceptions::Account::IsNotDebit', + '->apply() rolls back if any of the passed lines is not a debit'; + + is( $debit_1->discard_changes->amountoutstanding, 0, 'No changes to already cancelled debit' ); + is( $debit_2->discard_changes->amountoutstanding, 10, 'Debit cancelled' ); + is( $debit_3->discard_changes->amountoutstanding, 100, 'Outstanding amount correctly calculated' ); + is( $credit_2->discard_changes->amountoutstanding, 20, 'No changes made' ); + + $debits = Koha::Account::Lines->search({ id => { -in => [ $debit_1->id, $debit_2->id, $debit_3->id ] } }); + $remaining_credit = $credit_2->apply( { debits => $debits, offset_type => 'Manual Credit' } ); + + is( $debit_1->discard_changes->amountoutstanding, 0, 'No changes to already cancelled debit' ); + is( $debit_2->discard_changes->amountoutstanding, 0, 'Debit cancelled' ); + is( $debit_3->discard_changes->amountoutstanding, 90, 'Outstanding amount correctly calculated' ); + is( $credit_2->discard_changes->amountoutstanding, 0, 'No remaining credit' ); $schema->storage->txn_rollback; }; -- 2.18.0