View | Details | Raw Unified | Return to bug 23012
Collapse All | Expand All

(-)a/C4/Circulation.pm (+2 lines)
Lines 2226-2231 sub AddReturn { Link Here
2226
            for my $message (@object_messages) {
2226
            for my $message (@object_messages) {
2227
                $messages->{'LostItemFeeRefunded'} = 1
2227
                $messages->{'LostItemFeeRefunded'} = 1
2228
                  if $message->message eq 'lost_refunded';
2228
                  if $message->message eq 'lost_refunded';
2229
                $messages->{'ProcessingFeeRefunded'} = 1
2230
                  if $message->message eq 'processing_refunded';
2229
                $messages->{'LostItemFeeRestored'} = 1
2231
                $messages->{'LostItemFeeRestored'} = 1
2230
                  if $message->message eq 'lost_restored';
2232
                  if $message->message eq 'lost_restored';
2231
2233
(-)a/Koha/Item.pm (+105 lines)
Lines 1324-1329 sub _set_found_trigger { Link Here
1324
        }
1324
        }
1325
    }
1325
    }
1326
1326
1327
    my $processingreturn_policy = Koha::CirculationRules->get_processingreturn_policy(
1328
        {
1329
            item          => $self,
1330
            return_branch => C4::Context->userenv
1331
            ? C4::Context->userenv->{'branch'}
1332
            : undef,
1333
        }
1334
      );
1335
1336
    if ( $processingreturn_policy ) {
1337
1338
        # refund processing charge made for lost book
1339
        my $processing_charge = Koha::Account::Lines->search(
1340
            {
1341
                itemnumber      => $self->itemnumber,
1342
                debit_type_code => 'PROCESSING',
1343
                status          => [ undef, { '<>' => 'FOUND' } ]
1344
            },
1345
            {
1346
                order_by => { -desc => [ 'date', 'accountlines_id' ] },
1347
                rows     => 1
1348
            }
1349
        )->single;
1350
1351
        if ( $processing_charge ) {
1352
1353
            my $patron = $processing_charge->patron;
1354
            if ( $patron ) {
1355
1356
                my $account = $patron->account;
1357
1358
                # Credit outstanding amount
1359
                my $credit_total = $processing_charge->amountoutstanding;
1360
1361
                # Use cases
1362
                if (
1363
                    $processing_charge->amount > $processing_charge->amountoutstanding &&
1364
                    $processingreturn_policy ne "refund_unpaid"
1365
                ) {
1366
                    # some amount has been cancelled. collect the offsets that are not writeoffs
1367
                    # this works because the only way to subtract from this kind of a debt is
1368
                    # using the UI buttons 'Pay' and 'Write off'
1369
1370
                    # We don't credit any payments if return policy is
1371
                    # "refund_unpaid"
1372
                    #
1373
                    # In that case only unpaid/outstanding amount
1374
                    # will be credited which settles the debt without
1375
                    # creating extra credits
1376
1377
                    my $credit_offsets = $processing_charge->debit_offsets(
1378
                        {
1379
                            'credit_id'               => { '!=' => undef },
1380
                            'credit.credit_type_code' => { '!=' => 'Writeoff' }
1381
                        },
1382
                        { join => 'credit' }
1383
                    );
1384
1385
                    my $total_to_refund = ( $credit_offsets->count > 0 ) ?
1386
                        # credits are negative on the DB
1387
                        $credit_offsets->total * -1 :
1388
                        0;
1389
                    # Credit the outstanding amount, then add what has been
1390
                    # paid to create a net credit for this amount
1391
                    $credit_total += $total_to_refund;
1392
                }
1393
1394
                my $credit;
1395
                if ( $credit_total > 0 ) {
1396
                    my $branchcode =
1397
                      C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef;
1398
                    $credit = $account->add_credit(
1399
                        {
1400
                            amount      => $credit_total,
1401
                            description => 'Item found ' . $self->itemnumber,
1402
                            type        => 'PROCESSING_FOUND',
1403
                            interface   => C4::Context->interface,
1404
                            library_id  => $branchcode,
1405
                            item_id     => $self->itemnumber,
1406
                            issue_id    => $processing_charge->issue_id
1407
                        }
1408
                    );
1409
1410
                    $credit->apply( { debits => [$processing_charge] } );
1411
                    $self->add_message(
1412
                        {
1413
                            type    => 'info',
1414
                            message => 'processing_refunded',
1415
                            payload => { credit_id => $credit->id }
1416
                        }
1417
                    );
1418
                }
1419
1420
                # Update the account status
1421
                $processing_charge->status('FOUND');
1422
                $processing_charge->store();
1423
1424
                # Reconcile balances if required
1425
                if ( C4::Context->preference('AccountAutoReconcile') ) {
1426
                    $account->reconcile_balance;
1427
                }
1428
            }
1429
        }
1430
    }
1431
1327
    return $self;
1432
    return $self;
1328
}
1433
}
1329
1434
(-)a/circ/returns.pl (+3 lines)
Lines 673-678 foreach my $code ( keys %$messages ) { Link Here
673
    elsif ( $code eq 'LostItemFeeRestored' ) {
673
    elsif ( $code eq 'LostItemFeeRestored' ) {
674
        $template->param( LostItemFeeRestored => 1 );
674
        $template->param( LostItemFeeRestored => 1 );
675
    }
675
    }
676
    elsif ( $code eq 'ProcessingFeeRefunded' ) {
677
        $template->param( ProcessingFeeRefunded => 1 );
678
    }
676
    elsif ( $code eq 'ResFound' ) {
679
    elsif ( $code eq 'ResFound' ) {
677
        ;    # FIXME... anything to do here?
680
        ;    # FIXME... anything to do here?
678
    }
681
    }
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt (-1 / +6 lines)
Lines 336-342 Link Here
336
                                                <p class="problem ret_checkedin">Item was lost, now found.</p>
336
                                                <p class="problem ret_checkedin">Item was lost, now found.</p>
337
                                            [% END %]
337
                                            [% END %]
338
                                            [% IF LostItemFeeRefunded and not Koha.Preference('BlockReturnOfLostItems') %]
338
                                            [% IF LostItemFeeRefunded and not Koha.Preference('BlockReturnOfLostItems') %]
339
                                                <p class="problem ret_refund">A refund has been applied to the borrowing patron's account.</p>
339
                                                <p class="problem ret_refund">A refund for the lost item charge has been applied to the borrowing patron's account.</p>
340
                                            [% ELSIF LostItemFeeCharged and not Koha.Preference('BlockReturnOfLostItems') %]
340
                                            [% ELSIF LostItemFeeCharged and not Koha.Preference('BlockReturnOfLostItems') %]
341
                                                <p class="problem ret_charged">A refund for the lost item charge has been applied to the borrowing patron's account, and new overdue charge has been calculated and applied.</p>
341
                                                <p class="problem ret_charged">A refund for the lost item charge has been applied to the borrowing patron's account, and new overdue charge has been calculated and applied.</p>
342
                                            [% ELSIF LostItemFeeRestored and not Koha.Preference('BlockReturnOfLostItems') %]
342
                                            [% ELSIF LostItemFeeRestored and not Koha.Preference('BlockReturnOfLostItems') %]
Lines 347-352 Link Here
347
                                            [% ELSE %]
347
                                            [% ELSE %]
348
                                                <p class="problem ret_feeremains">Any lost item fees for this item will remain on the patron's account.</p>
348
                                                <p class="problem ret_feeremains">Any lost item fees for this item will remain on the patron's account.</p>
349
                                            [% END %]
349
                                            [% END %]
350
                                            [% IF ProcessingFeeRefunded and not Koha.Preference('BlockReturnOfLostItems') %]
351
                                                <p class="problem ret_refund">A refund for the lost item processing charge has been applied to the borrowing patron's account.</p>
352
                                            [% ELSE %]
353
                                                <p class="problem ret_feeremains">Any processing fees for this item will remain on the patron's account.</p>
354
                                            [% END %]
350
                                        [% END %]
355
                                        [% END %]
351
                                        [% IF ( errmsgloo.withdrawn ) %]
356
                                        [% IF ( errmsgloo.withdrawn ) %]
352
                                            [% IF Koha.Preference('BlockReturnOfWithdrawnItems') %]
357
                                            [% IF Koha.Preference('BlockReturnOfWithdrawnItems') %]
(-)a/t/db_dependent/Koha/Item.t (-2 / +23 lines)
Lines 1407-1413 subtest 'store() tests' => sub { Link Here
1407
1407
1408
    subtest '_set_found_trigger() tests' => sub {
1408
    subtest '_set_found_trigger() tests' => sub {
1409
1409
1410
        plan tests => 6;
1410
        plan tests => 8;
1411
1411
1412
        $schema->storage->txn_begin;
1412
        $schema->storage->txn_begin;
1413
1413
Lines 1424-1433 subtest 'store() tests' => sub { Link Here
1424
            }
1424
            }
1425
        );
1425
        );
1426
1426
1427
        # Add a lost item processing fee
1428
        my $processing_debit = $patron->account->add_debit(
1429
            {
1430
                amount    => 2,
1431
                type      => 'PROCESSING',
1432
                item_id   => $item->id,
1433
                interface => 'intranet',
1434
            }
1435
        );
1436
1427
        my $lostreturn_policy = 'charge';
1437
        my $lostreturn_policy = 'charge';
1438
        my $processingreturn_policy = 'refund';
1428
1439
1429
        my $mocked_circ_rules = Test::MockModule->new('Koha::CirculationRules');
1440
        my $mocked_circ_rules = Test::MockModule->new('Koha::CirculationRules');
1430
        $mocked_circ_rules->mock( 'get_lostreturn_policy', sub { return $lostreturn_policy; } );
1441
        $mocked_circ_rules->mock( 'get_lostreturn_policy', sub { return $lostreturn_policy; } );
1442
        $mocked_circ_rules->mock( 'get_processingreturn_policy', sub { return $processingreturn_policy; } );
1431
1443
1432
        # simulate it was found
1444
        # simulate it was found
1433
        $item->set( { itemlost => 0 } )->store;
1445
        $item->set( { itemlost => 0 } )->store;
Lines 1454-1459 subtest 'store() tests' => sub { Link Here
1454
        is( $message_2->message, 'lost_charge', 'message is correct' );
1466
        is( $message_2->message, 'lost_charge', 'message is correct' );
1455
        is( $message_2->payload, undef,         'no payload' );
1467
        is( $message_2->payload, undef,         'no payload' );
1456
1468
1469
        my $message_3 = $messages->[2];
1470
        is( $message_3->message, 'processing_refunded', 'message is correct' );
1471
1472
        my $processing_credit = $processing_debit->credits->next;
1473
        is_deeply(
1474
            $message_3->payload,
1475
            { credit_id => $processing_credit->id },
1476
            'type is correct'
1477
        );
1478
1457
        $schema->storage->txn_rollback;
1479
        $schema->storage->txn_rollback;
1458
    };
1480
    };
1459
1481
1460
- 

Return to bug 23012