From d3c6a0a7eb0c9ee93b8d64e21a0813d553d5b83b Mon Sep 17 00:00:00 2001
From: Kyle M Hall <kyle@bywatersolutions.com>
Date: Mon, 11 Jul 2016 15:36:54 +0000
Subject: [PATCH] Bug 16899 - Add ability to disallow overpayments
Some SIP services ( such as Comprise ) require that an attempt at
over-paying a patron's account via SIP2 should fail, rather than create
a credit on the account. We should make this a configurable option on a
per-login basis in the SIP2 config file.
Test Plan:
1) Apply this patch
2) Enable the new parameter
disallow_overpayment="1"
for the login to be used in this test.
3) Restart your SIP server
4) Create or find a patron with fines
5) Attempt to send a payment via SIP for more than what the
patron's balance is
6) Note the response indicates a payment failure
7) Attempt to send a payment via SIP for the account balance or
less
8) Note the response indicates the payment has succeeded
9) Verify in Koha that the payment was processed
---
C4/SIP/ILS.pm | 4 ++--
C4/SIP/ILS/Transaction/FeePayment.pm | 11 ++++++++++-
C4/SIP/Sip/MsgType.pm | 3 ++-
Koha/Account/Lines.pm | 10 ++++++++++
Koha/Patron.pm | 17 +++++++++++++++++
etc/SIPconfig.xml | 2 +-
t/db_dependent/Patron.t | 23 ++++++++++++++++++++++-
7 files changed, 64 insertions(+), 6 deletions(-)
diff --git a/C4/SIP/ILS.pm b/C4/SIP/ILS.pm
index 35879af..5d3f189 100644
--- a/C4/SIP/ILS.pm
+++ b/C4/SIP/ILS.pm
@@ -247,7 +247,7 @@ sub end_patron_session {
}
sub pay_fee {
- my ($self, $patron_id, $patron_pwd, $fee_amt, $fee_type, $pay_type, $fee_id, $trans_id, $currency, $is_writeoff) = @_;
+ my ($self, $patron_id, $patron_pwd, $fee_amt, $fee_type, $pay_type, $fee_id, $trans_id, $currency, $is_writeoff, $disallow_overpayment ) = @_;
my $trans = C4::SIP::ILS::Transaction::FeePayment->new();
@@ -258,7 +258,7 @@ sub pay_fee {
$trans->screen_msg('Invalid patron barcode.');
return $trans;
}
- my $ok = $trans->pay( $patron->{borrowernumber}, $fee_amt, $pay_type, $fee_id, $is_writeoff );
+ my $ok = $trans->pay( $patron->{borrowernumber}, $fee_amt, $pay_type, $fee_id, $is_writeoff, $disallow_overpayment );
$trans->ok($ok);
return $trans;
diff --git a/C4/SIP/ILS/Transaction/FeePayment.pm b/C4/SIP/ILS/Transaction/FeePayment.pm
index e2b73cd..7baee6c 100644
--- a/C4/SIP/ILS/Transaction/FeePayment.pm
+++ b/C4/SIP/ILS/Transaction/FeePayment.pm
@@ -21,7 +21,7 @@ use strict;
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use C4::Accounts qw(recordpayment makepayment WriteOffFee);
-use Koha::Account::Lines;
+use Koha::Patrons;
use parent qw(C4::SIP::ILS::Transaction);
@@ -48,9 +48,18 @@ sub pay {
my $type = shift;
my $fee_id = shift;
my $is_writeoff = shift;
+ my $disallow_overpayment = shift;
warn("RECORD:$borrowernumber::$amt");
+ if ($disallow_overpayment) {
+ my $patron = Koha::Patrons->find($borrowernumber);
+ return 0 unless $patron;
+
+ my $balance = $patron->account_balance();
+ return 0 if $balance < $amt;
+ }
+
my $fee = $fee_id ? Koha::Account::Lines->find($fee_id) : undef;
if ($is_writeoff) { # Writeoffs require a fee id to be sent
diff --git a/C4/SIP/Sip/MsgType.pm b/C4/SIP/Sip/MsgType.pm
index 3660aa4..df9957e 100644
--- a/C4/SIP/Sip/MsgType.pm
+++ b/C4/SIP/Sip/MsgType.pm
@@ -1068,6 +1068,7 @@ sub handle_fee_paid {
my $status;
my $resp = FEE_PAID_RESP;
+ my $disallow_overpayment = $server->{account}->{disallow_overpayment};
my $payment_type_writeoff = $server->{account}->{payment_type_writeoff};
my $is_writeoff = $pay_type eq $payment_type_writeoff;
@@ -1080,7 +1081,7 @@ sub handle_fee_paid {
$ils->check_inst_id( $inst_id, "handle_fee_paid" );
- $status = $ils->pay_fee( $patron_id, $patron_pwd, $fee_amt, $fee_type, $pay_type, $fee_id, $trans_id, $currency, $is_writeoff );
+ $status = $ils->pay_fee( $patron_id, $patron_pwd, $fee_amt, $fee_type, $pay_type, $fee_id, $trans_id, $currency, $is_writeoff, $disallow_overpayment );
$resp .= ( $status->ok ? 'Y' : 'N' ) . timestamp;
$resp .= add_field( FID_INST_ID, $inst_id );
diff --git a/Koha/Account/Lines.pm b/Koha/Account/Lines.pm
index 0e0677c..33e5e22 100644
--- a/Koha/Account/Lines.pm
+++ b/Koha/Account/Lines.pm
@@ -36,6 +36,16 @@ Koha::Account::Lines - Koha Account Line Object set class
=cut
+=head3 amount_outstanding
+
+=cut
+
+sub amount_outstanding {
+ my ( $self ) = @_;
+
+ return $self->_resultset()->get_column('amountoutstanding')->sum();
+}
+
=head3 type
=cut
diff --git a/Koha/Patron.pm b/Koha/Patron.pm
index 42b066b..34bb090 100644
--- a/Koha/Patron.pm
+++ b/Koha/Patron.pm
@@ -24,6 +24,7 @@ use Carp;
use C4::Context;
use C4::Log;
+use Koha::Account::Lines;
use Koha::Database;
use Koha::DateUtils;
use Koha::Issues;
@@ -44,6 +45,22 @@ Koha::Patron - Koha Patron Object class
=cut
+=head3 account_balance
+
+Returns the total amount owed by this patron
+
+=cut
+
+sub account_balance {
+ my ($self) = @_;
+
+ return Koha::Account::Lines->search(
+ {
+ borrowernumber => $self->id
+ }
+ )->amount_outstanding();
+}
+
=head3 guarantor
Returns a Koha::Patron object for this patron's guarantor
diff --git a/etc/SIPconfig.xml b/etc/SIPconfig.xml
index 96cd1c8..70d802e 100644
--- a/etc/SIPconfig.xml
+++ b/etc/SIPconfig.xml
@@ -44,7 +44,7 @@
</listeners>
<accounts>
- <login id="term1" password="term1" delimiter="|" error-detect="enabled" institution="CPL" encoding="ascii" checked_in_ok="1" payment_type_writeoff="06" />
+ <login id="staff" password="staff" delimiter="|" error-detect="enabled" institution="CPL" encoding="ascii" checked_in_ok="1" payment_type_writeoff="06" disallow_overpayment="1" />
<login id="koha" password="koha" delimiter="|" error-detect="enabled" institution="kohalibrary" encoding="utf8" />
<login id="koha2" password="koha" institution="kohalibrary2" terminator="CR" />
<login id="lpl-sc" password="1234" institution="LPL" />
diff --git a/t/db_dependent/Patron.t b/t/db_dependent/Patron.t
index 11c57fe..5ea9b6c 100755
--- a/t/db_dependent/Patron.t
+++ b/t/db_dependent/Patron.t
@@ -17,11 +17,12 @@
use Modern::Perl;
-use Test::More tests => 13;
+use Test::More tests => 14;
use Test::Warn;
use C4::Context;
use Koha::Database;
+use Koha::Account::Line;
BEGIN {
use_ok('Koha::Object');
@@ -50,6 +51,26 @@ my $borrowernumber = $object->borrowernumber;
my $patron = $schema->resultset('Borrower')->find( $borrowernumber );
is( $patron->surname(), "Test Surname", "Object found in database" );
+my $accountline_1 = Koha::Account::Line->new(
+ {
+ borrowernumber => $patron->id,
+ accountno => 1,
+ amount => 10.00,
+ amountoutstanding => 5.00,
+ }
+)->store();
+
+my $accountline_2 = Koha::Account::Line->new(
+ {
+ borrowernumber => $patron->id,
+ accountno => 2,
+ amount => 7.00,
+ amountoutstanding => 7.00,
+ }
+)->store();
+
+is( $object->account_balance, '12.000000', "Got correct patron account balance" );
+
is( $object->is_changed(), 0, "Object is unchanged" );
$object->surname("Test Surname");
is( $object->is_changed(), 0, "Object is still unchanged" );
--
2.1.4