From 70bd48ea34100cca46000e66974294fe1809379d 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 | 72 +++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/Koha/Account/Line.pm b/Koha/Account/Line.pm index 949bd23c09..34bab520fc 100644 --- a/Koha/Account/Line.pm +++ b/Koha/Account/Line.pm @@ -362,12 +362,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. @@ -392,19 +393,22 @@ 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; @@ -412,34 +416,15 @@ sub cancel { 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}, + reduction_type => $cancellation_type, + amount => $cancellation_amount, + staff_id => $params->{staff_id}, + interface => $params->{interface}, + branch => $params->{branch} } - )->store(); - - my $cancellation_offset = Koha::Account::Offset->new( - { - credit_id => $cancellation->accountlines_id, - type => 'CREATE', - amount => 0 - $self->amount - } - )->store(); - - # Link cancellation to charge - $cancellation->apply( { debits => [$self] } ); - $cancellation->status('APPLIED')->store(); - - # Update status of original debit - $self->status('CANCELLED')->store; + ); } ); @@ -469,6 +454,7 @@ Reduction type may be one of: * REFUND * DISCOUNT +* CANCELLATION Returns the reduction accountline (which will be a credit) @@ -517,14 +503,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