From 4b9a5b13ce03cf9783db5981f7bf582c45f5e0b8 Mon Sep 17 00:00:00 2001
From: Tomas Cohen Arazi <tomascohen@theke.io>
Date: Tue, 26 Jun 2018 11:52:44 -0300
Subject: [PATCH] Bug 20997: Add Koha::Account::Line::apply method
This patch implements the ->apply() method for account lines.
It will only work on credit lines, and raise an exception otherwise.
It implements ->is_credit() as well.
To test:
- Apply this patch
- Run:
$ kshell
k$ prove t/db_dependent/Koha/Account/Lines.t
=> SUCCESS: Tests pass!
- Check all use cases are covered by the tests
- Sign off :-D
---
Koha/Account/Line.pm | 85 +++++++++++++++++++++++++++++++++++++-
Koha/Exceptions/Account.pm | 66 +++++++++++++++++++++++++++++
2 files changed, 149 insertions(+), 2 deletions(-)
create mode 100644 Koha/Exceptions/Account.pm
diff --git a/Koha/Account/Line.pm b/Koha/Account/Line.pm
index b32f9a7b91..7ee5843556 100644
--- a/Koha/Account/Line.pm
+++ b/Koha/Account/Line.pm
@@ -22,9 +22,10 @@ use Data::Dumper;
use C4::Log qw(logaction);
+use Koha::Account::Offsets;
use Koha::Database;
+use Koha::Exceptions::Account;
use Koha::Items;
-use Koha::Account::Offsets;
use base qw(Koha::Object);
@@ -34,7 +35,7 @@ Koha::Account::Lines - Koha accountline Object class
=head1 API
-=head2 Class Methods
+=head2 Class methods
=cut
@@ -125,6 +126,86 @@ sub void {
}
+=head3 apply
+
+ my $outstanding_amount = $credit->apply({ debit => $debit, [ offset_type => $offset_type ] });
+
+=cut
+
+sub apply {
+ my ( $self, $params ) = @_;
+
+ my $debit = $params->{debit};
+ my $offset_type = $params->{offset_type} // 'credit_applied';
+
+ unless ( $self->is_credit ) {
+ Koha::Exceptions::Account::IsNotCredit->throw(
+ error => 'Account line ' . $self->id . ' is not a credit'
+ );
+ }
+
+ unless ( !$debit->is_credit ) {
+ Koha::Exceptions::Account::IsNotDebit->throw(
+ error => 'Account line ' . $debit->id . 'is not a debit'
+ );
+ }
+
+ my $available_credit = $self->amountoutstanding * -1;
+
+ unless ( $available_credit > 0 ) {
+ Koha::Exceptions::Account::NoAvailableCredit->throw(
+ error => 'Outstanding credit is ' . $available_credit . ' and cannot be applied'
+ );
+ }
+
+ my $schema = Koha::Database->new->schema;
+
+ $schema->txn_do( sub {
+
+ 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;
+ }
+
+ # 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;
+ });
+
+ return $available_credit;
+}
+
+=head3 is_credit
+
+ my $bool = $line->is_credit;
+
+=cut
+
+sub is_credit {
+ my ($self) = @_;
+
+ return ( $self->amount < 0 );
+}
+
+=head2 Internal methods
+
+=cut
+
=head3 _type
=cut
diff --git a/Koha/Exceptions/Account.pm b/Koha/Exceptions/Account.pm
new file mode 100644
index 0000000000..5cafe5f9ab
--- /dev/null
+++ b/Koha/Exceptions/Account.pm
@@ -0,0 +1,66 @@
+package Koha::Exceptions::Account;
+
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Exception::Class (
+
+ 'Koha::Exceptions::Account' => {
+ description => 'Something went wrong!',
+ },
+ 'Koha::Exceptions::Account::IsNotCredit' => {
+ isa => 'Koha::Exceptions::Account',
+ description => 'Account line is not a credit'
+ },
+ 'Koha::Exceptions::Account::IsNotDebit' => {
+ isa => 'Koha::Exceptions::Account',
+ description => 'Account line is not a credit'
+ },
+ 'Koha::Exceptions::Account::NoAvailableCredit' => {
+ isa => 'Koha::Exceptions::Account',
+ description => 'No outstanding credit'
+ }
+);
+
+=head1 NAME
+
+Koha::Exceptions::Account - Base class for Account exceptions
+
+=head1 Exceptions
+
+=head2 Koha::Exceptions::Account
+
+Generic Account exception
+
+=head2 Koha::Exceptions::Account::IsNotCredit
+
+Exception to be used when an action on an account line requires it to be a
+credit and it isn't.
+
+=head2 Koha::Exceptions::Account::IsNotDebit
+
+Exception to be used when an action on an account line requires it to be a
+debit and it isn't.
+
+=head2 Koha::Exceptions::Account::NoAvailableCredit
+
+Exception to be used when a credit has no amount outstanding and is required
+to be applied to outstanding debits.
+
+=cut
+
+1;
--
2.18.0