Bugzilla – Attachment 118419 Details for
Bug 27971
The VOID method should be updated to respect double-entry accounting
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 27971: Update void method to use double entry accounting
Bug-27971-Update-void-method-to-use-double-entry-a.patch (text/plain), 9.40 KB, created by
Martin Renvoize (ashimema)
on 2021-03-17 16:25:27 UTC
(
hide
)
Description:
Bug 27971: Update void method to use double entry accounting
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2021-03-17 16:25:27 UTC
Size:
9.40 KB
patch
obsolete
>From 2d28670ddd44054d2032691912f96edb45fd40e9 Mon Sep 17 00:00:00 2001 >From: Martin Renvoize <martin.renvoize@ptfs-europe.com> >Date: Wed, 17 Mar 2021 09:10:17 +0000 >Subject: [PATCH] Bug 27971: Update void method to use double entry accounting > >This patch adds double-entry accounting to the Koha::Account::Line->void method. > >This results in the addition of a VOID debit type line that is offset >against the original credit type line that is being voided. This allows >us to accurately record when the void took place, at what branch and by >whome the void was triggered. > >Test plan >1/ Apply the database update >2/ Add some debts to a borrower account >3/ Pay those debts >4/ Void the payment >5/ A new 'VOID' line should appear on the account for the full amount of >the original payment. >6/ Payments should have all been reversed >7/ t/db_dependent/Koha/Account/Line.t should still pass >8/ Signoff >--- > Koha/Account/Line.pm | 88 ++++++++++++++++--- > Koha/Item.pm | 2 +- > .../mysql/mandatory/account_debit_types.sql | 3 +- > .../mysql/mandatory/account_offset_types.sql | 3 +- > members/boraccount.pl | 8 +- > t/db_dependent/Koha/Account/Line.t | 6 +- > 6 files changed, 89 insertions(+), 21 deletions(-) > >diff --git a/Koha/Account/Line.pm b/Koha/Account/Line.pm >index 2cc81993ef..650008fb0b 100644 >--- a/Koha/Account/Line.pm >+++ b/Koha/Account/Line.pm >@@ -210,7 +210,10 @@ sub debits { > > =head3 void > >- $payment_accountline->void(); >+ $payment_accountline->void({ >+ interface => $interface, >+ [ staff_id => $staff_id, branch => $branchcode ] >+ }); > > Used to 'void' (or reverse) a payment/credit. It will roll back any offsets > created by the application of this credit upon any debits and mark the credit >@@ -219,17 +222,74 @@ as 'void' by updating it's status to "VOID". > =cut > > sub void { >- my ($self) = @_; >+ my ($self, $params) = @_; >+ >+ # Make sure it is a credit we are voiding >+ unless ( $self->is_credit ) { >+ Koha::Exceptions::Account::IsNotCredit->throw( >+ error => 'Account line ' . $self->id . 'is not a credit' ); >+ } > >- # Make sure it is a payment we are voiding >- return unless $self->amount < 0; >+ # Make sure it is not already voided >+ if ( $self->status && $self->status eq 'VOID' ) { >+ Koha::Exceptions::Account->throw( >+ error => 'Account line ' . $self->id . 'is already void' ); >+ } >+ >+ # Check for mandatory parameters >+ my @mandatory = ( 'interface' ); >+ for my $param (@mandatory) { >+ unless ( defined( $params->{$param} ) ) { >+ Koha::Exceptions::MissingParameter->throw( >+ error => "The $param parameter is mandatory" ); >+ } >+ } >+ >+ # More mandatory parameters >+ if ( $params->{interface} eq 'intranet' ) { >+ my @optional = ( 'staff_id', 'branch' ); >+ for my $param (@optional) { >+ unless ( defined( $params->{$param} ) ) { >+ Koha::Exceptions::MissingParameter->throw( error => >+"The $param parameter is mandatory when interface is set to 'intranet'" >+ ); >+ } >+ } >+ } > >+ # Find any applied offsets for the credit so we may reverse them > my @account_offsets = > Koha::Account::Offsets->search( > { credit_id => $self->id, amount => { '<' => 0 } } ); > >+ my $void; > $self->_result->result_source->schema->txn_do( > sub { >+ >+ # A 'void' is a 'debit' >+ $void = Koha::Account::Line->new( >+ { >+ borrowernumber => $self->borrowernumber, >+ date => \'NOW()', >+ debit_type_code => 'VOID', >+ amount => $self->amount * -1, >+ amountoutstanding => $self->amount * -1, >+ manager_id => $params->{staff_id}, >+ interface => $params->{interface}, >+ branchcode => $params->{branch}, >+ } >+ )->store(); >+ >+ # Record the creation offset >+ Koha::Account::Offset->new( >+ { >+ debit_id => $void->id, >+ type => 'VOID', >+ amount => $self->amount * -1 >+ } >+ )->store(); >+ >+ # Reverse any applied payments > foreach my $account_offset (@account_offsets) { > my $fee_paid = > Koha::Account::Lines->find( $account_offset->debit_id ); >@@ -246,11 +306,18 @@ sub void { > credit_id => $self->id, > debit_id => $fee_paid->id, > amount => $amount_paid, >- type => 'Void Payment', >+ type => 'VOID', > } > )->store(); > } > >+ # Link void to payment >+ $self->set({ >+ amountoutstanding => $self->amount, >+ status => 'VOID' >+ })->store(); >+ $self->apply({ debits => [$void]}); >+ > if ( C4::Context->preference("FinesLog") ) { > logaction( > "FINES", 'VOID', >@@ -273,18 +340,11 @@ sub void { > ) > ); > } >- >- $self->set( >- { >- status => 'VOID', >- amountoutstanding => 0, >- amount => 0, >- } >- ); >- $self->store(); > } > ); > >+ $void->discard_changes; >+ return $void; > } > > =head3 cancel >diff --git a/Koha/Item.pm b/Koha/Item.pm >index c0da07c4b9..0bdb242f8c 100644 >--- a/Koha/Item.pm >+++ b/Koha/Item.pm >@@ -1056,7 +1056,7 @@ sub _set_found_trigger { > > if ( $refund ) { > # Revert the forgive credit >- $refund->void(); >+ $refund->void({ interface => 'trigger' }); > $self->{_restored} = 1; > } > >diff --git a/installer/data/mysql/mandatory/account_debit_types.sql b/installer/data/mysql/mandatory/account_debit_types.sql >index 4e70bab286..8a133197fe 100644 >--- a/installer/data/mysql/mandatory/account_debit_types.sql >+++ b/installer/data/mysql/mandatory/account_debit_types.sql >@@ -12,4 +12,5 @@ INSERT INTO account_debit_types ( code, description, can_be_invoiced, can_be_sol > ('RENT_RENEW', 'Renewal of rental item', 0, 0, NULL, 1), > ('RENT_DAILY_RENEW', 'Renewal of daily rental item', 0, 0, NULL, 1), > ('RESERVE', 'Hold fee', 0, 0, NULL, 1), >-('RESERVE_EXPIRED', 'Hold waiting too long', 0, 0, NULL, 1); >+('RESERVE_EXPIRED', 'Hold waiting too long', 0, 0, NULL, 1), >+('VOID', 'Credit has been voided', 0, 0, NULL, 1); >diff --git a/installer/data/mysql/mandatory/account_offset_types.sql b/installer/data/mysql/mandatory/account_offset_types.sql >index 523300b003..040135b9f9 100644 >--- a/installer/data/mysql/mandatory/account_offset_types.sql >+++ b/installer/data/mysql/mandatory/account_offset_types.sql >@@ -23,4 +23,5 @@ INSERT INTO account_offset_types ( type ) VALUES > ('PAYOUT'), > ('DISCOUNT'), > ('REFUND'), >-('CANCELLATION'); >+('CANCELLATION'), >+('VOID'); >diff --git a/members/boraccount.pl b/members/boraccount.pl >index ebe69db39c..2aa7766f98 100755 >--- a/members/boraccount.pl >+++ b/members/boraccount.pl >@@ -72,7 +72,13 @@ my $registerid = $input->param('registerid'); > if ( $action eq 'void' ) { > my $payment_id = scalar $input->param('accountlines_id'); > my $payment = Koha::Account::Lines->find( $payment_id ); >- $payment->void(); >+ $payment->void( >+ { >+ branch => $library_id, >+ staff_id => $logged_in_user->id, >+ interface => 'intranet', >+ } >+ ); > } > > if ( $action eq 'payout' ) { >diff --git a/t/db_dependent/Koha/Account/Line.t b/t/db_dependent/Koha/Account/Line.t >index 4a18526dac..dffa5ebfcc 100755 >--- a/t/db_dependent/Koha/Account/Line.t >+++ b/t/db_dependent/Koha/Account/Line.t >@@ -744,7 +744,7 @@ subtest "void() tests" => sub { > is( $line1->amountoutstanding+0, 0, 'First fee has amount outstanding of 0' ); > is( $line2->amountoutstanding+0, 0, 'Second fee has amount outstanding of 0' ); > >- my $ret = $account_payment->void(); >+ my $ret = $account_payment->void({ interface => 'test' }); > > is( ref($ret), 'Koha::Account::Line', 'Void returns the account line' ); > is( $account->balance(), 30, "Account balance is again 30" ); >@@ -755,7 +755,7 @@ subtest "void() tests" => sub { > > is( $account_payment->credit_type_code, 'PAYMENT', 'Voided payment credit_type_code is still PAYMENT' ); > is( $account_payment->status, 'VOID', 'Voided payment status is VOID' ); >- is( $account_payment->amount+0, 0, 'Voided payment amount is 0' ); >+ is( $account_payment->amount+0, -30, 'Voided payment amount is -30' ); > is( $account_payment->amountoutstanding+0, 0, 'Voided payment amount outstanding is 0' ); > > is( $line1->amountoutstanding+0, 10, 'First fee again has amount outstanding of 10' ); >@@ -763,7 +763,7 @@ subtest "void() tests" => sub { > > # Accountlines that are not credits should be un-voidable > my $line1_pre = $line1->unblessed(); >- $ret = $line1->void(); >+ $ret = $line1->void({ interface => 'test' }); > $line1->_result->discard_changes(); > my $line1_post = $line1->unblessed(); > is( $ret, undef, 'Attempted void on non-credit returns undef' ); >-- >2.20.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 27971
:
118358
|
118419
|
118420
|
118422
|
118423
|
118504
|
118505
|
118613
|
118614
|
118624
|
118625
|
119201
|
119202