Lines 172-178
sub debit_offsets {
Link Here
|
172 |
|
172 |
|
173 |
Return the credits linked to this account line if some exist. |
173 |
Return the credits linked to this account line if some exist. |
174 |
Search conditions and attributes may be passed if you wish to filter |
174 |
Search conditions and attributes may be passed if you wish to filter |
175 |
the resultant resultant resultset. |
175 |
the resultant resultset. |
176 |
|
176 |
|
177 |
=cut |
177 |
=cut |
178 |
|
178 |
|
Lines 200-206
sub credits {
Link Here
|
200 |
|
200 |
|
201 |
Return the debits linked to this account line if some exist. |
201 |
Return the debits linked to this account line if some exist. |
202 |
Search conditions and attributes may be passed if you wish to filter |
202 |
Search conditions and attributes may be passed if you wish to filter |
203 |
the resultant resultant resultset. |
203 |
the resultant resultset. |
204 |
|
204 |
|
205 |
=cut |
205 |
=cut |
206 |
|
206 |
|
Lines 362-374
sub void {
Link Here
|
362 |
|
362 |
|
363 |
=head3 cancel |
363 |
=head3 cancel |
364 |
|
364 |
|
365 |
$debit_accountline->cancel({ cancellation_type => $type }); |
365 |
$debit_accountline->cancel(); |
366 |
|
366 |
|
367 |
Cancel a charge. It will mark the debit as 'cancelled' by updating its |
367 |
Cancel a charge. It will mark the debit as 'cancelled' by updating its |
368 |
status to 'CANCELLED'. |
368 |
status to 'CANCELLED'. |
369 |
|
369 |
|
370 |
Charges that have been fully or partially paid will be refunded upto |
370 |
Charges that have been fully or partially offset will be refunded upto |
371 |
the amount paid excluding discounts, writeoffs and refunds. |
371 |
the amount paid excluding discounts, writeoffs and prior refunds. |
372 |
|
372 |
|
373 |
Returns the cancellation accountline. |
373 |
Returns the cancellation accountline. |
374 |
|
374 |
|
Lines 393-414
sub cancel {
Link Here
|
393 |
error => 'Account line ' . $self->id . 'is already cancelled' ); |
393 |
error => 'Account line ' . $self->id . 'is already cancelled' ); |
394 |
} |
394 |
} |
395 |
|
395 |
|
396 |
my $cancellation_type = $params->{cancellation_type} // 'CANCELLATION'; |
396 |
my $cancellation_amount = $self->amount; |
397 |
|
397 |
my @applied_offsets; |
398 |
my $cancellation_amount = $self->amountoutstanding; |
|
|
399 |
if ( $self->amount != $self->amountoutstanding ) { |
398 |
if ( $self->amount != $self->amountoutstanding ) { |
400 |
my $credit_offsets = Koha::Account::Offsets->search( |
399 |
# Reductions are 'Writeoff', 'Refund' or 'Discount' lines applied against the debt already. |
401 |
{ |
400 |
# We can ignore 'VOID' status as it will be accounted for in the offsets total |
402 |
debit_id => $self->id, |
401 |
my $reduction_offsets = $self->debit_offsets->filter_by_non_reversable(); |
403 |
credit_id => { '!=' => undef }, # not the debt itself |
|
|
404 |
type => { '!=' => [ 'Writeoff', 'REFUND', 'DISCOUNT' ] } |
405 |
, # Don't refund writeoffs, refunds or discounts |
406 |
amount => { '<' => 0 } # credits are negative on the DB |
407 |
} |
408 |
); |
409 |
|
410 |
$cancellation_amount += |
402 |
$cancellation_amount += |
411 |
$credit_offsets->count > 0 ? $credit_offsets->total * -1 : 0; |
403 |
$reduction_offsets->count > 0 ? $reduction_offsets->total : 0; |
|
|
404 |
|
405 |
# Payments are any credits applied (and not subsequently voided) that are |
406 |
# not 'Writeoff', 'Refund' or 'Discount' |
407 |
@applied_offsets = $self->debit_offsets->filter_by_reversable(); |
412 |
} |
408 |
} |
413 |
|
409 |
|
414 |
my $cancellation; |
410 |
my $cancellation; |
Lines 416-430
sub cancel {
Link Here
|
416 |
sub { |
412 |
sub { |
417 |
|
413 |
|
418 |
# A 'cancellation' is a 'credit' |
414 |
# A 'cancellation' is a 'credit' |
419 |
$cancellation = $self->reduce( |
415 |
$cancellation = Koha::Account::Line->new( |
420 |
{ |
416 |
{ |
421 |
reduction_type => $cancellation_type, |
417 |
date => \'NOW()', |
422 |
amount => $cancellation_amount, |
418 |
amount => 0 - $cancellation_amount, |
423 |
staff_id => $params->{staff_id}, |
419 |
credit_type_code => 'CANCELLATION', |
424 |
interface => $params->{interface}, |
420 |
status => 'ADDED', |
425 |
branch => $params->{branch} |
421 |
amountoutstanding => 0 - $cancellation_amount, |
|
|
422 |
manager_id => $params->{staff_id}, |
423 |
borrowernumber => $self->borrowernumber, |
424 |
interface => 'intranet', |
425 |
branchcode => $params->{branch}, |
426 |
} |
427 |
)->store(); |
428 |
|
429 |
Koha::Account::Offset->new( |
430 |
{ |
431 |
credit_id => $cancellation->accountlines_id, |
432 |
type => 'CREATE', |
433 |
amount => $cancellation_amount |
426 |
} |
434 |
} |
427 |
); |
435 |
)->store(); |
|
|
436 |
|
437 |
# Link cancellation to charge |
438 |
$self->set( |
439 |
{ |
440 |
amountoutstanding => $cancellation_amount, |
441 |
status => 'CANCELLED' |
442 |
} |
443 |
)->store(); |
444 |
$cancellation->apply( { debits => [$self] } ); |
445 |
|
446 |
# Reverse any applied payments |
447 |
for my $applied_offset ( @applied_offsets ) { |
448 |
my $credit = $applied_offset->credit; |
449 |
$credit->amountoutstanding( |
450 |
$credit->amountoutstanding - $applied_offset->amount ) |
451 |
->store(); |
452 |
|
453 |
Koha::Account::Offset->new( |
454 |
{ |
455 |
credit_id => $applied_offset->credit_id, |
456 |
debit_id => $self->id, |
457 |
amount => $applied_offset->amount * -1, |
458 |
type => 'VOID', |
459 |
} |
460 |
)->store(); |
461 |
} |
428 |
} |
462 |
} |
429 |
); |
463 |
); |
430 |
|
464 |
|
Lines 454-460
Reduction type may be one of:
Link Here
|
454 |
|
488 |
|
455 |
* REFUND |
489 |
* REFUND |
456 |
* DISCOUNT |
490 |
* DISCOUNT |
457 |
* CANCELLATION |
|
|
458 |
|
491 |
|
459 |
Returns the reduction accountline (which will be a credit) |
492 |
Returns the reduction accountline (which will be a credit) |
460 |
|
493 |
|
Lines 482-487
sub reduce {
Link Here
|
482 |
} |
515 |
} |
483 |
} |
516 |
} |
484 |
|
517 |
|
|
|
518 |
# Amount should always be passed as positive |
519 |
Koha::Exceptions::Account::AmountNotPositive->throw( |
520 |
error => 'Reduce amount passed is not positive' ) |
521 |
unless ( $params->{amount} > 0 ); |
522 |
|
485 |
# More mandatory parameters |
523 |
# More mandatory parameters |
486 |
if ( $params->{interface} eq 'intranet' ) { |
524 |
if ( $params->{interface} eq 'intranet' ) { |
487 |
my @optional = ( 'staff_id', 'branch' ); |
525 |
my @optional = ( 'staff_id', 'branch' ); |
Lines 496-520
sub reduce {
Link Here
|
496 |
|
534 |
|
497 |
# Make sure the reduction isn't more than the original |
535 |
# Make sure the reduction isn't more than the original |
498 |
my $original = $self->amount; |
536 |
my $original = $self->amount; |
499 |
Koha::Exceptions::Account::AmountNotPositive->throw( |
|
|
500 |
error => 'Reduce amount passed is not positive' ) |
501 |
unless ( $params->{amount} > 0 ); |
502 |
Koha::Exceptions::ParameterTooHigh->throw( error => |
537 |
Koha::Exceptions::ParameterTooHigh->throw( error => |
503 |
"Amount to reduce ($params->{amount}) is higher than original amount ($original)" |
538 |
"Amount to reduce ($params->{amount}) is higher than original amount ($original)" |
504 |
) unless ( $original >= $params->{amount} ); |
539 |
) unless ( $original >= $params->{amount} ); |
505 |
my $reduced = |
540 |
|
506 |
$self->credits( { credit_type_code => [ 'WRITEOFF', 'DISCOUNT', 'REFUND' ] } )->total; |
541 |
# Make sure combined reduction isn't more than the original |
|
|
542 |
my $reduced = 0; |
543 |
if ( $self->amount != $self->amountoutstanding ) { |
544 |
my $reduction_offsets = Koha::Account::Offsets->search( |
545 |
{ |
546 |
debit_id => $self->id, |
547 |
credit_id => { '!=' => undef }, # not the debt itself |
548 |
type => { '!=' => [ 'Writeoff', 'REFUND', 'DISCOUNT' ] } |
549 |
, # Don't refund writeoffs, refunds or discounts |
550 |
amount => { '<' => 0 } # credits are negative on the DB |
551 |
} |
552 |
); |
553 |
|
554 |
$reduced = $reduction_offsets->count > 0 ? $reduction_offsets->total * -1 : 0; |
555 |
} |
556 |
|
507 |
Koha::Exceptions::ParameterTooHigh->throw( error => |
557 |
Koha::Exceptions::ParameterTooHigh->throw( error => |
508 |
"Combined reduction ($params->{amount} + $reduced) is higher than original amount (" |
558 |
"Combined reduction ($params->{amount} + $reduced) is higher than original amount (" |
509 |
. abs($original) |
559 |
. abs($original) |
510 |
. ")" ) |
560 |
. ")" ) |
511 |
unless ( $original >= ( $params->{amount} + abs($reduced) ) ); |
561 |
unless ( $original >= ( $params->{amount} + abs($reduced) ) ); |
512 |
|
562 |
|
513 |
my $status = { |
563 |
my $status = { 'REFUND' => 'REFUNDED', 'DISCOUNT' => 'DISCOUNTED' }; |
514 |
'REFUND' => 'REFUNDED', |
|
|
515 |
'DISCOUNT' => 'DISCOUNTED', |
516 |
'CANCELLATION' => 'CANCELLED' |
517 |
}; |
518 |
|
564 |
|
519 |
my $reduction; |
565 |
my $reduction; |
520 |
$self->_result->result_source->schema->txn_do( |
566 |
$self->_result->result_source->schema->txn_do( |