@@ -, +, @@ --- Koha/Account/Line.pm | 72 +++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 41 deletions(-) --- a/Koha/Account/Line.pm +++ a/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( --