From eef9e66c6eb60ffd3999e154fc2b5cf14686024c Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Fri, 2 Jul 2021 16:10:48 +0100 Subject: [PATCH] Bug 28656: Update the cancel method for paid debts This patch updates the cancel method to allow cancellation of debts that have been partially or fully paid off. Payments will be included in the cancellation amount allowing for later use as credit. Discounts, Writeoffs and Refunds are excluded from the cancellation amount. --- Koha/Account/Line.pm | 77 +++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 47 deletions(-) diff --git a/Koha/Account/Line.pm b/Koha/Account/Line.pm index bd233e3b36..a393ef39f2 100644 --- a/Koha/Account/Line.pm +++ b/Koha/Account/Line.pm @@ -349,12 +349,13 @@ sub void { =head3 cancel - $debit_accountline->cancel(); + $debit_accountline->cancel({ cancellation_type => $type }); Cancel a charge. It will mark the debit as 'cancelled' by updating its status to 'CANCELLED'. -Charges that have been fully or partially paid cannot be cancelled. +Charges that have been fully or partially paid will be refunded upto +the amount paid excluding discounts, writeoffs and refunds. Returns the cancellation accountline. @@ -379,59 +380,36 @@ sub cancel { error => 'Account line ' . $self->id . 'is already cancelled' ); } - # Make sure it has not be paid yet + my $cancellation_type = $params->{cancellation_type} // 'CANCELLATION'; + + my $cancellation_amount = $self->amountoutstanding; if ( $self->amount != $self->amountoutstanding ) { - Koha::Exceptions::Account->throw( - error => 'Account line ' . $self->id . 'is already offset' ); - } + my $credit_offsets = Koha::Account::Offsets->search( + { + debit_id => $self->id, + credit_id => { '!=' => undef }, # not the debt itself + type => { '!=' => [ 'Writeoff', 'REFUND', 'DISCOUNT' ] } + , # Don't refund writeoffs, refunds or discounts + amount => { '<' => 0 } # credits are negative on the DB + } + ); - # Check for mandatory parameters - my @mandatory = ( 'staff_id', 'branch' ); - for my $param (@mandatory) { - unless ( defined( $params->{$param} ) ) { - Koha::Exceptions::MissingParameter->throw( - error => "The $param parameter is mandatory" ); - } + $cancellation_amount += + $credit_offsets->count > 0 ? $credit_offsets->total * -1 : 0; } my $cancellation; $self->_result->result_source->schema->txn_do( sub { - - # A 'cancellation' is a 'credit' - $cancellation = Koha::Account::Line->new( + $cancellation = $self->reduce( { - date => \'NOW()', - amount => 0 - $self->amount, - credit_type_code => 'CANCELLATION', - status => 'ADDED', - amountoutstanding => 0 - $self->amount, - manager_id => $params->{staff_id}, - borrowernumber => $self->borrowernumber, - interface => 'intranet', - branchcode => $params->{branch}, - } - )->store(); - - my $cancellation_offset = Koha::Account::Offset->new( - { - credit_id => $cancellation->accountlines_id, - type => 'CANCELLATION', - amount => $self->amount - } - )->store(); - - # Link cancellation to charge - $cancellation->apply( - { - debits => [$self], - offset_type => 'CANCELLATION' + reduction_type => $cancellation_type, + amount => $cancellation_amount, + staff_id => $params->{staff_id}, + interface => $params->{interface}, + branch => $params->{branch} } ); - $cancellation->status('APPLIED')->store(); - - # Update status of original debit - $self->status('CANCELLED')->store; } ); @@ -461,6 +439,7 @@ Reduction type may be one of: * REFUND * DISCOUNT +* CANCELLATION Returns the reduction accountline (which will be a credit) @@ -509,14 +488,18 @@ sub reduce { "Amount to reduce ($params->{amount}) is higher than original amount ($original)" ) unless ( $original >= $params->{amount} ); my $reduced = - $self->credits( { credit_type_code => [ 'DISCOUNT', 'REFUND' ] } )->total; + $self->credits( { credit_type_code => [ 'WRITEOFF', 'DISCOUNT', 'REFUND' ] } )->total; Koha::Exceptions::ParameterTooHigh->throw( error => "Combined reduction ($params->{amount} + $reduced) is higher than original amount (" . abs($original) . ")" ) unless ( $original >= ( $params->{amount} + abs($reduced) ) ); - my $status = { 'REFUND' => 'REFUNDED', 'DISCOUNT' => 'DISCOUNTED' }; + my $status = { + 'REFUND' => 'REFUNDED', + 'DISCOUNT' => 'DISCOUNTED', + 'CANCELLATION' => 'CANCELLED' + }; my $reduction; $self->_result->result_source->schema->txn_do( -- 2.20.1