From cf0ce1c5b53ac1aeb9375112f19c921dafc3889a Mon Sep 17 00:00:00 2001 From: Aleisha Amohia Date: Wed, 12 Oct 2022 04:22:31 +0000 Subject: [PATCH] Bug 23012: Set policy for lost item processing fee Signed-off-by: David Nind Signed-off-by: Nick Clemens --- Koha/CirculationRules.pm | 48 ++++- admin/smart-rules.pl | 31 ++- .../prog/en/modules/admin/smart-rules.tt | 61 +++++- t/db_dependent/Koha/CirculationRules.t | 177 +++++++++++++++++- 4 files changed, 310 insertions(+), 7 deletions(-) diff --git a/Koha/CirculationRules.pm b/Koha/CirculationRules.pm index c44ac8510e..64999533b5 100644 --- a/Koha/CirculationRules.pm +++ b/Koha/CirculationRules.pm @@ -51,7 +51,9 @@ our $RULE_KINDS = { lostreturn => { scope => [ 'branchcode' ], }, - + processingreturn => { + scope => [ 'branchcode' ], + }, patron_maxissueqty => { scope => [ 'branchcode', 'categorycode' ], }, @@ -617,6 +619,50 @@ sub get_lostreturn_policy { return $rule ? $rule->rule_value : 'refund'; } +=head3 get_processingreturn_policy + + my $processingrefund_policy = Koha::CirculationRules->get_processingreturn_policy( { return_branch => $return_branch, item => $item } ); + +Return values are: + +=over 2 + +=item '0' - Do not refund + +=item 'refund' - Refund the lost item processing charge + +=item 'restore' - Refund the lost item processing charge and restore the original overdue fine + +=item 'charge' - Refund the lost item processing charge and charge a new overdue fine + +=back + +=cut + +sub get_processingreturn_policy { + my ( $class, $params ) = @_; + + my $item = $params->{item}; + + my $behaviour = C4::Context->preference( 'RefundLostOnReturnControl' ) // 'CheckinLibrary'; + my $behaviour_mapping = { + CheckinLibrary => $params->{'return_branch'} // $item->homebranch, + ItemHomeBranch => $item->homebranch, + ItemHoldingBranch => $item->holdingbranch + }; + + my $branch = $behaviour_mapping->{ $behaviour }; + + my $rule = Koha::CirculationRules->get_effective_rule( + { + branchcode => $branch, + rule_name => 'processingreturn', + } + ); + + return $rule ? $rule->rule_value : 'refund'; +} + =head3 article_requestable_rules Return rules that allow article requests, optionally filtered by diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl index 7c3b5b86ae..b71179437f 100755 --- a/admin/smart-rules.pl +++ b/admin/smart-rules.pl @@ -654,6 +654,31 @@ elsif ( $op eq 'mod-refund-lost-item-fee-rule' ) { } ); } + + my $processingreturn = $input->param('processingreturn'); + + if ( $processingreturn eq '*' ) { + if ( $branch ne '*' ) { + # only do something for $processingreturn eq '*' if branch-specific + Koha::CirculationRules->set_rules( + { + branchcode => $branch, + rules => { + processingreturn => undef + } + } + ); + } + } else { + Koha::CirculationRules->set_rules( + { + branchcode => $branch, + rules => { + processingreturn => $processingreturn + } + } + ); + } } elsif ( $op eq "set-waiting-hold-cancellation" ) { my $category = $input->param('waiting_hold_cancellation_category'); @@ -691,9 +716,13 @@ elsif ( $op eq 'mod-refund-lost-item-fee-rule' ) { my $refundLostItemFeeRule = Koha::CirculationRules->find({ branchcode => ($branch eq '*') ? undef : $branch, rule_name => 'lostreturn' }); my $defaultLostItemFeeRule = Koha::CirculationRules->find({ branchcode => undef, rule_name => 'lostreturn' }); +my $refundProcessingFeeRule = Koha::CirculationRules->find({ branchcode => ($branch eq '*') ? undef : $branch, rule_name => 'processingreturn' }); +my $defaultProcessingFeeRule = Koha::CirculationRules->find({ branchcode => undef, rule_name => 'processingreturn' }); $template->param( refundLostItemFeeRule => $refundLostItemFeeRule, - defaultRefundRule => $defaultLostItemFeeRule ? $defaultLostItemFeeRule->rule_value : 'refund' + defaultRefundRule => $defaultLostItemFeeRule ? $defaultLostItemFeeRule->rule_value : 'refund', + refundProcessingFeeRule => $refundProcessingFeeRule, + defaultProcessingRefundRule => $defaultProcessingFeeRule ? $defaultProcessingFeeRule->rule_value : 'refund', ); my $patron_categories = Koha::Patron::Categories->search({}, { order_by => ['description'] }); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt index 86467d0196..a850d9dff4 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt @@ -1073,7 +1073,8 @@ - + + @@ -1179,6 +1180,64 @@ [% END %] + diff --git a/t/db_dependent/Koha/CirculationRules.t b/t/db_dependent/Koha/CirculationRules.t index 7117484d20..8664505524 100755 --- a/t/db_dependent/Koha/CirculationRules.t +++ b/t/db_dependent/Koha/CirculationRules.t @@ -20,7 +20,7 @@ use Modern::Perl; use Benchmark; -use Test::More tests => 7; +use Test::More tests => 8; use Test::Deep qw( cmp_methods ); use Test::Exception; @@ -161,7 +161,7 @@ subtest 'set_rule' => sub { my $itemtype = $builder->build({ source => 'Itemtype' })->{'itemtype'}; subtest 'Correct call' => sub { - plan tests => 4; + plan tests => 5; Koha::CirculationRules->delete; @@ -173,6 +173,14 @@ subtest 'set_rule' => sub { } ); }, 'setting lostreturn with branch' ); + lives_ok( sub { + Koha::CirculationRules->set_rule( { + branchcode => $branchcode, + rule_name => 'processingreturn', + rule_value => '', + } ); + }, 'setting processingreturn with branch' ); + lives_ok( sub { Koha::CirculationRules->set_rule( { branchcode => $branchcode, @@ -203,7 +211,7 @@ subtest 'set_rule' => sub { }; subtest 'Call with missing params' => sub { - plan tests => 4; + plan tests => 5; Koha::CirculationRules->delete; @@ -214,6 +222,13 @@ subtest 'set_rule' => sub { } ); }, qr/branchcode/, 'setting lostreturn without branch fails' ); + throws_ok( sub { + Koha::CirculationRules->set_rule( { + rule_name => 'processingreturn', + rule_value => '', + } ); + }, qr/branchcode/, 'setting processingreturn without branch fails' ); + throws_ok( sub { Koha::CirculationRules->set_rule( { branchcode => $branchcode, @@ -241,7 +256,7 @@ subtest 'set_rule' => sub { }; subtest 'Call with extra params' => sub { - plan tests => 3; + plan tests => 4; Koha::CirculationRules->delete; @@ -254,6 +269,15 @@ subtest 'set_rule' => sub { } ); }, qr/categorycode/, 'setting lostreturn with categorycode fails' ); + throws_ok( sub { + Koha::CirculationRules->set_rule( { + branchcode => $branchcode, + categorycode => $categorycode, + rule_name => 'processingreturn', + rule_value => '', + } ); + }, qr/categorycode/, 'setting processingreturn with categorycode fails' ); + throws_ok( sub { Koha::CirculationRules->set_rule( { branchcode => $branchcode, @@ -801,6 +825,151 @@ subtest 'get_lostreturn_policy() tests' => sub { $schema->storage->txn_rollback; }; +subtest 'get_processingreturn_policy() tests' => sub { + plan tests => 7; + + $schema->storage->txn_begin; + + $schema->resultset('CirculationRule')->search()->delete; + + my $default_rule_charge = $builder->build( + { + source => 'CirculationRule', + value => { + branchcode => undef, + categorycode => undef, + itemtype => undef, + rule_name => 'processingreturn', + rule_value => 'charge' + } + } + ); + my $branchcode = $builder->build( { source => 'Branch' } )->{branchcode}; + my $specific_rule_false = $builder->build( + { + source => 'CirculationRule', + value => { + branchcode => $branchcode, + categorycode => undef, + itemtype => undef, + rule_name => 'processingreturn', + rule_value => 0 + } + } + ); + my $branchcode2 = $builder->build( { source => 'Branch' } )->{branchcode}; + my $specific_rule_refund = $builder->build( + { + source => 'CirculationRule', + value => { + branchcode => $branchcode2, + categorycode => undef, + itemtype => undef, + rule_name => 'processingreturn', + rule_value => 'refund' + } + } + ); + my $branchcode3 = $builder->build( { source => 'Branch' } )->{branchcode}; + my $specific_rule_restore = $builder->build( + { + source => 'CirculationRule', + value => { + branchcode => $branchcode3, + categorycode => undef, + itemtype => undef, + rule_name => 'processingreturn', + rule_value => 'restore' + } + } + ); + + # Make sure we have an unused branchcode + my $branchcode4 = $builder->build( { source => 'Branch' } )->{branchcode}; + my $specific_rule_dummy = $builder->build( + { + source => 'CirculationRule', + value => { + branchcode => $branchcode4, + categorycode => undef, + itemtype => undef, + rule_name => 'processingreturn', + rule_value => 'refund' + } + } + ); + my $branch_without_rule = $specific_rule_dummy->{ branchcode }; + Koha::CirculationRules + ->search( + { + branchcode => $branch_without_rule, + categorycode => undef, + itemtype => undef, + rule_name => 'processingreturn', + rule_value => 'refund' + } + ) + ->next + ->delete; + + my $item = $builder->build_sample_item( + { + homebranch => $specific_rule_restore->{branchcode}, + holdingbranch => $specific_rule_false->{branchcode} + } + ); + my $params = { + return_branch => $specific_rule_refund->{ branchcode }, + item => $item + }; + + # Specific rules + t::lib::Mocks::mock_preference( 'RefundLostOnReturnControl', 'CheckinLibrary' ); + is( Koha::CirculationRules->get_processingreturn_policy( $params ), + 'refund','Specific rule for checkin branch is applied (refund)'); + + t::lib::Mocks::mock_preference( 'RefundLostOnReturnControl', 'ItemHomeBranch' ); + is( Koha::CirculationRules->get_processingreturn_policy( $params ), + 'restore','Specific rule for home branch is applied (restore)'); + + t::lib::Mocks::mock_preference( 'RefundLostOnReturnControl', 'ItemHoldingBranch' ); + is( Koha::CirculationRules->get_processingreturn_policy( $params ), + 0,'Specific rule for holding branch is applied (false)'); + + # Default rule check + t::lib::Mocks::mock_preference( 'RefundLostOnReturnControl', 'CheckinLibrary' ); + $params->{return_branch} = $branch_without_rule; + is( Koha::CirculationRules->get_processingreturn_policy( $params ), + 'charge','No rule for branch, global rule applied (charge)'); + + # Change the default value just to try + Koha::CirculationRules->search({ branchcode => undef, rule_name => 'processingreturn' })->next->rule_value(0)->store; + is( Koha::CirculationRules->get_processingreturn_policy( $params ), + 0,'No rule for branch, global rule applied (false)'); + + # No default rule defined check + Koha::CirculationRules + ->search( + { + branchcode => undef, + categorycode => undef, + itemtype => undef, + rule_name => 'processingreturn' + } + ) + ->next + ->delete; + is( Koha::CirculationRules->get_processingreturn_policy( $params ), + 'refund','No rule for branch, no default rule, fallback default (refund)'); + + # Fallback to ItemHoldBranch if CheckinLibrary is undefined + $params->{return_branch} = undef; + is( Koha::CirculationRules->get_processingreturn_policy( $params ), + 'restore','return_branch undefined, fallback to ItemHomeBranch rule (restore)'); + + $schema->storage->txn_rollback; +}; + sub _is_row_match { my ( $rule, $expected, $message ) = @_; -- 2.30.2
Refund lost item feeRefund lost item replacement feeRefund lost item processing fee  
+ +