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

(-)a/C4/Circulation.pm (-27 / +136 lines)
Lines 1453-1459 sub AddIssue { Link Here
1453
                UpdateTotalIssues( $item_object->biblionumber, 1 );
1453
                UpdateTotalIssues( $item_object->biblionumber, 1 );
1454
            }
1454
            }
1455
1455
1456
            ## If item was lost, it has now been found, reverse any list item charges if necessary.
1456
            ## If item was lost, it has now been found, reverse any lost item charges if necessary.
1457
            if ( $item_object->itemlost ) {
1457
            if ( $item_object->itemlost ) {
1458
                my $refund = 1;
1458
                my $refund = 1;
1459
                my $no_refund_after_days = C4::Context->preference('NoRefundOnLostReturnedItemsAge');
1459
                my $no_refund_after_days = C4::Context->preference('NoRefundOnLostReturnedItemsAge');
Lines 1467-1483 sub AddIssue { Link Here
1467
                    $refund = 0 unless ( $lost_age_in_days < $no_refund_after_days );
1467
                    $refund = 0 unless ( $lost_age_in_days < $no_refund_after_days );
1468
                }
1468
                }
1469
1469
1470
                if (
1470
                my $lostreturn_policy =
1471
                    $refund && Koha::CirculationRules->get_lostreturn_policy(
1471
                  Koha::CirculationRules->get_lostreturn_policy(
1472
                        {
1472
                    {
1473
                            return_branch => C4::Context->userenv->{branch},
1473
                        return_branch => C4::Context->userenv->{branch},
1474
                            item          => $item_object
1474
                        item          => $item_object
1475
                        }
1475
                    }
1476
                    )
1476
                  );
1477
                  )
1477
1478
                {
1478
                if ($refund && $lostreturn_policy) {
1479
                    _FixAccountForLostAndFound( $item_object->itemnumber, undef,
1479
                    _FixAccountForLostAndFound( $item_object->itemnumber, undef,
1480
                        $item_object->barcode );
1480
                        $item_object->barcode );
1481
1482
                    if ( $lostreturn_policy eq 'charge' ) {
1483
                        $actualissue //= Koha::Old::Checkouts->search(
1484
                            { itemnumber => $item_unblessed->{itemnumber} },
1485
                            {
1486
                                order_by => { '-desc' => 'returndate' },
1487
                                rows     => 1
1488
                            }
1489
                        )->single;
1490
1491
                        _CalculateAndUpdateFine(
1492
                            {
1493
                                issue    => $actualissue,
1494
                                item     => $item_unblessed,
1495
                                borrower => $borrower
1496
                            }
1497
                        );
1498
                        _FixOverduesOnReturn( $borrower->{borrowernumber},
1499
                            $item_object->itemnumber, undef, 'RENEWED' );
1500
                    }
1501
                    elsif ( $lostreturn_policy eq 'restore' ) {
1502
                        _RestoreOverdueForLostAndFound(
1503
                            $borrower->{'borrowernumber'},
1504
                            $item_object->itemnumber
1505
                        );
1506
                    }
1481
                }
1507
                }
1482
            }
1508
            }
1483
1509
Lines 2062-2080 sub AddReturn { Link Here
2062
                $refund = 0 unless ( $lost_age_in_days < $no_refund_after_days );
2088
                $refund = 0 unless ( $lost_age_in_days < $no_refund_after_days );
2063
            }
2089
            }
2064
2090
2065
            if (
2091
            my $lostreturn_policy =
2066
                $refund &&
2092
              Koha::CirculationRules->get_lostreturn_policy(
2067
                Koha::CirculationRules->get_lostreturn_policy(
2093
                {
2068
                    {
2094
                    return_branch => C4::Context->userenv->{branch},
2069
                        return_branch => C4::Context->userenv->{branch},
2095
                    item          => $item
2070
                        item          => $item,
2096
                }
2071
                    }
2097
              );
2072
                  )
2098
2073
              )
2099
            if ($refund && $lostreturn_policy) {
2074
            {
2075
                _FixAccountForLostAndFound( $item->itemnumber,
2100
                _FixAccountForLostAndFound( $item->itemnumber,
2076
                    $borrowernumber, $barcode );
2101
                    $borrowernumber, $barcode );
2077
                $messages->{'LostItemFeeRefunded'} = 1;
2102
                $messages->{'LostItemFeeRefunded'} = 1;
2103
2104
                if ( $lostreturn_policy eq 'charge' ) {
2105
                    $issue //= Koha::Old::Checkouts->search(
2106
                        { itemnumber => $item->itemnumber },
2107
                        { order_by   => { '-desc' => 'returndate' }, rows => 1 }
2108
                    )->single;
2109
                    _CalculateAndUpdateFine(
2110
                        {
2111
                            issue       => $issue,
2112
                            item        => $item->unblessed,
2113
                            borrower    => $patron_unblessed,
2114
                            return_date => $return_date
2115
                        }
2116
                    );
2117
                    $messages->{'LostItemFeeCharged'} = 1;
2118
                }
2119
                elsif ( $lostreturn_policy eq 'restore' ) {
2120
                    _RestoreOverdueForLostAndFound( $borrowernumber,
2121
                        $item->itemnumber );
2122
                    $messages->{'LostItemFeeRestored'} = 1;
2123
                }
2078
            }
2124
            }
2079
        }
2125
        }
2080
    }
2126
    }
Lines 2486-2499 sub _FixOverduesOnReturn { Link Here
2486
                if (C4::Context->preference("FinesLog")) {
2532
                if (C4::Context->preference("FinesLog")) {
2487
                    &logaction("FINES", 'MODIFY',$borrowernumber,"Overdue forgiven: item $item");
2533
                    &logaction("FINES", 'MODIFY',$borrowernumber,"Overdue forgiven: item $item");
2488
                }
2534
                }
2489
2490
                $accountline->status('FORGIVEN');
2491
                $accountline->store();
2492
            } else {
2493
                $accountline->status($status);
2494
                $accountline->store();
2495
2496
            }
2535
            }
2536
2537
            $accountline->status($status);
2538
            return $accountline->store();
2497
        }
2539
        }
2498
    );
2540
    );
2499
2541
Lines 2589-2594 sub _FixAccountForLostAndFound { Link Here
2589
    return ($credit) ? $credit->id : undef;
2631
    return ($credit) ? $credit->id : undef;
2590
}
2632
}
2591
2633
2634
=head2 _RestoreOverdueForLostAndFound
2635
2636
   &_RestoreOverdueForLostAndFound($borrowernumber, $itemnumber );
2637
2638
C<$borrowernumber> borrowernumber
2639
2640
C<$itemnumber> itemnumber
2641
2642
Internal function
2643
2644
=cut
2645
2646
sub _RestoreOverdueForLostAndFound {
2647
    my ( $borrowernumber, $item ) = @_;
2648
2649
    unless( $borrowernumber ) {
2650
        warn "_RestoreOverdueForLostAndFound() not supplied valid borrowernumber";
2651
        return;
2652
    }
2653
    unless( $item ) {
2654
        warn "_RestoreOverdueForLostAndFound() not supplied valid itemnumber";
2655
        return;
2656
    }
2657
2658
    my $schema = Koha::Database->schema;
2659
2660
    my $result = $schema->txn_do(
2661
        sub {
2662
            # check for lost overdue fine
2663
            my $accountlines = Koha::Account::Lines->search(
2664
                {
2665
                    borrowernumber  => $borrowernumber,
2666
                    itemnumber      => $item,
2667
                    debit_type_code => 'OVERDUE',
2668
                    status          => 'LOST'
2669
                },
2670
                {
2671
                    order_by => { '-desc' => 'date' },
2672
                    rows     => 1
2673
                }
2674
            );
2675
            return 0 unless $accountlines->count; # no warning, there's just nothing to fix
2676
2677
            # Update status of fine
2678
            my $overdue = $accountlines->next;
2679
            $overdue->status('RETURNED')->store();
2680
2681
            # Find related forgive credit
2682
            my $refunds = $overdue->credits(
2683
                {
2684
                    credit_type_code => 'FORGIVEN',
2685
                    itemnumber       => $item,
2686
                    status           => [ { '!=' => 'VOID' }, undef ]
2687
                },
2688
                { order_by => { '-desc' => 'date' }, rows => 1 }
2689
            );
2690
            return 0 unless $refunds->count; # no warning, there's just nothing to fix
2691
2692
            # Revert the forgive credit
2693
            my $refund = $refunds->next;
2694
            return $refund->void();
2695
        }
2696
    );
2697
2698
    return $result;
2699
}
2700
2592
=head2 _GetCircControlBranch
2701
=head2 _GetCircControlBranch
2593
2702
2594
   my $circ_control_branch = _GetCircControlBranch($iteminfos, $borrower);
2703
   my $circ_control_branch = _GetCircControlBranch($iteminfos, $borrower);
(-)a/Koha/CirculationRules.pm (-4 / +15 lines)
Lines 46-52 Any attempt to set a rule with a nonsensical scope (for instance, setting the C< Link Here
46
=cut
46
=cut
47
47
48
our $RULE_KINDS = {
48
our $RULE_KINDS = {
49
    refund => {
49
    lostreturn => {
50
        scope => [ 'branchcode' ],
50
        scope => [ 'branchcode' ],
51
    },
51
    },
52
52
Lines 428-434 sub get_onshelfholds_policy { Link Here
428
428
429
=head3 get_lostreturn_policy
429
=head3 get_lostreturn_policy
430
430
431
  my $refund = Koha::CirculationRules->get_lostreturn_policy( { return_branch => $return_branch, item => $item } );
431
  my $lostrefund_policy = Koha::CirculationRules->get_lostreturn_policy( { return_branch => $return_branch, item => $item } );
432
433
Return values are:
434
435
=over 2
436
437
=item 0 - Do not refund
438
=item refund - Refund the lost item charge
439
=item restore - Refund the lost item charge and restore the original overdue fine
440
=item charge - Refund the lost item charge and charge a new overdue fine
441
442
=back
432
443
433
=cut
444
=cut
434
445
Lines 449-459 sub get_lostreturn_policy { Link Here
449
    my $rule = Koha::CirculationRules->get_effective_rule(
460
    my $rule = Koha::CirculationRules->get_effective_rule(
450
        {
461
        {
451
            branchcode => $branch,
462
            branchcode => $branch,
452
            rule_name  => 'refund',
463
            rule_name  => 'lostreturn',
453
        }
464
        }
454
    );
465
    );
455
466
456
    return $rule ? $rule->rule_value : 1;
467
    return $rule ? $rule->rule_value : 'refund';
457
}
468
}
458
469
459
=head3 article_requestable_rules
470
=head3 article_requestable_rules
(-)a/admin/smart-rules.pl (-8 / +8 lines)
Lines 523-538 elsif ($op eq "add-branch-item") { Link Here
523
}
523
}
524
elsif ( $op eq 'mod-refund-lost-item-fee-rule' ) {
524
elsif ( $op eq 'mod-refund-lost-item-fee-rule' ) {
525
525
526
    my $refund = $input->param('refund');
526
    my $lostreturn = $input->param('lostreturn');
527
527
528
    if ( $refund eq '*' ) {
528
    if ( $lostreturn eq '*' ) {
529
        if ( $branch ne '*' ) {
529
        if ( $branch ne '*' ) {
530
            # only do something for $refund eq '*' if branch-specific
530
            # only do something for $lostreturn eq '*' if branch-specific
531
            Koha::CirculationRules->set_rules(
531
            Koha::CirculationRules->set_rules(
532
                {
532
                {
533
                    branchcode   => $branch,
533
                    branchcode   => $branch,
534
                    rules        => {
534
                    rules        => {
535
                        refund => undef
535
                        lostreturn => undef
536
                    }
536
                    }
537
                }
537
                }
538
            );
538
            );
Lines 542-559 elsif ( $op eq 'mod-refund-lost-item-fee-rule' ) { Link Here
542
            {
542
            {
543
                branchcode   => $branch,
543
                branchcode   => $branch,
544
                rules        => {
544
                rules        => {
545
                    refund => $refund
545
                    lostreturn => $lostreturn
546
                }
546
                }
547
            }
547
            }
548
        );
548
        );
549
    }
549
    }
550
}
550
}
551
551
552
my $refundLostItemFeeRule = Koha::CirculationRules->find({ branchcode => ($branch eq '*') ? undef : $branch, rule_name => 'refund' });
552
my $refundLostItemFeeRule = Koha::CirculationRules->find({ branchcode => ($branch eq '*') ? undef : $branch, rule_name => 'lostreturn' });
553
my $defaultLostItemFeeRule = Koha::CirculationRules->find({ branchcode => undef, rule_name => 'refund' });
553
my $defaultLostItemFeeRule = Koha::CirculationRules->find({ branchcode => undef, rule_name => 'lostreturn' });
554
$template->param(
554
$template->param(
555
    refundLostItemFeeRule => $refundLostItemFeeRule,
555
    refundLostItemFeeRule => $refundLostItemFeeRule,
556
    defaultRefundRule     => $defaultLostItemFeeRule ? $defaultLostItemFeeRule->rule_value : 1
556
    defaultRefundRule     => $defaultLostItemFeeRule ? $defaultLostItemFeeRule->rule_value : 'refund'
557
);
557
);
558
558
559
my $patron_categories = Koha::Patron::Categories->search({}, { order_by => ['description'] });
559
my $patron_categories = Koha::Patron::Categories->search({}, { order_by => ['description'] });
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt (-32 / +56 lines)
Lines 739-761 Link Here
739
                </tr>
739
                </tr>
740
                <tr>
740
                <tr>
741
                    <td>
741
                    <td>
742
                        <select name="refund">
742
                        <select name="lostreturn">
743
                          [%# Default branch %]
743
                          [%# Default branch %]
744
                          [% IF ( current_branch == '*' ) %]
744
                          [% IF ( current_branch == '*' ) %]
745
                            [% IF ( defaultRefundRule ) %]
745
                            [% IF ( defaultRefundRule == 'refund' ) %]
746
                            <option value="1" selected="selected">
746
                            <option value="refund" selected="selected">Refund lost item charge</option>
747
                            <option value="charge">Refund lost item charge and charge new overdue fine</option>
748
                            <option value="restore">Refund lost item charge and restore overdue fine</option>
749
                            <option value="0">Leave lost item charge</option>
750
                            [% ELSIF ( defaultRefundRule == 'charge' ) %]
751
                            <option value="refund">Refund lost item charge</option>
752
                            <option value="charge" selected="selected">Refund lost item charge and charge new overdue fine</option>
753
                            <option value="restore">Refund lost item charge and restore overdue fine</option>
754
                            <option value="0">Leave lost item charge</option>
755
                            [% ELSIF ( defaultRefundRule == 'restore' ) %]
756
                            <option value="refund">Refund lost item charge</option>
757
                            <option value="charge">Refund lost item charge and charge new overdue fine</option>
758
                            <option value="restore" selected="selected">Refund lost item charge and restore overdue fine</option>
759
                            <option value="0">Leave lost item charge</option>
760
                            [% ELSIF ( defaultRefundRule == 0 ) %]
761
                            <option value="refund">Refund lost item charge</option>
762
                            <option value="charge">Refund lost item charge and charge new overdue fine</option>
763
                            <option value="restore">Refund lost item charge and restore overdue fine</option>
764
                            <option value="0" selected="selected">Leave lost item charge</option>
747
                            [% ELSE %]
765
                            [% ELSE %]
748
                            <option value="1">
766
                            <option value="refund">Refund lost item charge</option>
767
                            <option value="charge">Refund lost item charge and charge new overdue fine</option>
768
                            <option value="restore">Refund lost item charge and restore overdue fine</option>
769
                            <option value="0">Leave lost item charge</option>
749
                            [% END %]
770
                            [% END %]
750
                                Yes
751
                            </option>
752
                            [% IF ( not defaultRefundRule ) %]
753
                            <option value="0" selected="selected">
754
                            [% ELSE %]
755
                            <option value="0">
756
                            [% END %]
757
                                No
758
                            </option>
759
                          [% ELSE %]
771
                          [% ELSE %]
760
                          [%# Branch-specific %]
772
                          [%# Branch-specific %]
761
                            [% IF ( not refundLostItemFeeRule ) %]
773
                            [% IF ( not refundLostItemFeeRule ) %]
Lines 763-792 Link Here
763
                            [% ELSE %]
775
                            [% ELSE %]
764
                                <option value="*">
776
                                <option value="*">
765
                            [% END %]
777
                            [% END %]
766
                              [% IF defaultRefundRule %]
778
                              [% IF defaultRefundRule == 'refund' %]
767
                                Use default (Yes)
779
                                Use default (Refund lost item charge)
780
                              [% ELSIF defaultRefundRule == 'charge' %]
781
                                Use default (Refund lost item charge and restore overdue fine)
782
                              [% ELSIF defaultRefundRule == 'restore' %]
783
                                Use default (Refund lost item charge and charge new overdue fine)
768
                              [% ELSE %]
784
                              [% ELSE %]
769
                                Use default (No)
785
                                Use default (Leave lost item charge)
770
                              [% END %]
786
                              [% END %]
771
                                </option>
787
                                </option>
772
                            [% IF ( not refundLostItemFeeRule ) %]
788
                            [% IF ( not refundLostItemFeeRule ) %]
773
                                <option value="1">Yes</option>
789
                                <option value="refund">Refund lost item charge</option>
774
                                <option value="0">No</option>
790
                                <option value="charge">Refund lost item charge and charge new overdue fine</option>
791
                                <option value="restore">Refund lost item charge and restore overdue fine</option>
792
                                <option value="0">Leave lost item charge</option>
775
                            [% ELSE %]
793
                            [% ELSE %]
776
                                [% IF ( refundLostItemFeeRule.rule_value ) %]
794
                                [% IF ( refundLostItemFeeRule.rule_value == 'refund' ) %]
777
                                <option value="1" selected="selected">
795
                                <option value="refund" selected="selected">Refund lost item charge</option>
778
                                [% ELSE %]
796
                                <option value="charge">Refund lost item charge and charge new overdue fine</option>
779
                                <option value="1">
797
                                <option value="restore">Refund lost item charge and restore overdue fine</option>
798
                                <option value="0">Leave lost item charge</option>
799
                                [% ELSIF ( refundLostItemFeeRule.rule_value == 'charge' ) %]
800
                                <option value="refund">Refund lost item charge</option>
801
                                <option value="charge" selected="selected">Refund lost item charge and charge new overdue fine</option>
802
                                <option value="restore">Refund lost item charge and restore overdue fine</option>
803
                                <option value="0">Leave lost item charge</option>
804
                                [% ELSIF ( refundLostItemFeeRule.rule_value == 'restore' ) %]
805
                                <option value="refund">Refund lost item charge</option>
806
                                <option value="charge">Refund lost item charge and charge new overdue fine</option>
807
                                <option value="restore" selected="selected">Refund lost item charge and restore overdue fine</option>
808
                                <option value="0">Leave lost item charge</option>
809
                                [% ELSIF ( refundLostItemFeeRule.rule_value == 0 ) %]
810
                                <option value="refund">Refund lost item charge</option>
811
                                <option value="charge">Refund lost item charge and charge new overdue fine</option>
812
                                <option value="restore">Refund lost item charge and restore overdue fine</option>
813
                                <option value="0" selected="selected">Leave lost item charge</option>
780
                                [% END %]
814
                                [% END %]
781
                                    Yes
782
                                </option>
783
                                [% IF ( not refundLostItemFeeRule.rule_value ) %]
784
                                <option value="0" selected="selected">
785
                                [% ELSE %]
786
                                <option value="0">
787
                                [% END %]
788
                                    No
789
                                </option>
790
                            [% END %]
815
                            [% END %]
791
                          [% END %]
816
                          [% END %]
792
                        </select>
817
                        </select>
793
- 

Return to bug 23091