From cb5b9875983f6b0a7d9483cb5248d134ba4354aa Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Thu, 2 Dec 2021 17:27:43 +0100 Subject: [PATCH] Bug 29623: Cache circulation rules --- C4/Circulation.pm | 37 +++++++++++++++++++++--------------- Koha/CirculationRules.pm | 35 ++++++++++++++++++++++++++++++++-- t/db_dependent/Circulation.t | 5 +++++ 3 files changed, 60 insertions(+), 17 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index d4cca7b1b1a..acf1bce3f00 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -1349,7 +1349,7 @@ sub checkHighHolds { my $orig_due = C4::Circulation::CalcDateDue( $issuedate, $itype, $branchcode, $borrower ); - my $rule = Koha::CirculationRules->get_effective_rule( + my $rule = Koha::CirculationRules->get_effective_rule_value( { categorycode => $borrower->{categorycode}, itemtype => $item_object->effective_itemtype, @@ -1359,9 +1359,9 @@ sub checkHighHolds { ); my $duration; - if ( defined($rule) && $rule->rule_value ne '' ){ + if ( defined($rule) && $rule ne '' ){ # overrides decreaseLoanHighHoldsDuration syspref - $duration = $rule->rule_value; + $duration = $rule; } else { $duration = C4::Context->preference('decreaseLoanHighHoldsDuration'); } @@ -1520,7 +1520,7 @@ sub AddIssue { # If automatic renewal wasn't selected while issuing, set the value according to the issuing rule. unless ($auto_renew) { - my $rule = Koha::CirculationRules->get_effective_rule( + my $rule = Koha::CirculationRules->get_effective_rule_value( { categorycode => $borrower->{categorycode}, itemtype => $item_object->effective_itemtype, @@ -1529,7 +1529,7 @@ sub AddIssue { } ); - $auto_renew = $rule->rule_value if $rule; + $auto_renew = $rule if defined $rule && $rule ne ''; } my $issue_attributes = { @@ -2763,11 +2763,7 @@ sub CanBookBeRenewed { branchcode => $branchcode, rules => [ 'renewalsallowed', - 'lengthunit', 'unseen_renewals_allowed', - 'no_auto_renewal_after', - 'no_auto_renewal_after_hard_limit', - 'norenewalbefore' ] } ); @@ -2792,14 +2788,13 @@ sub CanBookBeRenewed { return ( 0, 'overdue'); } - $soonest_renew_date = GetSoonestRenewDate($borrowernumber, $itemnumber, $branchcode, $issuing_rule); + $soonest_renew_date = GetSoonestRenewDate($borrowernumber, $itemnumber, $branchcode); $auto_renew = _CanBookBeAutoRenewed({ patron => $patron, item => $item, branchcode => $branchcode, issue => $issue, - issuing_rule => $issuing_rule, soonest => $soonest_renew_date }) if $issue->auto_renew && $patron->autorenew_checkouts; @@ -3168,7 +3163,7 @@ cannot be found. =cut sub GetSoonestRenewDate { - my ( $borrowernumber, $itemnumber, $branchcode, $issuing_rule ) = @_; + my ( $borrowernumber, $itemnumber, $branchcode ) = @_; my $dbh = C4::Context->dbh; @@ -3180,7 +3175,7 @@ sub GetSoonestRenewDate { or return; $branchcode = _GetCircControlBranch( $item->unblessed, $patron->unblessed ) unless $branchcode; - $issuing_rule = Koha::CirculationRules->get_effective_rules( + my $issuing_rule = Koha::CirculationRules->get_effective_rules( { categorycode => $patron->categorycode, itemtype => $item->effective_itemtype, branchcode => $branchcode, @@ -3189,7 +3184,7 @@ sub GetSoonestRenewDate { 'lengthunit', ] } - ) unless $issuing_rule; + ); my $now = dt_from_string; @@ -4278,12 +4273,24 @@ sub _CanBookBeAutoRenewed { my $branchcode = $params->{branchcode}; my $issue = $params->{issue}; my $soonest_renew_date = $params->{soonest}; - my $issuing_rule = $params->{issuing_rule}; if ( $patron->category->effective_BlockExpiredPatronOpacActions and $patron->is_expired ) { return 'auto_account_expired'; } + my $issuing_rule = Koha::CirculationRules->get_effective_rules( + { + categorycode => $patron->categorycode, + itemtype => $item->effective_itemtype, + branchcode => $branchcode, + rules => [ + 'no_auto_renewal_after', + 'no_auto_renewal_after_hard_limit', + 'lengthunit' + ] + } + ); + if ( defined $issuing_rule->{no_auto_renewal_after} and $issuing_rule->{no_auto_renewal_after} ne "" ) { # Get issue_date and add no_auto_renewal_after diff --git a/Koha/CirculationRules.pm b/Koha/CirculationRules.pm index eb66f5f1a0e..32054ddb3f4 100644 --- a/Koha/CirculationRules.pm +++ b/Koha/CirculationRules.pm @@ -22,6 +22,8 @@ use Carp qw( croak ); use Koha::Exceptions; use Koha::CirculationRule; +use Koha::Caches; +use Koha::Cache::Memory::Lite; use base qw(Koha::Objects); @@ -229,6 +231,28 @@ sub get_effective_rule { return $rule; } +sub get_effective_rule_value { + my ( $self, $params ) = @_; + + my $rule_name = $params->{rule_name}; + my $categorycode = $params->{categorycode}; + my $itemtype = $params->{itemtype}; + my $branchcode = $params->{branchcode}; + + my $memory_cache = Koha::Cache::Memory::Lite->get_instance; + my $cache_key = sprintf "CircRules:%s:%s:%s:%s", $rule_name // q{}, + $categorycode // q{}, $branchcode // q{}, $itemtype // q{}; + + my $cached = $memory_cache->get_from_cache($cache_key); + return $cached if $cached; + + my $rule = $self->get_effective_rule($params); + + my $value= $rule ? $rule->rule_value : undef; + $memory_cache->set_in_cache( $cache_key, $value ); + return $value; +} + =head3 get_effective_rules =cut @@ -243,7 +267,7 @@ sub get_effective_rules { my $r; foreach my $rule (@$rules) { - my $effective_rule = $self->get_effective_rule( + my $effective_rule = $self->get_effective_rule_value( { rule_name => $rule, categorycode => $categorycode, @@ -252,7 +276,7 @@ sub get_effective_rules { } ); - $r->{$rule} = $effective_rule->rule_value if $effective_rule; + $r->{$rule} = $effective_rule if defined $effective_rule; } return $r; @@ -331,6 +355,12 @@ sub set_rule { } } + my $memory_cache = Koha::Cache::Memory::Lite->get_instance; + my $cache_key = sprintf "CircRules:%s:%s:%s:%s", $rule_name // q{}, + $categorycode // q{}, $branchcode // q{}, $itemtype // q{}; + + Koha::Cache::Memory::Lite->flush(); + return $rule; } @@ -359,6 +389,7 @@ sub set_rules { push( @$rule_objects, $rule_object ); } + Koha::Cache::Memory::Lite->flush(); return $rule_objects; } diff --git a/t/db_dependent/Circulation.t b/t/db_dependent/Circulation.t index 2981430bdc4..f2278877187 100755 --- a/t/db_dependent/Circulation.t +++ b/t/db_dependent/Circulation.t @@ -54,6 +54,7 @@ use Koha::Account::Lines; use Koha::Account::Offsets; use Koha::ActionLogs; use Koha::Notice::Messages; +use Koha::Cache::Memory::Lite; sub set_userenv { my ( $library ) = @_; @@ -827,6 +828,7 @@ subtest "CanBookBeRenewed tests" => sub { is( $renewokay, 0, 'Still should not be able to renew' ); is( $error, 'on_reserve', 'returned code is on_reserve, auto_too_soon limit is overridden' ); $dbh->do('UPDATE circulation_rules SET rule_value = 0 where rule_name = "norenewalbefore"'); + Koha::Cache::Memory::Lite->flush(); ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $item_4->itemnumber, 1 ); is( $renewokay, 0, 'Still should not be able to renew' ); is( $error, 'on_reserve', 'returned code is on_reserve, auto_renew only happens if not on reserve' ); @@ -874,6 +876,7 @@ subtest "CanBookBeRenewed tests" => sub { # Change policy so that loans can only be renewed exactly on due date (0 days prior to due date) # and test automatic renewal again $dbh->do(q{UPDATE circulation_rules SET rule_value = '0' WHERE rule_name = 'norenewalbefore'}); + Koha::Cache::Memory::Lite->flush(); ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $item_4->itemnumber ); is( $renewokay, 0, 'Bug 14101: Cannot renew, renewal is automatic and premature' ); @@ -890,6 +893,7 @@ subtest "CanBookBeRenewed tests" => sub { # Change policy so that loans can be renewed 99 days prior to the due date # and test automatic renewal again $dbh->do(q{UPDATE circulation_rules SET rule_value = '99' WHERE rule_name = 'norenewalbefore'}); + Koha::Cache::Memory::Lite->flush(); ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $item_4->itemnumber ); is( $renewokay, 0, 'Bug 14101: Cannot renew, renewal is automatic' ); @@ -1233,6 +1237,7 @@ subtest "CanBookBeRenewed tests" => sub { $dbh->do(q{UPDATE circulation_rules SET rule_value = '10' WHERE rule_name = 'norenewalbefore'}); $dbh->do(q{UPDATE circulation_rules SET rule_value = '15' WHERE rule_name = 'no_auto_renewal_after'}); $dbh->do(q{UPDATE circulation_rules SET rule_value = NULL WHERE rule_name = 'no_auto_renewal_after_hard_limit'}); + Koha::Cache::Memory::Lite->flush(); Koha::CirculationRules->set_rules( { categorycode => undef, -- 2.25.1