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

(-)a/C4/Circulation.pm (-3 / +29 lines)
Lines 1445-1455 sub AddIssue { Link Here
1445
1445
1446
            ## If item was lost, it has now been found, reverse any list item charges if necessary.
1446
            ## If item was lost, it has now been found, reverse any list item charges if necessary.
1447
            if ( $item_object->itemlost ) {
1447
            if ( $item_object->itemlost ) {
1448
                my $refund = 1;
1449
                my $no_refund_after_days = C4::Context->preference('NoRefundOnLostReturnedItemsAge');
1450
                if ($no_refund_after_days) {
1451
                    my $today = dt_from_string();
1452
                    my $lost_age_in_days =
1453
                      dt_from_string( $item_object->itemlost_on )
1454
                      ->delta_days($today)
1455
                      ->in_units('days');
1456
1457
                    $refund = 0 unless ( $lost_age_in_days < $no_refund_after_days );
1458
                }
1459
1448
                if (
1460
                if (
1449
                    Koha::RefundLostItemFeeRules->should_refund(
1461
                    $refund
1462
                    && Koha::RefundLostItemFeeRules->should_refund(
1450
                        {
1463
                        {
1451
                            current_branch      => C4::Context->userenv->{branch},
1464
                            current_branch   => C4::Context->userenv->{branch},
1452
                            item_home_branch    => $item_object->homebranch,
1465
                            item_home_branch => $item_object->homebranch,
1453
                            item_holding_branch => $item_object->holdingbranch,
1466
                            item_holding_branch => $item_object->holdingbranch,
1454
                        }
1467
                        }
1455
                    )
1468
                    )
Lines 2027-2033 sub AddReturn { Link Here
2027
    if ( $item->itemlost ) {
2040
    if ( $item->itemlost ) {
2028
        $messages->{'WasLost'} = 1;
2041
        $messages->{'WasLost'} = 1;
2029
        unless ( C4::Context->preference("BlockReturnOfLostItems") ) {
2042
        unless ( C4::Context->preference("BlockReturnOfLostItems") ) {
2043
            my $refund = 1;
2044
            my $no_refund_after_days = C4::Context->preference('NoRefundOnLostReturnedItemsAge');
2045
            if ($no_refund_after_days) {
2046
                my $today = dt_from_string();
2047
                my $lost_age_in_days =
2048
                  dt_from_string( $item->itemlost_on )
2049
                  ->delta_days($today)
2050
                  ->in_units('days');
2051
2052
                $refund = 0 unless ( $lost_age_in_days < $no_refund_after_days );
2053
            }
2054
2030
            if (
2055
            if (
2056
                $refund &&
2031
                Koha::RefundLostItemFeeRules->should_refund(
2057
                Koha::RefundLostItemFeeRules->should_refund(
2032
                    {
2058
                    {
2033
                        current_branch      => C4::Context->userenv->{branch},
2059
                        current_branch      => C4::Context->userenv->{branch},
(-)a/installer/data/mysql/atomicupdate/bug_20815.perl (+10 lines)
Line 0 Link Here
1
$DBversion = 'XXX'; # will be replaced by the RM
2
if( CheckVersion( $DBversion ) ) {
3
    $dbh->do(q{
4
        INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
5
        ('NoRefundOnLostReturnedItemsAge','','','Do not refund lost item fees if item is lost for more than this number of days','Integer')
6
    });
7
8
    SetVersion( $DBversion );
9
    print "Upgrade to $DBversion done (Bug XXXXX - description)\n";
10
}
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 327-332 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
327
('noissuescharge','5','','Define maximum amount withstanding before check outs are blocked','Integer'),
327
('noissuescharge','5','','Define maximum amount withstanding before check outs are blocked','Integer'),
328
('NoIssuesChargeGuarantees','','','Define maximum amount withstanding before check outs are blocked','Integer'),
328
('NoIssuesChargeGuarantees','','','Define maximum amount withstanding before check outs are blocked','Integer'),
329
('noItemTypeImages','0',NULL,'If ON, disables item-type images','YesNo'),
329
('noItemTypeImages','0',NULL,'If ON, disables item-type images','YesNo'),
330
('NoRefundOnLostReturnedItemsAge','','','Do not refund lost item fees if item is lost for more than this number of days','Integer'),
330
('NoRenewalBeforePrecision','exact_time','date|exact_time','Calculate "No renewal before" based on date only or exact time of due date','Choice'),
331
('NoRenewalBeforePrecision','exact_time','date|exact_time','Calculate "No renewal before" based on date only or exact time of due date','Choice'),
331
('NotesBlacklist','',NULL,'List of notes fields that should not appear in the title notes/description separator of details','free'),
332
('NotesBlacklist','',NULL,'List of notes fields that should not appear in the title notes/description separator of details','free'),
332
('NotHighlightedWords','and|or|not',NULL,'List of words to NOT highlight when OpacHitHighlight is enabled','free'),
333
('NotHighlightedWords','and|or|not',NULL,'List of words to NOT highlight when OpacHitHighlight is enabled','free'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (+5 lines)
Lines 878-883 Circulation: Link Here
878
                  yes: Forgive
878
                  yes: Forgive
879
                  no: "Don't Forgive"
879
                  no: "Don't Forgive"
880
            - the fines on an item when it is lost.
880
            - the fines on an item when it is lost.
881
        -
882
            - "Don't refund lost fees if a lost item is returned more than"
883
            - pref: NoRefundOnLostReturnedItemsAge
884
              class: integer
885
            - days after it was marked lost.
881
        -
886
        -
882
            - pref: WhenLostChargeReplacementFee
887
            - pref: WhenLostChargeReplacementFee
883
              choices:
888
              choices:
(-)a/t/db_dependent/Circulation.t (-2 / +301 lines)
Lines 18-24 Link Here
18
use Modern::Perl;
18
use Modern::Perl;
19
use utf8;
19
use utf8;
20
20
21
use Test::More tests => 46;
21
use Test::More tests => 50;
22
use Test::MockModule;
22
use Test::MockModule;
23
use Test::Deep qw( cmp_deeply );
23
use Test::Deep qw( cmp_deeply );
24
24
Lines 3721-3726 subtest "Test Backdating of Returns" => sub { Link Here
3721
    is( $accountline->amount+0, 0, 'Fee amount was reduced to 0' );
3721
    is( $accountline->amount+0, 0, 'Fee amount was reduced to 0' );
3722
};
3722
};
3723
3723
3724
subtest 'Tests for NoRefundOnLostReturnedItemsAge = undef' => sub {
3725
    plan tests => 3;
3726
3727
    t::lib::Mocks::mock_preference( 'WhenLostChargeReplacementFee',   1 );
3728
    t::lib::Mocks::mock_preference( 'NoRefundOnLostReturnedItemsAge', undef );
3729
3730
    my $lost_on = dt_from_string->subtract( days => 7 )->date;
3731
3732
    my $library = $builder->build( { source => 'Branch' } );
3733
    my $patron  = $builder->build(
3734
        {
3735
            source => 'Borrower',
3736
            value  => { categorycode => $patron_category->{categorycode} }
3737
        }
3738
    );
3739
3740
    my $biblionumber = $builder->build_sample_biblio(
3741
        {
3742
            branchcode => $library->{branchcode},
3743
        }
3744
    )->biblionumber;
3745
    my $item = $builder->build_sample_item(
3746
        {
3747
            biblionumber     => $biblionumber,
3748
            library          => $library->{branchcode},
3749
            replacementprice => '42.00',
3750
        }
3751
    );
3752
3753
    # And the circulation rule
3754
    Koha::CirculationRules->search->delete;
3755
    Koha::CirculationRules->set_rules(
3756
        {
3757
            categorycode => undef,
3758
            itemtype     => undef,
3759
            branchcode   => undef,
3760
            rules        => {
3761
                issuelength => 14,
3762
                lengthunit  => 'days',
3763
            }
3764
        }
3765
    );
3766
    $builder->build(
3767
        {
3768
            source => 'CirculationRule',
3769
            value  => {
3770
                branchcode   => undef,
3771
                categorycode => undef,
3772
                itemtype     => undef,
3773
                rule_name    => 'refund',
3774
                rule_value   => 1
3775
            }
3776
        }
3777
    );
3778
3779
    # Test with NoRefundOnLostReturnedItemsAge disabled
3780
    my $issue = AddIssue( $patron, $item->barcode );
3781
    LostItem( $item->itemnumber, 'cli', 0 );
3782
    $item->itemlost(1);
3783
    $item->itemlost_on( $lost_on );
3784
    $item->store();
3785
3786
    my $a = Koha::Account::Lines->find(
3787
        {
3788
            itemnumber     => $item->id,
3789
            borrowernumber => $patron->{borrowernumber}
3790
        }
3791
    );
3792
    ok( $a, "Found accountline for lost fee" );
3793
    is( $a->amountoutstanding, '42.000000', "Lost fee charged correctly" );
3794
    my ( $doreturn, $messages ) = AddReturn( $item->barcode, $library->{branchcode}, undef, dt_from_string );
3795
    $a = Koha::Account::Lines->find( $a->id );
3796
    is( $a->amountoutstanding, '0.000000', "Lost fee was refunded" );
3797
};
3798
3799
subtest 'Tests for NoRefundOnLostReturnedItemsAge > length of days item has been lost' => sub {
3800
    plan tests => 3;
3801
3802
    t::lib::Mocks::mock_preference( 'WhenLostChargeReplacementFee',   1 );
3803
    t::lib::Mocks::mock_preference( 'NoRefundOnLostReturnedItemsAge', 7 );
3804
3805
    my $lost_on = dt_from_string->subtract( days => 6 )->date;
3806
3807
    my $library = $builder->build( { source => 'Branch' } );
3808
    my $patron  = $builder->build(
3809
        {
3810
            source => 'Borrower',
3811
            value  => { categorycode => $patron_category->{categorycode} }
3812
        }
3813
    );
3814
3815
    my $biblionumber = $builder->build_sample_biblio(
3816
        {
3817
            branchcode => $library->{branchcode},
3818
        }
3819
    )->biblionumber;
3820
    my $item = $builder->build_sample_item(
3821
        {
3822
            biblionumber     => $biblionumber,
3823
            library          => $library->{branchcode},
3824
            replacementprice => '42.00',
3825
        }
3826
    );
3827
3828
    # And the circulation rule
3829
    Koha::CirculationRules->search->delete;
3830
    Koha::CirculationRules->set_rules(
3831
        {
3832
            categorycode => undef,
3833
            itemtype     => undef,
3834
            branchcode   => undef,
3835
            rules        => {
3836
                issuelength => 14,
3837
                lengthunit  => 'days',
3838
            }
3839
        }
3840
    );
3841
    $builder->build(
3842
        {
3843
            source => 'CirculationRule',
3844
            value  => {
3845
                branchcode   => undef,
3846
                categorycode => undef,
3847
                itemtype     => undef,
3848
                rule_name    => 'refund',
3849
                rule_value   => 1
3850
            }
3851
        }
3852
    );
3853
3854
    # Test with NoRefundOnLostReturnedItemsAge disabled
3855
    my $issue = AddIssue( $patron, $item->barcode );
3856
    LostItem( $item->itemnumber, 'cli', 0 );
3857
    $item->itemlost(1);
3858
    $item->itemlost_on( $lost_on );
3859
    $item->store();
3860
3861
    my $a = Koha::Account::Lines->find(
3862
        {
3863
            itemnumber     => $item->id,
3864
            borrowernumber => $patron->{borrowernumber}
3865
        }
3866
    );
3867
    ok( $a, "Found accountline for lost fee" );
3868
    is( $a->amountoutstanding, '42.000000', "Lost fee charged correctly" );
3869
    my ( $doreturn, $messages ) = AddReturn( $item->barcode, $library->{branchcode}, undef, dt_from_string );
3870
    $a = Koha::Account::Lines->find( $a->id );
3871
    is( $a->amountoutstanding, '0.000000', "Lost fee was refunded" );
3872
};
3873
3874
subtest 'Tests for NoRefundOnLostReturnedItemsAge = length of days item has been lost' => sub {
3875
    plan tests => 3;
3876
3877
    t::lib::Mocks::mock_preference( 'WhenLostChargeReplacementFee',   1 );
3878
    t::lib::Mocks::mock_preference( 'NoRefundOnLostReturnedItemsAge', 7 );
3879
3880
    my $lost_on = dt_from_string->subtract( days => 7 )->date;
3881
3882
    my $library = $builder->build( { source => 'Branch' } );
3883
    my $patron  = $builder->build(
3884
        {
3885
            source => 'Borrower',
3886
            value  => { categorycode => $patron_category->{categorycode} }
3887
        }
3888
    );
3889
3890
    my $biblionumber = $builder->build_sample_biblio(
3891
        {
3892
            branchcode => $library->{branchcode},
3893
        }
3894
    )->biblionumber;
3895
    my $item = $builder->build_sample_item(
3896
        {
3897
            biblionumber     => $biblionumber,
3898
            library          => $library->{branchcode},
3899
            replacementprice => '42.00',
3900
        }
3901
    );
3902
3903
    # And the circulation rule
3904
    Koha::CirculationRules->search->delete;
3905
    Koha::CirculationRules->set_rules(
3906
        {
3907
            categorycode => undef,
3908
            itemtype     => undef,
3909
            branchcode   => undef,
3910
            rules        => {
3911
                issuelength => 14,
3912
                lengthunit  => 'days',
3913
            }
3914
        }
3915
    );
3916
    $builder->build(
3917
        {
3918
            source => 'CirculationRule',
3919
            value  => {
3920
                branchcode   => undef,
3921
                categorycode => undef,
3922
                itemtype     => undef,
3923
                rule_name    => 'refund',
3924
                rule_value   => 1
3925
            }
3926
        }
3927
    );
3928
3929
    # Test with NoRefundOnLostReturnedItemsAge disabled
3930
    my $issue = AddIssue( $patron, $item->barcode );
3931
    LostItem( $item->itemnumber, 'cli', 0 );
3932
    $item->itemlost(1);
3933
    $item->itemlost_on( $lost_on );
3934
    $item->store();
3935
3936
    my $a = Koha::Account::Lines->find(
3937
        {
3938
            itemnumber     => $item->id,
3939
            borrowernumber => $patron->{borrowernumber}
3940
        }
3941
    );
3942
    ok( $a, "Found accountline for lost fee" );
3943
    is( $a->amountoutstanding, '42.000000', "Lost fee charged correctly" );
3944
    my ( $doreturn, $messages ) = AddReturn( $item->barcode, $library->{branchcode}, undef, dt_from_string );
3945
    $a = Koha::Account::Lines->find( $a->id );
3946
    is( $a->amountoutstanding, '42.000000', "Lost fee was not refunded" );
3947
};
3948
3949
subtest 'Tests for NoRefundOnLostReturnedItemsAge < length of days item has been lost' => sub {
3950
    plan tests => 3;
3951
3952
    t::lib::Mocks::mock_preference( 'WhenLostChargeReplacementFee',   1 );
3953
    t::lib::Mocks::mock_preference( 'NoRefundOnLostReturnedItemsAge', 7 );
3954
3955
    my $lost_on = dt_from_string->subtract( days => 8 )->date;
3956
3957
    my $library = $builder->build( { source => 'Branch' } );
3958
    my $patron  = $builder->build(
3959
        {
3960
            source => 'Borrower',
3961
            value  => { categorycode => $patron_category->{categorycode} }
3962
        }
3963
    );
3964
3965
    my $biblionumber = $builder->build_sample_biblio(
3966
        {
3967
            branchcode => $library->{branchcode},
3968
        }
3969
    )->biblionumber;
3970
    my $item = $builder->build_sample_item(
3971
        {
3972
            biblionumber     => $biblionumber,
3973
            library          => $library->{branchcode},
3974
            replacementprice => '42.00',
3975
        }
3976
    );
3977
3978
    # And the circulation rule
3979
    Koha::CirculationRules->search->delete;
3980
    Koha::CirculationRules->set_rules(
3981
        {
3982
            categorycode => undef,
3983
            itemtype     => undef,
3984
            branchcode   => undef,
3985
            rules        => {
3986
                issuelength => 14,
3987
                lengthunit  => 'days',
3988
            }
3989
        }
3990
    );
3991
    $builder->build(
3992
        {
3993
            source => 'CirculationRule',
3994
            value  => {
3995
                branchcode   => undef,
3996
                categorycode => undef,
3997
                itemtype     => undef,
3998
                rule_name    => 'refund',
3999
                rule_value   => 1
4000
            }
4001
        }
4002
    );
4003
4004
    # Test with NoRefundOnLostReturnedItemsAge disabled
4005
    my $issue = AddIssue( $patron, $item->barcode );
4006
    LostItem( $item->itemnumber, 'cli', 0 );
4007
    $item->itemlost(1);
4008
    $item->itemlost_on( $lost_on );
4009
    $item->store();
4010
4011
    my $a = Koha::Account::Lines->find(
4012
        {
4013
            itemnumber     => $item->id,
4014
            borrowernumber => $patron->{borrowernumber}
4015
        }
4016
    );
4017
    ok( $a, "Found accountline for lost fee" );
4018
    is( $a->amountoutstanding, '42.000000', "Lost fee charged correctly" );
4019
    my ( $doreturn, $messages ) = AddReturn( $item->barcode, $library->{branchcode}, undef, dt_from_string );
4020
    $a = Koha::Account::Lines->find( $a->id );
4021
    is( $a->amountoutstanding, '42.000000', "Lost fee was not refunded" );
4022
};
4023
3724
$schema->storage->txn_rollback;
4024
$schema->storage->txn_rollback;
3725
C4::Context->clear_syspref_cache();
4025
C4::Context->clear_syspref_cache();
3726
$cache->clear_from_cache('single_holidays');
4026
$cache->clear_from_cache('single_holidays');
3727
- 

Return to bug 20815