From ff5096cdd2f319720b1ffa5921963834331bfbfa Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Thu, 21 Nov 2019 12:10:41 +0000 Subject: [PATCH] Bug 23442: Add 'reduce' method to Koha::Account::Line This enhancement adds a 'reduce' method to Koha::Account::Line which can be used to reduce a charge/debit by adding a credit to offset against the amount outstanding. It may be used to apply a discount whilst retaining the original debit amounts or to apply a full or partial refund for example when a lost item is found and returned. The created credit will be immediately applied against the debit unless the debit has already been paid, in which case a 'zero' offset will be added to maintain a link to the debit but the outstanding credit will be left so it may be applied to other debts. Test Plan: 1) Run the included tests and verify they pass. 2) Signoff --- Koha/Account/Line.pm | 106 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/Koha/Account/Line.pm b/Koha/Account/Line.pm index 09d4338eef..e55d87d73a 100644 --- a/Koha/Account/Line.pm +++ b/Koha/Account/Line.pm @@ -189,6 +189,112 @@ sub void { } +=head3 reduce + + $charge_accountline->reduce({ + reduction_type => $reduction_type + }); + +Used to 'reduce' a charge/debit by adding a credit to offset against the amount +outstanding. + +May be used to apply a discount whilst retaining the original debit amounts or +to apply a full or partial refund for example when a lost item is found and +returned. + +It will immediately be applied to the given debit unless the debit has already +been paid, in which case a 'zero' offset will be added to maintain a link to +the debit but the outstanding credit will be left so it may be applied to other +debts. + +Reduction type may be one of: + +* DISCOUNT +* REFUND + +Returns the reduction accountline (which will be a credit) + +=cut + +sub reduce { + my ( $self, $params ) = @_; + + # Make sure it is a charge we are reducing + unless ( $self->is_debit ) { + Koha::Exceptions::Account::IsNotDebit->throw( + error => 'Account line ' . $self->id . 'is not a debit' ); + } + + unless ( $params->{interface} ) { + Koha::Exceptions::MissingParameter->throw( + error => 'The interface parameter is mandatory' + ); + } + + my $status = { 'REFUND' => 'REFUNDED', 'DISCOUNT' => 'DISCOUNTED' }; + + $params->{branch} //= $self->branchcode; + + my $reduction; + $self->_result->result_source->schema->txn_do( + sub { + + # A 'reduction' is a 'credit' + $reduction = Koha::Account::Line->new( + { + date => \'NOW()', + amount => 0 - $params->{amount}, + credit_type_code => $params->{reduction_type}, + status => 'ADDED', + amountoutstanding => 0 - $params->{amount}, + manager_id => $params->{staff_id}, + borrowernumber => $self->borrowernumber, + interface => $params->{interface}, + branchcode => $params->{branch}, + } + )->store(); + + my $reduction_offset = Koha::Account::Offset->new( + { + credit_id => $reduction->accountlines_id, + type => uc( $params->{reduction_type} ), + amount => $params->{amount} + } + )->store(); + + # Link reduction to charge (and apply as required) + my $debit_outstanding = $self->amountoutstanding; + if ( $debit_outstanding >= $params->{amount} ) { + + my $credit_outstanding = $reduction->apply( + { + debits => [$self], + offset_type => uc( $params->{reduction_type} ) + } + ); + $reduction->status('APPLIED')->store(); + } + else { + + # Zero amount offset used to link original 'debit' to reduction 'credit' + my $link_reduction_offset = Koha::Account::Offset->new( + { + credit_id => $reduction->accountlines_id, + debit_id => $self->accountlines_id, + type => uc( $params->{reduction_type} ), + amount => 0 + } + )->store(); + } + + # Update status of original debit + $self->status( $status->{ $params->{reduction_type} } )->store; + } + ); + + return $reduction; +} + =head3 apply my $debits = $account->outstanding_debits; -- 2.20.1