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

(-)a/C4/Circulation.pm (-3 / +29 lines)
Lines 1447-1457 sub AddIssue { Link Here
1447
1447
1448
            ## If item was lost, it has now been found, reverse any list item charges if necessary.
1448
            ## If item was lost, it has now been found, reverse any list item charges if necessary.
1449
            if ( $item_object->itemlost ) {
1449
            if ( $item_object->itemlost ) {
1450
                my $refund = 1;
1451
                my $no_refund_after_days = C4::Context->preference('NoRefundOnLostReturnedItemsAge');
1452
                if ($no_refund_after_days) {
1453
                    my $today = dt_from_string();
1454
                    my $lost_age_in_days =
1455
                      dt_from_string( $item_object->itemlost_on )
1456
                      ->delta_days($today)
1457
                      ->in_units('days');
1458
1459
                    $refund = 0 unless ( $lost_age_in_days < $no_refund_after_days );
1460
                }
1461
1450
                if (
1462
                if (
1451
                    Koha::RefundLostItemFeeRules->should_refund(
1463
                    $refund
1464
                    && Koha::RefundLostItemFeeRules->should_refund(
1452
                        {
1465
                        {
1453
                            current_branch      => C4::Context->userenv->{branch},
1466
                            current_branch   => C4::Context->userenv->{branch},
1454
                            item_home_branch    => $item_object->homebranch,
1467
                            item_home_branch => $item_object->homebranch,
1455
                            item_holding_branch => $item_object->holdingbranch,
1468
                            item_holding_branch => $item_object->holdingbranch,
1456
                        }
1469
                        }
1457
                    )
1470
                    )
Lines 2031-2037 sub AddReturn { Link Here
2031
    if ( $item->itemlost ) {
2044
    if ( $item->itemlost ) {
2032
        $messages->{'WasLost'} = 1;
2045
        $messages->{'WasLost'} = 1;
2033
        unless ( C4::Context->preference("BlockReturnOfLostItems") ) {
2046
        unless ( C4::Context->preference("BlockReturnOfLostItems") ) {
2047
            my $refund = 1;
2048
            my $no_refund_after_days = C4::Context->preference('NoRefundOnLostReturnedItemsAge');
2049
            if ($no_refund_after_days) {
2050
                my $today = dt_from_string();
2051
                my $lost_age_in_days =
2052
                  dt_from_string( $item->itemlost_on )
2053
                  ->delta_days($today)
2054
                  ->in_units('days');
2055
2056
                $refund = 0 unless ( $lost_age_in_days < $no_refund_after_days );
2057
            }
2058
2034
            if (
2059
            if (
2060
                $refund &&
2035
                Koha::RefundLostItemFeeRules->should_refund(
2061
                Koha::RefundLostItemFeeRules->should_refund(
2036
                    {
2062
                    {
2037
                        current_branch      => C4::Context->userenv->{branch},
2063
                        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 332-337 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
332
('noissuescharge','5','','Define maximum amount withstanding before check outs are blocked','Integer'),
332
('noissuescharge','5','','Define maximum amount withstanding before check outs are blocked','Integer'),
333
('NoIssuesChargeGuarantees','','','Define maximum amount withstanding before check outs are blocked','Integer'),
333
('NoIssuesChargeGuarantees','','','Define maximum amount withstanding before check outs are blocked','Integer'),
334
('noItemTypeImages','0',NULL,'If ON, disables itemtype images in the staff interface','YesNo'),
334
('noItemTypeImages','0',NULL,'If ON, disables itemtype images in the staff interface','YesNo'),
335
('NoRefundOnLostReturnedItemsAge','','','Do not refund lost item fees if item is lost for more than this number of days','Integer'),
335
('NoRenewalBeforePrecision','exact_time','date|exact_time','Calculate "No renewal before" based on date only or exact time of due date','Choice'),
336
('NoRenewalBeforePrecision','exact_time','date|exact_time','Calculate "No renewal before" based on date only or exact time of due date','Choice'),
336
('NotesBlacklist','',NULL,'List of notes fields that should not appear in the title notes/description separator of details','free'),
337
('NotesBlacklist','',NULL,'List of notes fields that should not appear in the title notes/description separator of details','free'),
337
('NotHighlightedWords','and|or|not',NULL,'List of words to NOT highlight when OpacHitHighlight is enabled','free'),
338
('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 930-935 Circulation: Link Here
930
                  yes: Forgive
930
                  yes: Forgive
931
                  no: "Don't Forgive"
931
                  no: "Don't Forgive"
932
            - the fines on an item when it is lost.
932
            - the fines on an item when it is lost.
933
        -
934
            - "Don't refund lost fees if a lost item is returned more than"
935
            - pref: NoRefundOnLostReturnedItemsAge
936
              class: integer
937
            - days after it was marked lost.
933
        -
938
        -
934
            - pref: WhenLostChargeReplacementFee
939
            - pref: WhenLostChargeReplacementFee
935
              choices:
940
              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 => 48;
21
use Test::More tests => 52;
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 3926-3931 subtest 'Filling a hold should cancel existing transfer' => sub { Link Here
3926
    is( Koha::Item::Transfers->search({ itemnumber => $item->itemnumber, datearrived => undef })->count, 0, "No outstanding transfers when hold is waiting");
3926
    is( Koha::Item::Transfers->search({ itemnumber => $item->itemnumber, datearrived => undef })->count, 0, "No outstanding transfers when hold is waiting");
3927
};
3927
};
3928
3928
3929
subtest 'Tests for NoRefundOnLostReturnedItemsAge = undef' => sub {
3930
    plan tests => 3;
3931
3932
    t::lib::Mocks::mock_preference( 'WhenLostChargeReplacementFee',   1 );
3933
    t::lib::Mocks::mock_preference( 'NoRefundOnLostReturnedItemsAge', undef );
3934
3935
    my $lost_on = dt_from_string->subtract( days => 7 )->date;
3936
3937
    my $library = $builder->build( { source => 'Branch' } );
3938
    my $patron  = $builder->build(
3939
        {
3940
            source => 'Borrower',
3941
            value  => { categorycode => $patron_category->{categorycode} }
3942
        }
3943
    );
3944
3945
    my $biblionumber = $builder->build_sample_biblio(
3946
        {
3947
            branchcode => $library->{branchcode},
3948
        }
3949
    )->biblionumber;
3950
    my $item = $builder->build_sample_item(
3951
        {
3952
            biblionumber     => $biblionumber,
3953
            library          => $library->{branchcode},
3954
            replacementprice => '42.00',
3955
        }
3956
    );
3957
3958
    # And the circulation rule
3959
    Koha::CirculationRules->search->delete;
3960
    Koha::CirculationRules->set_rules(
3961
        {
3962
            categorycode => undef,
3963
            itemtype     => undef,
3964
            branchcode   => undef,
3965
            rules        => {
3966
                issuelength => 14,
3967
                lengthunit  => 'days',
3968
            }
3969
        }
3970
    );
3971
    $builder->build(
3972
        {
3973
            source => 'CirculationRule',
3974
            value  => {
3975
                branchcode   => undef,
3976
                categorycode => undef,
3977
                itemtype     => undef,
3978
                rule_name    => 'refund',
3979
                rule_value   => 1
3980
            }
3981
        }
3982
    );
3983
3984
    # Test with NoRefundOnLostReturnedItemsAge disabled
3985
    my $issue = AddIssue( $patron, $item->barcode );
3986
    LostItem( $item->itemnumber, 'cli', 0 );
3987
    $item->_result->itemlost(1);
3988
    $item->_result->itemlost_on( $lost_on );
3989
    $item->_result->update();
3990
3991
    my $a = Koha::Account::Lines->find(
3992
        {
3993
            itemnumber     => $item->id,
3994
            borrowernumber => $patron->{borrowernumber}
3995
        }
3996
    );
3997
    ok( $a, "Found accountline for lost fee" );
3998
    is( $a->amountoutstanding, '42.000000', "Lost fee charged correctly" );
3999
    my ( $doreturn, $messages ) = AddReturn( $item->barcode, $library->{branchcode}, undef, dt_from_string );
4000
    $a = Koha::Account::Lines->find( $a->id );
4001
    is( $a->amountoutstanding, '0.000000', "Lost fee was refunded" );
4002
};
4003
4004
subtest 'Tests for NoRefundOnLostReturnedItemsAge > length of days item has been lost' => sub {
4005
    plan tests => 3;
4006
4007
    t::lib::Mocks::mock_preference( 'WhenLostChargeReplacementFee',   1 );
4008
    t::lib::Mocks::mock_preference( 'NoRefundOnLostReturnedItemsAge', 7 );
4009
4010
    my $lost_on = dt_from_string->subtract( days => 6 )->date;
4011
4012
    my $library = $builder->build( { source => 'Branch' } );
4013
    my $patron  = $builder->build(
4014
        {
4015
            source => 'Borrower',
4016
            value  => { categorycode => $patron_category->{categorycode} }
4017
        }
4018
    );
4019
4020
    my $biblionumber = $builder->build_sample_biblio(
4021
        {
4022
            branchcode => $library->{branchcode},
4023
        }
4024
    )->biblionumber;
4025
    my $item = $builder->build_sample_item(
4026
        {
4027
            biblionumber     => $biblionumber,
4028
            library          => $library->{branchcode},
4029
            replacementprice => '42.00',
4030
        }
4031
    );
4032
4033
    # And the circulation rule
4034
    Koha::CirculationRules->search->delete;
4035
    Koha::CirculationRules->set_rules(
4036
        {
4037
            categorycode => undef,
4038
            itemtype     => undef,
4039
            branchcode   => undef,
4040
            rules        => {
4041
                issuelength => 14,
4042
                lengthunit  => 'days',
4043
            }
4044
        }
4045
    );
4046
    $builder->build(
4047
        {
4048
            source => 'CirculationRule',
4049
            value  => {
4050
                branchcode   => undef,
4051
                categorycode => undef,
4052
                itemtype     => undef,
4053
                rule_name    => 'refund',
4054
                rule_value   => 1
4055
            }
4056
        }
4057
    );
4058
4059
    # Test with NoRefundOnLostReturnedItemsAge disabled
4060
    my $issue = AddIssue( $patron, $item->barcode );
4061
    LostItem( $item->itemnumber, 'cli', 0 );
4062
    $item->_result->itemlost(1);
4063
    $item->_result->itemlost_on( $lost_on );
4064
    $item->_result->update();
4065
4066
    my $a = Koha::Account::Lines->find(
4067
        {
4068
            itemnumber     => $item->id,
4069
            borrowernumber => $patron->{borrowernumber}
4070
        }
4071
    );
4072
    ok( $a, "Found accountline for lost fee" );
4073
    is( $a->amountoutstanding, '42.000000', "Lost fee charged correctly" );
4074
    my ( $doreturn, $messages ) = AddReturn( $item->barcode, $library->{branchcode}, undef, dt_from_string );
4075
    $a = Koha::Account::Lines->find( $a->id );
4076
    is( $a->amountoutstanding, '0.000000', "Lost fee was refunded" );
4077
};
4078
4079
subtest 'Tests for NoRefundOnLostReturnedItemsAge = length of days item has been lost' => sub {
4080
    plan tests => 3;
4081
4082
    t::lib::Mocks::mock_preference( 'WhenLostChargeReplacementFee',   1 );
4083
    t::lib::Mocks::mock_preference( 'NoRefundOnLostReturnedItemsAge', 7 );
4084
4085
    my $lost_on = dt_from_string->subtract( days => 7 )->date;
4086
4087
    my $library = $builder->build( { source => 'Branch' } );
4088
    my $patron  = $builder->build(
4089
        {
4090
            source => 'Borrower',
4091
            value  => { categorycode => $patron_category->{categorycode} }
4092
        }
4093
    );
4094
4095
    my $biblionumber = $builder->build_sample_biblio(
4096
        {
4097
            branchcode => $library->{branchcode},
4098
        }
4099
    )->biblionumber;
4100
    my $item = $builder->build_sample_item(
4101
        {
4102
            biblionumber     => $biblionumber,
4103
            library          => $library->{branchcode},
4104
            replacementprice => '42.00',
4105
        }
4106
    );
4107
4108
    # And the circulation rule
4109
    Koha::CirculationRules->search->delete;
4110
    Koha::CirculationRules->set_rules(
4111
        {
4112
            categorycode => undef,
4113
            itemtype     => undef,
4114
            branchcode   => undef,
4115
            rules        => {
4116
                issuelength => 14,
4117
                lengthunit  => 'days',
4118
            }
4119
        }
4120
    );
4121
    $builder->build(
4122
        {
4123
            source => 'CirculationRule',
4124
            value  => {
4125
                branchcode   => undef,
4126
                categorycode => undef,
4127
                itemtype     => undef,
4128
                rule_name    => 'refund',
4129
                rule_value   => 1
4130
            }
4131
        }
4132
    );
4133
4134
    # Test with NoRefundOnLostReturnedItemsAge disabled
4135
    my $issue = AddIssue( $patron, $item->barcode );
4136
    LostItem( $item->itemnumber, 'cli', 0 );
4137
    $item->_result->itemlost(1);
4138
    $item->_result->itemlost_on( $lost_on );
4139
    $item->_result->update();
4140
4141
    my $a = Koha::Account::Lines->find(
4142
        {
4143
            itemnumber     => $item->id,
4144
            borrowernumber => $patron->{borrowernumber}
4145
        }
4146
    );
4147
    ok( $a, "Found accountline for lost fee" );
4148
    is( $a->amountoutstanding, '42.000000', "Lost fee charged correctly" );
4149
    my ( $doreturn, $messages ) = AddReturn( $item->barcode, $library->{branchcode}, undef, dt_from_string );
4150
    $a = Koha::Account::Lines->find( $a->id );
4151
    is( $a->amountoutstanding, '42.000000', "Lost fee was not refunded" );
4152
};
4153
4154
subtest 'Tests for NoRefundOnLostReturnedItemsAge < length of days item has been lost' => sub {
4155
    plan tests => 3;
4156
4157
    t::lib::Mocks::mock_preference( 'WhenLostChargeReplacementFee',   1 );
4158
    t::lib::Mocks::mock_preference( 'NoRefundOnLostReturnedItemsAge', 7 );
4159
4160
    my $lost_on = dt_from_string->subtract( days => 8 )->date;
4161
4162
    my $library = $builder->build( { source => 'Branch' } );
4163
    my $patron  = $builder->build(
4164
        {
4165
            source => 'Borrower',
4166
            value  => { categorycode => $patron_category->{categorycode} }
4167
        }
4168
    );
4169
4170
    my $biblionumber = $builder->build_sample_biblio(
4171
        {
4172
            branchcode => $library->{branchcode},
4173
        }
4174
    )->biblionumber;
4175
    my $item = $builder->build_sample_item(
4176
        {
4177
            biblionumber     => $biblionumber,
4178
            library          => $library->{branchcode},
4179
            replacementprice => '42.00',
4180
        }
4181
    );
4182
4183
    # And the circulation rule
4184
    Koha::CirculationRules->search->delete;
4185
    Koha::CirculationRules->set_rules(
4186
        {
4187
            categorycode => undef,
4188
            itemtype     => undef,
4189
            branchcode   => undef,
4190
            rules        => {
4191
                issuelength => 14,
4192
                lengthunit  => 'days',
4193
            }
4194
        }
4195
    );
4196
    $builder->build(
4197
        {
4198
            source => 'CirculationRule',
4199
            value  => {
4200
                branchcode   => undef,
4201
                categorycode => undef,
4202
                itemtype     => undef,
4203
                rule_name    => 'refund',
4204
                rule_value   => 1
4205
            }
4206
        }
4207
    );
4208
4209
    # Test with NoRefundOnLostReturnedItemsAge disabled
4210
    my $issue = AddIssue( $patron, $item->barcode );
4211
    LostItem( $item->itemnumber, 'cli', 0 );
4212
    $item->_result->itemlost(1);
4213
    $item->_result->itemlost_on( $lost_on );
4214
    $item->_result->update();
4215
4216
    my $a = Koha::Account::Lines->find(
4217
        {
4218
            itemnumber     => $item->id,
4219
            borrowernumber => $patron->{borrowernumber}
4220
        }
4221
    );
4222
    ok( $a, "Found accountline for lost fee" );
4223
    is( $a->amountoutstanding, '42.000000', "Lost fee charged correctly" );
4224
    my ( $doreturn, $messages ) = AddReturn( $item->barcode, $library->{branchcode}, undef, dt_from_string );
4225
    $a = Koha::Account::Lines->find( $a->id );
4226
    is( $a->amountoutstanding, '42.000000', "Lost fee was not refunded" );
4227
};
4228
3929
$schema->storage->txn_rollback;
4229
$schema->storage->txn_rollback;
3930
C4::Context->clear_syspref_cache();
4230
C4::Context->clear_syspref_cache();
3931
$cache->clear_from_cache('single_holidays');
4231
$cache->clear_from_cache('single_holidays');
3932
- 

Return to bug 20815