From a51ea30d8087b3cdae0aef61bad2fa8175989119 Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Thu, 13 Jul 2017 10:03:54 -0400 Subject: [PATCH] Bug 18936 - Convert issuingrules fields to circulation_rules --- C4/Circulation.pm | 350 +++++++++++--------- C4/Overdues.pm | 37 ++- C4/Reserves.pm | 57 +++- Koha/Biblio.pm | 14 +- Koha/CirculationRules.pm | 45 ++- Koha/IssuingRule.pm | 42 --- Koha/IssuingRules.pm | 86 ----- Koha/Item.pm | 15 +- Koha/Schema/Result/Issuingrule.pm | 307 ----------------- admin/smart-rules.pl | 101 +++--- installer/data/mysql/atomicupdate/bug_18936.perl | 45 +++ .../prog/en/modules/admin/smart-rules.tt | 259 +++++++++------ t/db_dependent/ArticleRequests.t | 48 ++- t/db_dependent/Circulation.t | 366 ++++++++++++++++----- t/db_dependent/Circulation/CalcDateDue.t | 23 +- t/db_dependent/Circulation/CalcFine.t | 34 +- t/db_dependent/Circulation/GetHardDueDate.t | 329 +++++++----------- .../Circulation/IssuingRules/maxsuspensiondays.t | 31 +- t/db_dependent/Circulation/Returns.t | 21 +- t/db_dependent/Circulation/SwitchOnSiteCheckouts.t | 21 +- t/db_dependent/Circulation/TooMany.t | 20 +- t/db_dependent/Circulation/issue.t | 31 +- t/db_dependent/DecreaseLoanHighHolds.t | 18 +- t/db_dependent/Fines.t | 35 +- t/db_dependent/Holds.t | 85 +++-- .../Holds/DisallowHoldIfItemsAvailable.t | 17 +- t/db_dependent/Koha/IssuingRules.t | 88 +++-- t/db_dependent/Koha/Objects.t | 9 +- t/db_dependent/Reserves.t | 42 ++- t/db_dependent/Reserves/MultiplePerRecord.t | 105 +++--- t/db_dependent/TestBuilder.t | 4 +- t/db_dependent/api/v1/holds.t | 17 +- 32 files changed, 1339 insertions(+), 1363 deletions(-) delete mode 100644 Koha/IssuingRule.pm delete mode 100644 Koha/IssuingRules.pm delete mode 100644 Koha/Schema/Result/Issuingrule.pm create mode 100644 installer/data/mysql/atomicupdate/bug_18936.perl diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 61e3685..4e2e565 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -44,7 +44,6 @@ use Koha::AuthorisedValues; use Koha::DateUtils; use Koha::Calendar; use Koha::Checkouts; -use Koha::IssuingRules; use Koha::Items; use Koha::Patrons; use Koha::Patron::Debarments; @@ -431,18 +430,20 @@ sub TooMany { # specific rule if (C4::Context->preference('item-level_itypes')) { $count_query .= " WHERE items.itype NOT IN ( - SELECT itemtype FROM issuingrules + SELECT itemtype FROM circulation_rules WHERE branchcode = ? AND (categorycode = ? OR categorycode = ?) AND itemtype <> '*' + AND rule_name = 'maxissueqty' ) "; } else { $count_query .= " JOIN biblioitems USING (biblionumber) WHERE biblioitems.itemtype NOT IN ( - SELECT itemtype FROM issuingrules + SELECT itemtype FROM circulation_rules WHERE branchcode = ? AND (categorycode = ? OR categorycode = ?) AND itemtype <> '*' + AND rule_name = 'maxissueqty' ) "; } push @bind_params, $maxissueqty_rule->branchcode; @@ -1352,14 +1353,16 @@ sub AddIssue { # If automatic renewal wasn't selected while issuing, set the value according to the issuing rule. unless ($auto_renew) { - my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule( - { categorycode => $borrower->{categorycode}, + my $rule = Koha::CirculationRules->get_effective_rule( + { + categorycode => $borrower->{categorycode}, itemtype => $item->{itype}, - branchcode => $branch + branchcode => $branch, + rule_name => 'auto_renew' } ); - $auto_renew = $issuing_rule->auto_renew if $issuing_rule; + $auto_renew = $rule->rule_value if $rule; } # Record in the database the fact that the book was issued. @@ -1480,67 +1483,77 @@ Get loan length for an itemtype, a borrower type and a branch =cut sub GetLoanLength { - my ( $borrowertype, $itemtype, $branchcode ) = @_; - my $dbh = C4::Context->dbh; - my $sth = $dbh->prepare(qq{ - SELECT issuelength, lengthunit, renewalperiod - FROM issuingrules - WHERE categorycode=? - AND itemtype=? - AND branchcode=? - AND issuelength IS NOT NULL - }); + my ( $categorycode, $itemtype, $branchcode ) = @_; + + # Set search precedences + my @params = ( + { + categorycode => $categorycode, + itemtype => $itemtype, + branchcode => $branchcode, + }, + { + categorycode => $categorycode, + itemtype => '*', + branchcode => $branchcode, + }, + { + categorycode => '*', + itemtype => $itemtype, + branchcode => $branchcode, + }, + { + categorycode => '*', + itemtype => '*', + branchcode => $branchcode, + }, + { + categorycode => $categorycode, + itemtype => $itemtype, + branchcode => '*', + }, + { + categorycode => $categorycode, + itemtype => '*', + branchcode => '*', + }, + { + categorycode => '*', + itemtype => $itemtype, + branchcode => '*', + }, + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + }, + ); - # try to find issuelength & return the 1st available. - # check with borrowertype, itemtype and branchcode, then without one of those parameters - $sth->execute( $borrowertype, $itemtype, $branchcode ); - my $loanlength = $sth->fetchrow_hashref; - - return $loanlength - if defined($loanlength) && defined $loanlength->{issuelength}; - - $sth->execute( $borrowertype, '*', $branchcode ); - $loanlength = $sth->fetchrow_hashref; - return $loanlength - if defined($loanlength) && defined $loanlength->{issuelength}; - - $sth->execute( '*', $itemtype, $branchcode ); - $loanlength = $sth->fetchrow_hashref; - return $loanlength - if defined($loanlength) && defined $loanlength->{issuelength}; - - $sth->execute( '*', '*', $branchcode ); - $loanlength = $sth->fetchrow_hashref; - return $loanlength - if defined($loanlength) && defined $loanlength->{issuelength}; - - $sth->execute( $borrowertype, $itemtype, '*' ); - $loanlength = $sth->fetchrow_hashref; - return $loanlength - if defined($loanlength) && defined $loanlength->{issuelength}; - - $sth->execute( $borrowertype, '*', '*' ); - $loanlength = $sth->fetchrow_hashref; - return $loanlength - if defined($loanlength) && defined $loanlength->{issuelength}; - - $sth->execute( '*', $itemtype, '*' ); - $loanlength = $sth->fetchrow_hashref; - return $loanlength - if defined($loanlength) && defined $loanlength->{issuelength}; - - $sth->execute( '*', '*', '*' ); - $loanlength = $sth->fetchrow_hashref; - return $loanlength - if defined($loanlength) && defined $loanlength->{issuelength}; - - # if no rule is set => 0 day (hardcoded) - return { - issuelength => 0, + # Initialize default values + my $rules = { + issuelength => 0, renewalperiod => 0, - lengthunit => 'days', + lengthunit => 'days', }; + # Search for rules! + foreach my $rule_name (qw( issuelength renewalperiod lengthunit )) { + foreach my $params (@params) { + my $rule = Koha::CirculationRules->search( + { + rule_name => $rule_name, + %$params, + } + )->next(); + + if ($rule) { + $rules->{$rule_name} = $rule->rule_value; + last; + } + } + } + + return $rules; } @@ -1555,19 +1568,21 @@ Get the Hard Due Date and it's comparison for an itemtype, a borrower type and a sub GetHardDueDate { my ( $borrowertype, $itemtype, $branchcode ) = @_; - my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule( - { categorycode => $borrowertype, + my $rules = Koha::CirculationRules->get_effective_rules( + { + categorycode => $borrowertype, itemtype => $itemtype, - branchcode => $branchcode + branchcode => $branchcode, + rules => [ 'hardduedate', 'hardduedatecompare' ], } ); - - if ( defined( $issuing_rule ) ) { - if ( $issuing_rule->hardduedate ) { - return (dt_from_string($issuing_rule->hardduedate, 'iso'),$issuing_rule->hardduedatecompare); - } else { - return (undef, undef); + if ( defined( $rules->{hardduedate} ) ) { + if ( $rules->{hardduedate} ) { + return ( dt_from_string( $rules->{hardduedate}, 'iso' ), $rules->{hardduedatecompare} ); + } + else { + return ( undef, undef ); } } } @@ -2269,14 +2284,20 @@ sub _debar_user_on_return { my $branchcode = _GetCircControlBranch( $item, $borrower ); my $circcontrol = C4::Context->preference('CircControl'); - my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule( + my $issuing_rule = Koha::CirculationRules->get_effective_rules( { categorycode => $borrower->{categorycode}, itemtype => $item->{itype}, - branchcode => $branchcode + branchcode => $branchcode, + rules => [ + 'finedays', + 'lengthunit', + 'firstremind', + 'maxsuspensiondays', + ] } ); - my $finedays = $issuing_rule ? $issuing_rule->finedays : undef; - my $unit = $issuing_rule ? $issuing_rule->lengthunit : undef; + my $finedays = $issuing_rule ? $issuing_rule->{finedays} : undef; + my $unit = $issuing_rule ? $issuing_rule->{lengthunit} : undef; my $chargeable_units = C4::Overdues::get_chargeable_units($unit, $dt_due, $return_date, $branchcode); if ($finedays) { @@ -2287,7 +2308,7 @@ sub _debar_user_on_return { # grace period is measured in the same units as the loan my $grace = - DateTime::Duration->new( $unit => $issuing_rule->firstremind ); + DateTime::Duration->new( $unit => $issuing_rule->{firstremind} ); my $deltadays = DateTime::Duration->new( days => $chargeable_units @@ -2297,7 +2318,7 @@ sub _debar_user_on_return { # If the max suspension days is < than the suspension days # the suspension days is limited to this maximum period. - my $max_sd = $issuing_rule->maxsuspensiondays; + my $max_sd = $issuing_rule->{maxsuspensiondays}; if ( defined $max_sd ) { $max_sd = DateTime::Duration->new( days => $max_sd ); $suspension_days = $max_sd @@ -2729,15 +2750,23 @@ sub CanBookBeRenewed { return ( 1, undef ) if $override_limit; my $branchcode = _GetCircControlBranch( $item, $patron->unblessed ); - my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule( - { categorycode => $patron->categorycode, + my $issuing_rule = Koha::CirculationRules->get_effective_rules( + { + categorycode => $patron->categorycode, itemtype => $item->{itype}, - branchcode => $branchcode + branchcode => $branchcode, + rules => [ + 'renewalsallowed', + 'no_auto_renewal_after', + 'no_auto_renewal_after_hard_limit', + 'lengthunit', + 'norenewalbefore', + ] } ); return ( 0, "too_many" ) - if not $issuing_rule or $issuing_rule->renewalsallowed <= $issue->renewals; + if not $issuing_rule->{renewalsallowed} or $issuing_rule->{renewalsallowed} <= $issue->renewals; my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing'); my $restrictionblockrenewing = C4::Context->preference('RestrictionBlockRenewing'); @@ -2752,23 +2781,23 @@ sub CanBookBeRenewed { } if ( $issue->auto_renew ) { - if ( defined $issuing_rule->no_auto_renewal_after - and $issuing_rule->no_auto_renewal_after ne "" ) { + 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 # If this is greater than today, it's too late for renewal. my $maximum_renewal_date = dt_from_string($issue->issuedate, 'sql'); $maximum_renewal_date->add( - $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after + $issuing_rule->{lengthunit} => $issuing_rule->{no_auto_renewal_after} ); my $now = dt_from_string; if ( $now >= $maximum_renewal_date ) { return ( 0, "auto_too_late" ); } } - if ( defined $issuing_rule->no_auto_renewal_after_hard_limit - and $issuing_rule->no_auto_renewal_after_hard_limit ne "" ) { + if ( defined $issuing_rule->{no_auto_renewal_after_hard_limit} + and $issuing_rule->{no_auto_renewal_after_hard_limit} ne "" ) { # If no_auto_renewal_after_hard_limit is >= today, it's also too late for renewal - if ( dt_from_string >= dt_from_string( $issuing_rule->no_auto_renewal_after_hard_limit ) ) { + if ( dt_from_string >= dt_from_string( $issuing_rule->{no_auto_renewal_after_hard_limit} ) ) { return ( 0, "auto_too_late" ); } } @@ -2782,17 +2811,17 @@ sub CanBookBeRenewed { } } - if ( defined $issuing_rule->norenewalbefore - and $issuing_rule->norenewalbefore ne "" ) + if ( defined $issuing_rule->{norenewalbefore} + and $issuing_rule->{norenewalbefore} ne "" ) { # Calculate soonest renewal by subtracting 'No renewal before' from due date my $soonestrenewal = dt_from_string( $issue->date_due, 'sql' )->subtract( - $issuing_rule->lengthunit => $issuing_rule->norenewalbefore ); + $issuing_rule->{lengthunit} => $issuing_rule->{norenewalbefore} ); # Depending on syspref reset the exact time, only check the date if ( C4::Context->preference('NoRenewalBeforePrecision') eq 'date' - and $issuing_rule->lengthunit eq 'days' ) + and $issuing_rule->{lengthunit} eq 'days' ) { $soonestrenewal->truncate( to => 'day' ); } @@ -2999,14 +3028,16 @@ sub GetRenewCount { # $item and $borrower should be calculated my $branchcode = _GetCircControlBranch($item, $patron->unblessed); - my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule( - { categorycode => $patron->categorycode, + my $rule = Koha::CirculationRules->get_effective_rule( + { + categorycode => $patron->categorycode, itemtype => $item->{itype}, - branchcode => $branchcode + branchcode => $branchcode, + rule_name => 'renewalsallowed', } ); - $renewsallowed = $issuing_rule ? $issuing_rule->renewalsallowed : 0; + $renewsallowed = $rule ? $rule->rule_value : 0; $renewsleft = $renewsallowed - $renewcount; if($renewsleft < 0){ $renewsleft = 0; } return ( $renewcount, $renewsallowed, $renewsleft ); @@ -3044,25 +3075,29 @@ sub GetSoonestRenewDate { or return; my $branchcode = _GetCircControlBranch( $item, $patron->unblessed ); - my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule( + my $issuing_rule = Koha::CirculationRules->get_effective_rules( { categorycode => $patron->categorycode, itemtype => $item->{itype}, - branchcode => $branchcode + branchcode => $branchcode, + rules => [ + 'norenewalbefore', + 'lengthunit', + ] } ); my $now = dt_from_string; return $now unless $issuing_rule; - if ( defined $issuing_rule->norenewalbefore - and $issuing_rule->norenewalbefore ne "" ) + if ( defined $issuing_rule->{norenewalbefore} + and $issuing_rule->{norenewalbefore} ne "" ) { my $soonestrenewal = dt_from_string( $itemissue->date_due )->subtract( - $issuing_rule->lengthunit => $issuing_rule->norenewalbefore ); + $issuing_rule->{lengthunit} => $issuing_rule->{norenewalbefore} ); if ( C4::Context->preference('NoRenewalBeforePrecision') eq 'date' - and $issuing_rule->lengthunit eq 'days' ) + and $issuing_rule->{lengthunit} eq 'days' ) { $soonestrenewal->truncate( to => 'day' ); } @@ -3103,30 +3138,36 @@ sub GetLatestAutoRenewDate { or return; my $branchcode = _GetCircControlBranch( $item, $patron->unblessed ); - my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule( - { categorycode => $patron->categorycode, + my $circulation_rules = Koha::CirculationRules->get_effective_rules( + { + categorycode => $patron->categorycode, itemtype => $item->{itype}, - branchcode => $branchcode + branchcode => $branchcode, + rules => [ + 'no_auto_renewal_after', + 'no_auto_renewal_after_hard_limit', + 'lengthunit', + ] } ); - return unless $issuing_rule; + return unless $circulation_rules; return - if ( not $issuing_rule->no_auto_renewal_after - or $issuing_rule->no_auto_renewal_after eq '' ) - and ( not $issuing_rule->no_auto_renewal_after_hard_limit - or $issuing_rule->no_auto_renewal_after_hard_limit eq '' ); + if ( not $circulation_rules->{no_auto_renewal_after} + or $circulation_rules->{no_auto_renewal_after} eq '' ) + and ( not $circulation_rules->{no_auto_renewal_after_hard_limit} + or $circulation_rules->{no_auto_renewal_after_hard_limit} eq '' ); my $maximum_renewal_date; - if ( $issuing_rule->no_auto_renewal_after ) { + if ( $circulation_rules->{no_auto_renewal_after} ) { $maximum_renewal_date = dt_from_string($itemissue->issuedate); $maximum_renewal_date->add( - $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after + $circulation_rules->{lengthunit} => $circulation_rules->{no_auto_renewal_after} ); } - if ( $issuing_rule->no_auto_renewal_after_hard_limit ) { - my $dt = dt_from_string( $issuing_rule->no_auto_renewal_after_hard_limit ); + if ( $circulation_rules->{no_auto_renewal_after_hard_limit} ) { + my $dt = dt_from_string( $circulation_rules->{no_auto_renewal_after_hard_limit} ); $maximum_renewal_date = $dt if not $maximum_renewal_date or $maximum_renewal_date > $dt; } return $maximum_renewal_date; @@ -3173,19 +3214,10 @@ sub GetIssuingCharges { $item_type = $item_data->{itemtype}; $charge = $item_data->{rentalcharge}; my $branch = C4::Context::mybranch(); - my $discount_query = q|SELECT rentaldiscount, - issuingrules.itemtype, issuingrules.branchcode - FROM borrowers - LEFT JOIN issuingrules ON borrowers.categorycode = issuingrules.categorycode - WHERE borrowers.borrowernumber = ? - AND (issuingrules.itemtype = ? OR issuingrules.itemtype = '*') - AND (issuingrules.branchcode = ? OR issuingrules.branchcode = '*')|; - my $discount_sth = $dbh->prepare($discount_query); - $discount_sth->execute( $borrowernumber, $item_type, $branch ); - my $discount_rules = $discount_sth->fetchall_arrayref({}); - if (@{$discount_rules}) { + my $patron = Koha::Patrons->find( $borrowernumber ); + my $discount = _get_discount_from_rule($patron->categorycode, $branch, $item_type); + if ($discount) { # We may have multiple rules so get the most specific - my $discount = _get_discount_from_rule($discount_rules, $branch, $item_type); $charge = ( $charge * ( 100 - $discount ) ) / 100; } if ($charge) { @@ -3198,37 +3230,43 @@ sub GetIssuingCharges { # Select most appropriate discount rule from those returned sub _get_discount_from_rule { - my ($rules_ref, $branch, $itemtype) = @_; - my $discount; + my ($categorycode, $branchcode, $itemtype) = @_; - if (@{$rules_ref} == 1) { # only 1 applicable rule use it - $discount = $rules_ref->[0]->{rentaldiscount}; - return (defined $discount) ? $discount : 0; - } - # could have up to 4 does one match $branch and $itemtype - my @d = grep { $_->{branchcode} eq $branch && $_->{itemtype} eq $itemtype } @{$rules_ref}; - if (@d) { - $discount = $d[0]->{rentaldiscount}; - return (defined $discount) ? $discount : 0; - } - # do we have item type + all branches - @d = grep { $_->{branchcode} eq q{*} && $_->{itemtype} eq $itemtype } @{$rules_ref}; - if (@d) { - $discount = $d[0]->{rentaldiscount}; - return (defined $discount) ? $discount : 0; - } - # do we all item types + this branch - @d = grep { $_->{branchcode} eq $branch && $_->{itemtype} eq q{*} } @{$rules_ref}; - if (@d) { - $discount = $d[0]->{rentaldiscount}; - return (defined $discount) ? $discount : 0; - } - # so all and all (surely we wont get here) - @d = grep { $_->{branchcode} eq q{*} && $_->{itemtype} eq q{*} } @{$rules_ref}; - if (@d) { - $discount = $d[0]->{rentaldiscount}; - return (defined $discount) ? $discount : 0; + # Set search precedences + my @params = ( + { + branchcode => $branchcode, + itemtype => $itemtype, + categorycode => $categorycode, + }, + { + branchcode => '*', + categorycode => $categorycode, + itemtype => $itemtype, + }, + { + branchcode => $branchcode, + categorycode => $categorycode, + itemtype => '*', + }, + { + branchcode => '*', + categorycode => $categorycode, + itemtype => '*', + }, + ); + + foreach my $params (@params) { + my $rule = Koha::CirculationRules->search( + { + rule_name => 'rentaldiscount', + %$params, + } + )->next(); + + return $rule->rule_value if $rule; } + # none of the above return 0; } diff --git a/C4/Overdues.pm b/C4/Overdues.pm index d22914f..0de4de7 100644 --- a/C4/Overdues.pm +++ b/C4/Overdues.pm @@ -36,7 +36,6 @@ use C4::Debug; use Koha::DateUtils; use Koha::Account::Line; use Koha::Account::Lines; -use Koha::IssuingRules; use Koha::Libraries; use vars qw(@ISA @EXPORT); @@ -248,28 +247,44 @@ sub CalcFine { my $start_date = $due_dt->clone(); # get issuingrules (fines part will be used) my $itemtype = $item->{itemtype} || $item->{itype}; - my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule({ categorycode => $bortype, itemtype => $itemtype, branchcode => $branchcode }); + my $issuing_rule = Koha::CirculationRules->get_effective_rules( + { + categorycode => $bortype, + itemtype => $itemtype, + branchcode => $branchcode, + rules => [ + 'lengthunit', + 'firstremind', + 'chargeperiod', + 'chargeperiod_charge_at', + 'fine', + 'overduefinescap', + 'cap_fine_to_replacement_price', + 'chargename', + ] + } + ); return unless $issuing_rule; # If not rule exist, there is no fine - my $fine_unit = $issuing_rule->lengthunit || 'days'; + my $fine_unit = $issuing_rule->{lengthunit} || 'days'; my $chargeable_units = get_chargeable_units($fine_unit, $start_date, $end_date, $branchcode); - my $units_minus_grace = $chargeable_units - $issuing_rule->firstremind; + my $units_minus_grace = $chargeable_units - $issuing_rule->{firstremind}; my $amount = 0; - if ( $issuing_rule->chargeperiod && ( $units_minus_grace > 0 ) ) { + if ( $issuing_rule->{chargeperiod} && ( $units_minus_grace > 0 ) ) { my $units = C4::Context->preference('FinesIncludeGracePeriod') ? $chargeable_units : $units_minus_grace; - my $charge_periods = $units / $issuing_rule->chargeperiod; + my $charge_periods = $units / $issuing_rule->{chargeperiod}; # If chargeperiod_charge_at = 1, we charge a fine at the start of each charge period # if chargeperiod_charge_at = 0, we charge at the end of each charge period - $charge_periods = $issuing_rule->chargeperiod_charge_at == 1 ? ceil($charge_periods) : floor($charge_periods); - $amount = $charge_periods * $issuing_rule->fine; + $charge_periods = $issuing_rule->{chargeperiod_charge_at} == 1 ? ceil($charge_periods) : floor($charge_periods); + $amount = $charge_periods * $issuing_rule->{fine}; } # else { # a zero (or null) chargeperiod or negative units_minus_grace value means no charge. } - $amount = $issuing_rule->overduefinescap if $issuing_rule->overduefinescap && $amount > $issuing_rule->overduefinescap; - $amount = $item->{replacementprice} if ( $issuing_rule->cap_fine_to_replacement_price && $item->{replacementprice} && $amount > $item->{replacementprice} ); + $amount = $issuing_rule->{overduefinescap} if $issuing_rule->{overduefinescap} && $amount > $issuing_rule->{overduefinescap}; + $amount = $item->{replacementprice} if ( $issuing_rule->{cap_fine_to_replacement_price} && $item->{replacementprice} && $amount > $item->{replacementprice} ); $debug and warn sprintf("CalcFine returning (%s, %s, %s, %s)", $amount, $issuing_rule->chargename, $units_minus_grace, $chargeable_units); - return ($amount, $issuing_rule->chargename, $units_minus_grace, $chargeable_units); + return ($amount, $issuing_rule->{chargename}, $units_minus_grace, $chargeable_units); # FIXME: chargename is NEVER populated anywhere. } diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 1d80b80..c05fa3b 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -44,7 +44,6 @@ use Koha::Hold; use Koha::Old::Hold; use Koha::Holds; use Koha::Libraries; -use Koha::IssuingRules; use Koha::Items; use Koha::ItemTypes; use Koha::Patrons; @@ -1428,10 +1427,17 @@ sub _get_itype { } sub _OnShelfHoldsAllowed { - my ($itype,$borrowercategory,$branchcode) = @_; + my ( $itype, $borrowercategory, $branchcode ) = @_; - my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule({ categorycode => $borrowercategory, itemtype => $itype, branchcode => $branchcode }); - return $issuing_rule ? $issuing_rule->onshelfholds : undef; + my $rule = Koha::CirculationRules->get_effective_rule( + { + categorycode => $borrowercategory, + itemtype => $itype, + branchcode => $branchcode, + rule_name => 'onshelfholds', + } + ); + return $rule ? $rule->rule_value : undef; } =head2 AlterPriority @@ -2369,24 +2375,39 @@ patron category, itemtype, and library. sub GetHoldRule { my ( $categorycode, $itemtype, $branchcode ) = @_; - my $dbh = C4::Context->dbh; - - my $sth = $dbh->prepare( - q{ - SELECT categorycode, itemtype, branchcode, reservesallowed, holds_per_record - FROM issuingrules - WHERE (categorycode in (?,'*') ) - AND (itemtype IN (?,'*')) - AND (branchcode IN (?,'*')) - ORDER BY categorycode DESC, - itemtype DESC, - branchcode DESC + my $reservesallowed = Koha::CirculationRules->get_effective_rule( + { + itemtype => $itemtype, + categorycode => $categorycode, + branchcode => $branchcode, + rule_name => 'reservesallowed', + order_by => { + -desc => [ 'categorycode', 'itemtype', 'branchcode' ] + } } ); + return unless $reservesallowed;; - $sth->execute( $categorycode, $itemtype, $branchcode ); + my $rules; + $rules->{reservesallowed} = $reservesallowed->rule_value; + $rules->{itemtype} = $reservesallowed->itemtype; + $rules->{categorycode} = $reservesallowed->categorycode; + $rules->{branchcode} = $reservesallowed->branchcode; - return $sth->fetchrow_hashref(); + my $holds_per_record = Koha::CirculationRules->get_effective_rule( + { + itemtype => $itemtype, + categorycode => $categorycode, + branchcode => $branchcode, + rule_name => 'holds_per_record', + order_by => { + -desc => [ 'categorycode', 'itemtype', 'branchcode' ] + } + } + ); + $rules->{holds_per_record} = $holds_per_record->rule_value if $holds_per_record; + + return $rules; } =head1 AUTHOR diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm index aad4343..cf6a573 100644 --- a/Koha/Biblio.pm +++ b/Koha/Biblio.pm @@ -32,7 +32,7 @@ use Koha::Items; use Koha::Biblioitems; use Koha::ArticleRequests; use Koha::ArticleRequest::Status; -use Koha::IssuingRules; +use Koha::CirculationRules; use Koha::Subscriptions; =head1 NAME @@ -123,10 +123,16 @@ sub article_request_type_for_bib { my $borrowertype = $borrower->categorycode; my $itemtype = $self->itemtype(); - my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule({ categorycode => $borrowertype, itemtype => $itemtype }); + my $rule = Koha::CirculationRules->get_effective_rule( + { + rule_name => 'article_requests', + categorycode => $borrowertype, + itemtype => $itemtype, + } + ); - return q{} unless $issuing_rule; - return $issuing_rule->article_requests || q{} + return q{} unless $rule; + return $rule->rule_value || q{} } =head3 article_request_type_for_items diff --git a/Koha/CirculationRules.pm b/Koha/CirculationRules.pm index cf00eb4..1e3b6cc 100644 --- a/Koha/CirculationRules.pm +++ b/Koha/CirculationRules.pm @@ -1,7 +1,6 @@ package Koha::CirculationRules; -# Copyright Vaara-kirjastot 2015 -# Copyright Koha Development Team 2016 +# Copyright ByWater Solutions 2017 # # This file is part of Koha. # @@ -28,7 +27,7 @@ use base qw(Koha::Objects); =head1 NAME -Koha::IssuingRules - Koha IssuingRule Object set class +Koha::CirculationRules - Koha CirculationRule Object set class =head1 API @@ -43,11 +42,18 @@ Koha::IssuingRules - Koha IssuingRule Object set class sub get_effective_rule { my ( $self, $params ) = @_; + $params->{categorycode} = '*' if exists($params->{categorycode}) && !defined($params->{categorycode}); + $params->{branchcode} = '*' if exists($params->{branchcode}) && !defined($params->{branchcode}); + $params->{itemtype} = '*' if exists($params->{itemtype}) && !defined($params->{itemtype}); + my $rule_name = $params->{rule_name}; my $categorycode = $params->{categorycode}; my $itemtype = $params->{itemtype}; my $branchcode = $params->{branchcode}; + my $order_by = $params->{order_by} + // { -desc => [ 'branchcode', 'categorycode', 'itemtype' ] }; + croak q{No rule name passed in!} unless $rule_name; my $search_params; @@ -60,9 +66,7 @@ sub get_effective_rule { my $rule = $self->search( $search_params, { - order_by => { - -desc => [ 'branchcode', 'categorycode', 'itemtype' ] - }, + order_by => $order_by, rows => 1, } )->single; @@ -70,6 +74,35 @@ sub get_effective_rule { return $rule; } +=head3 get_effective_rule + +=cut + +sub get_effective_rules { + my ( $self, $params ) = @_; + + my $rules = $params->{rules}; + my $categorycode = $params->{categorycode}; + my $itemtype = $params->{itemtype}; + my $branchcode = $params->{branchcode}; + + my $r; + foreach my $rule (@$rules) { + my $effective_rule = $self->get_effective_rule( + { + rule_name => $rule, + categorycode => $categorycode, + itemtype => $itemtype, + branchcode => $branchcode, + } + ); + + $r->{$rule} = $effective_rule->rule_value if $effective_rule; + } + + return $r; +} + =head3 set_rule =cut diff --git a/Koha/IssuingRule.pm b/Koha/IssuingRule.pm deleted file mode 100644 index 9d81db8..0000000 --- a/Koha/IssuingRule.pm +++ /dev/null @@ -1,42 +0,0 @@ -package Koha::IssuingRule; - -# Copyright Vaara-kirjastot 2015 -# -# This file is part of Koha. -# -# Koha is free software; you can redistribute it and/or modify it under the -# terms of the GNU General Public License as published by the Free Software -# Foundation; either version 3 of the License, or (at your option) any later -# version. -# -# Koha is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -# A PARTICULAR PURPOSE. See the GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with Koha; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -use Modern::Perl; -use Koha::Database; -use base qw(Koha::Object); - -=head1 NAME - -Koha::Hold - Koha Hold object class - -=head1 API - -=head2 Class Methods - -=cut - -=head3 type - -=cut - -sub _type { - return 'Issuingrule'; -} - -1; \ No newline at end of file diff --git a/Koha/IssuingRules.pm b/Koha/IssuingRules.pm deleted file mode 100644 index e3664df..0000000 --- a/Koha/IssuingRules.pm +++ /dev/null @@ -1,86 +0,0 @@ -package Koha::IssuingRules; - -# Copyright Vaara-kirjastot 2015 -# Copyright Koha Development Team 2016 -# -# This file is part of Koha. -# -# Koha is free software; you can redistribute it and/or modify it under the -# terms of the GNU General Public License as published by the Free Software -# Foundation; either version 3 of the License, or (at your option) any later -# version. -# -# Koha is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -# A PARTICULAR PURPOSE. See the GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with Koha; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -use Modern::Perl; - -use Koha::Database; - -use Koha::IssuingRule; - -use base qw(Koha::Objects); - -=head1 NAME - -Koha::IssuingRules - Koha IssuingRule Object set class - -=head1 API - -=head2 Class Methods - -=cut - -sub get_effective_issuing_rule { - my ( $self, $params ) = @_; - - my $default = '*'; - my $categorycode = $params->{categorycode}; - my $itemtype = $params->{itemtype}; - my $branchcode = $params->{branchcode}; - - my $search_categorycode = $default; - my $search_itemtype = $default; - my $search_branchcode = $default; - - if ($categorycode) { - $search_categorycode = { 'in' => [ $categorycode, $default ] }; - } - if ($itemtype) { - $search_itemtype = { 'in' => [ $itemtype, $default ] }; - } - if ($branchcode) { - $search_branchcode = { 'in' => [ $branchcode, $default ] }; - } - - my $rule = $self->search({ - categorycode => $search_categorycode, - itemtype => $search_itemtype, - branchcode => $search_branchcode, - }, { - order_by => { - -desc => ['branchcode', 'categorycode', 'itemtype'] - }, - rows => 1, - })->single; - return $rule; -} - -=head3 type - -=cut - -sub _type { - return 'Issuingrule'; -} - -sub object_class { - return 'Koha::IssuingRule'; -} - -1; diff --git a/Koha/Item.pm b/Koha/Item.pm index bea05f8..84d8ddb 100644 --- a/Koha/Item.pm +++ b/Koha/Item.pm @@ -26,7 +26,7 @@ use Koha::DateUtils qw( dt_from_string ); use C4::Context; use Koha::Checkouts; -use Koha::IssuingRules; +use Koha::CirculationRules; use Koha::Item::Transfer; use Koha::Patrons; use Koha::Libraries; @@ -209,10 +209,17 @@ sub article_request_type { : undef; my $borrowertype = $borrower->categorycode; my $itemtype = $self->effective_itemtype(); - my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule({ categorycode => $borrowertype, itemtype => $itemtype, branchcode => $branchcode }); + my $rule = Koha::CirculationRules->get_effective_rule( + { + rule_name => 'article_requests', + categorycode => $borrowertype, + itemtype => $itemtype, + branchcode => $branchcode + } + ); - return q{} unless $issuing_rule; - return $issuing_rule->article_requests || q{} + return q{} unless $rule; + return $rule->rule_value || q{} } =head3 current_holds diff --git a/Koha/Schema/Result/Issuingrule.pm b/Koha/Schema/Result/Issuingrule.pm deleted file mode 100644 index b1abf36..0000000 --- a/Koha/Schema/Result/Issuingrule.pm +++ /dev/null @@ -1,307 +0,0 @@ -use utf8; -package Koha::Schema::Result::Issuingrule; - -# Created by DBIx::Class::Schema::Loader -# DO NOT MODIFY THE FIRST PART OF THIS FILE - -=head1 NAME - -Koha::Schema::Result::Issuingrule - -=cut - -use strict; -use warnings; - -use base 'DBIx::Class::Core'; - -=head1 TABLE: C - -=cut - -__PACKAGE__->table("issuingrules"); - -=head1 ACCESSORS - -=head2 categorycode - - data_type: 'varchar' - default_value: (empty string) - is_nullable: 0 - size: 10 - -=head2 itemtype - - data_type: 'varchar' - default_value: (empty string) - is_nullable: 0 - size: 10 - -=head2 restrictedtype - - data_type: 'tinyint' - is_nullable: 1 - -=head2 rentaldiscount - - data_type: 'decimal' - is_nullable: 1 - size: [28,6] - -=head2 reservecharge - - data_type: 'decimal' - is_nullable: 1 - size: [28,6] - -=head2 fine - - data_type: 'decimal' - is_nullable: 1 - size: [28,6] - -=head2 finedays - - data_type: 'integer' - is_nullable: 1 - -=head2 maxsuspensiondays - - data_type: 'integer' - is_nullable: 1 - -=head2 firstremind - - data_type: 'integer' - is_nullable: 1 - -=head2 chargeperiod - - data_type: 'integer' - is_nullable: 1 - -=head2 chargeperiod_charge_at - - data_type: 'tinyint' - default_value: 0 - is_nullable: 0 - -=head2 accountsent - - data_type: 'integer' - is_nullable: 1 - -=head2 chargename - - data_type: 'varchar' - is_nullable: 1 - size: 100 - -=head2 issuelength - - data_type: 'integer' - is_nullable: 1 - -=head2 lengthunit - - data_type: 'varchar' - default_value: 'days' - is_nullable: 1 - size: 10 - -=head2 hardduedate - - data_type: 'date' - datetime_undef_if_invalid: 1 - is_nullable: 1 - -=head2 hardduedatecompare - - data_type: 'tinyint' - default_value: 0 - is_nullable: 0 - -=head2 renewalsallowed - - data_type: 'smallint' - default_value: 0 - is_nullable: 0 - -=head2 renewalperiod - - data_type: 'integer' - is_nullable: 1 - -=head2 norenewalbefore - - data_type: 'integer' - is_nullable: 1 - -=head2 auto_renew - - data_type: 'tinyint' - default_value: 0 - is_nullable: 1 - -=head2 no_auto_renewal_after - - data_type: 'integer' - is_nullable: 1 - -=head2 no_auto_renewal_after_hard_limit - - data_type: 'date' - datetime_undef_if_invalid: 1 - is_nullable: 1 - -=head2 reservesallowed - - data_type: 'smallint' - default_value: 0 - is_nullable: 0 - -=head2 holds_per_record - - data_type: 'smallint' - default_value: 1 - is_nullable: 0 - -=head2 branchcode - - data_type: 'varchar' - default_value: (empty string) - is_nullable: 0 - size: 10 - -=head2 overduefinescap - - data_type: 'decimal' - is_nullable: 1 - size: [28,6] - -=head2 cap_fine_to_replacement_price - - data_type: 'tinyint' - default_value: 0 - is_nullable: 0 - -=head2 onshelfholds - - data_type: 'tinyint' - default_value: 0 - is_nullable: 0 - -=head2 opacitemholds - - data_type: 'char' - default_value: 'N' - is_nullable: 0 - size: 1 - -=head2 article_requests - - data_type: 'enum' - default_value: 'no' - extra: {list => ["no","yes","bib_only","item_only"]} - is_nullable: 0 - -=cut - -__PACKAGE__->add_columns( - "categorycode", - { data_type => "varchar", default_value => "", is_nullable => 0, size => 10 }, - "itemtype", - { data_type => "varchar", default_value => "", is_nullable => 0, size => 10 }, - "restrictedtype", - { data_type => "tinyint", is_nullable => 1 }, - "rentaldiscount", - { data_type => "decimal", is_nullable => 1, size => [28, 6] }, - "reservecharge", - { data_type => "decimal", is_nullable => 1, size => [28, 6] }, - "fine", - { data_type => "decimal", is_nullable => 1, size => [28, 6] }, - "finedays", - { data_type => "integer", is_nullable => 1 }, - "maxsuspensiondays", - { data_type => "integer", is_nullable => 1 }, - "firstremind", - { data_type => "integer", is_nullable => 1 }, - "chargeperiod", - { data_type => "integer", is_nullable => 1 }, - "chargeperiod_charge_at", - { data_type => "tinyint", default_value => 0, is_nullable => 0 }, - "accountsent", - { data_type => "integer", is_nullable => 1 }, - "chargename", - { data_type => "varchar", is_nullable => 1, size => 100 }, - "issuelength", - { data_type => "integer", is_nullable => 1 }, - "lengthunit", - { - data_type => "varchar", - default_value => "days", - is_nullable => 1, - size => 10, - }, - "hardduedate", - { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 }, - "hardduedatecompare", - { data_type => "tinyint", default_value => 0, is_nullable => 0 }, - "renewalsallowed", - { data_type => "smallint", default_value => 0, is_nullable => 0 }, - "renewalperiod", - { data_type => "integer", is_nullable => 1 }, - "norenewalbefore", - { data_type => "integer", is_nullable => 1 }, - "auto_renew", - { data_type => "tinyint", default_value => 0, is_nullable => 1 }, - "no_auto_renewal_after", - { data_type => "integer", is_nullable => 1 }, - "no_auto_renewal_after_hard_limit", - { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 }, - "reservesallowed", - { data_type => "smallint", default_value => 0, is_nullable => 0 }, - "holds_per_record", - { data_type => "smallint", default_value => 1, is_nullable => 0 }, - "branchcode", - { data_type => "varchar", default_value => "", is_nullable => 0, size => 10 }, - "overduefinescap", - { data_type => "decimal", is_nullable => 1, size => [28, 6] }, - "cap_fine_to_replacement_price", - { data_type => "tinyint", default_value => 0, is_nullable => 0 }, - "onshelfholds", - { data_type => "tinyint", default_value => 0, is_nullable => 0 }, - "opacitemholds", - { data_type => "char", default_value => "N", is_nullable => 0, size => 1 }, - "article_requests", - { - data_type => "enum", - default_value => "no", - extra => { list => ["no", "yes", "bib_only", "item_only"] }, - is_nullable => 0, - }, -); - -=head1 PRIMARY KEY - -=over 4 - -=item * L - -=item * L - -=item * L - -=back - -=cut - -__PACKAGE__->set_primary_key("branchcode", "categorycode", "itemtype"); - - -# Created by DBIx::Class::Schema::Loader v0.07042 @ 2017-07-03 15:35:15 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:dxv4gdxTEP+dd6MY0Y/lcw - - -# You can replace this text with custom code or comments, and it will be preserved on regeneration -1; diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl index 16e99f4..cb42c0c 100755 --- a/admin/smart-rules.pl +++ b/admin/smart-rules.pl @@ -27,8 +27,6 @@ use C4::Koha; use C4::Debug; use Koha::DateUtils; use Koha::Database; -use Koha::IssuingRule; -use Koha::IssuingRules; use Koha::Logger; use Koha::RefundLostItemFeeRules; use Koha::Libraries; @@ -70,8 +68,41 @@ if ($op eq 'delete') { my $categorycode = $input->param('categorycode'); $debug and warn "deleting $1 $2 $branch"; - my $sth_Idelete = $dbh->prepare("delete from issuingrules where branchcode=? and categorycode=? and itemtype=?"); - $sth_Idelete->execute($branch, $categorycode, $itemtype); + Koha::CirculationRules->set_rules( + { + categorycode => $categorycode, + branchcode => $branch, + itemtype => $itemtype, + rules => { + restrictedtype => undef, + rentaldiscount => undef, + fine => undef, + finedays => undef, + maxsuspensiondays => undef, + firstremind => undef, + chargeperiod => undef, + chargeperiod_charge_at => undef, + accountsent => undef, + issuelength => undef, + lengthunit => undef, + hardduedate => undef, + hardduedatecompare => undef, + renewalsallowed => undef, + renewalperiod => undef, + norenewalbefore => undef, + auto_renew => undef, + no_auto_renewal_after => undef, + no_auto_renewal_after_hard_limit => undef, + reservesallowed => undef, + holds_per_record => undef, + overduefinescap => undef, + cap_fine_to_replacement_price => undef, + onshelfholds => undef, + opacitemholds => undef, + article_requests => undef, + } + } + ); } elsif ($op eq 'delete-branch-cat') { my $categorycode = $input->param('categorycode'); @@ -272,13 +303,6 @@ elsif ($op eq 'add') { article_requests => $article_requests, }; - my $issuingrule = Koha::IssuingRules->find({categorycode => $bor, itemtype => $itemtype, branchcode => $br}); - if ($issuingrule) { - $issuingrule->set($params)->store(); - } else { - Koha::IssuingRule->new()->set($params)->store(); - } - Koha::CirculationRules->set_rules( { categorycode => $bor, @@ -287,6 +311,7 @@ elsif ($op eq 'add') { rules => { maxissueqty => $maxissueqty, maxonsiteissueqty => $maxonsiteissueqty, + %$params, } } ); @@ -511,62 +536,16 @@ $template->param( my $patron_categories = Koha::Patron::Categories->search({}, { order_by => ['description'] }); -my @row_loop; my $itemtypes = Koha::ItemTypes->search_with_localization; -my $sth2 = $dbh->prepare(" - SELECT issuingrules.*, - itemtypes.description AS humanitemtype, - categories.description AS humancategorycode, - COALESCE( localization.translation, itemtypes.description ) AS translated_description - FROM issuingrules - LEFT JOIN itemtypes - ON (itemtypes.itemtype = issuingrules.itemtype) - LEFT JOIN categories - ON (categories.categorycode = issuingrules.categorycode) - LEFT JOIN localization ON issuingrules.itemtype = localization.code - AND localization.entity = 'itemtypes' - AND localization.lang = ? - WHERE issuingrules.branchcode = ? -"); -$sth2->execute($language, $branch); - -while (my $row = $sth2->fetchrow_hashref) { - $row->{'current_branch'} ||= $row->{'branchcode'}; - $row->{humanitemtype} ||= $row->{itemtype}; - $row->{default_translated_description} = 1 if $row->{humanitemtype} eq '*'; - $row->{'humancategorycode'} ||= $row->{'categorycode'}; - $row->{'default_humancategorycode'} = 1 if $row->{'humancategorycode'} eq '*'; - $row->{'fine'} = sprintf('%.2f', $row->{'fine'}); - if ($row->{'hardduedate'} && $row->{'hardduedate'} ne '0000-00-00') { - my $harddue_dt = eval { dt_from_string( $row->{'hardduedate'} ) }; - $row->{'hardduedate'} = eval { output_pref( { dt => $harddue_dt, dateonly => 1 } ) } if ( $harddue_dt ); - $row->{'hardduedatebefore'} = 1 if ($row->{'hardduedatecompare'} == -1); - $row->{'hardduedateexact'} = 1 if ($row->{'hardduedatecompare'} == 0); - $row->{'hardduedateafter'} = 1 if ($row->{'hardduedatecompare'} == 1); - } else { - $row->{'hardduedate'} = 0; - } - if ($row->{no_auto_renewal_after_hard_limit}) { - my $dt = eval { dt_from_string( $row->{no_auto_renewal_after_hard_limit} ) }; - $row->{no_auto_renewal_after_hard_limit} = eval { output_pref( { dt => $dt, dateonly => 1 } ) } if $dt; - } - - push @row_loop, $row; -} - -my @sorted_row_loop = sort by_category_and_itemtype @row_loop; - $template->param(show_branch_cat_rule_form => 1); $template->param( patron_categories => $patron_categories, - itemtypeloop => $itemtypes, - rules => \@sorted_row_loop, - humanbranch => ($branch ne '*' ? $branch : ''), - current_branch => $branch, - definedbranch => scalar(@sorted_row_loop)>0 - ); + itemtypeloop => $itemtypes, + humanbranch => ( $branch ne '*' ? $branch : '' ), + current_branch => $branch, +); output_html_with_http_headers $input, $cookie, $template->output; exit 0; diff --git a/installer/data/mysql/atomicupdate/bug_18936.perl b/installer/data/mysql/atomicupdate/bug_18936.perl new file mode 100644 index 0000000..61b5fb9 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_18936.perl @@ -0,0 +1,45 @@ +$DBversion = 'XXX'; # will be replaced by the RM +if( CheckVersion( $DBversion ) ) { + my @columns = qw( + restrictedtype + rentaldiscount + fine + finedays + maxsuspensiondays + firstremind + chargeperiod + chargeperiod_charge_at + accountsent + issuelength + lengthunit + hardduedate + hardduedatecompare + renewalsallowed + renewalperiod + norenewalbefore + auto_renew + no_auto_renewal_after + no_auto_renewal_after_hard_limit + reservesallowed + holds_per_record + overduefinescap + cap_fine_to_replacement_price + onshelfholds + opacitemholds + article_requests + ); + + if ( column_exists( 'issuingrules', 'categorycode' ) ) { + foreach my $column ( @columns ) { + $dbh->do(" + INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value ) + SELECT categorycode, branchcode, itemtype, 'column', $column + FROM issuingrules + "); + } + $dbh->do("DROP TABLE issuingrules"); + } + + SetVersion( $DBversion ); + print "Upgrade to $DBversion done (Bug 18930 - Move lost item refund rules to circulation_rules table)\n"; +} 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 90f164f..fd39417 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 @@ -1,13 +1,22 @@ +[% USE KohaDates %] [% USE Branches %] [% USE Categories %] +[% USE ItemTypes %] [% USE CirculationRules %] -[% SET branchcode = humanbranch %] +[% SET branchcode = humanbranch || '*' %] -[% SET categorycodes = ['*'] %] +[% SET categorycodes = [] %] [% FOREACH pc IN patron_categories %] [% categorycodes.push( pc.id ) %] [% END %] +[% categorycodes.push('*') %] + +[% SET itemtypes = [] %] +[% FOREACH i IN itemtypeloop %] + [% itemtypes.push( i.itemtype ) %] +[% END %] +[% itemtypes.push('*') %] [% INCLUDE 'doc-head-open.inc' %] Koha › Administration › Circulation and fine rules @@ -207,110 +216,148 @@ $(document).ready(function() { - [% FOREACH rule IN rules %] - - [% IF ( rule.default_humancategorycode ) %] - All - [% ELSE %] - [% rule.humancategorycode %] - [% END %] - - [% IF rule.default_translated_description %] - All - [% ELSE %] - [% rule.translated_description %] - [% END %] - - - [% SET rule_value = CirculationRules.Get( rule.branchcode, rule.categorycode, rule.itemtype, 'maxissueqty' ) %] - [% IF rule_value %] - [% rule_value %] - [% ELSE %] - Unlimited - [% END %] - - - [% SET rule_value = CirculationRules.Get( rule.branchcode, rule.categorycode, rule.itemtype, 'maxonsiteissueqty' ) %] - [% IF rule_value %] - [% rule_value %] - [% ELSE %] - Unlimited - [% END %] - - [% rule.issuelength %] - - [% rule.lengthunit %] - - - [% IF ( rule.hardduedate ) %] - [% IF ( rule.hardduedatebefore ) %] - before [% rule.hardduedate %] - - [% ELSIF ( rule.hardduedateexact ) %] - on [% rule.hardduedate %] - - [% ELSIF ( rule.hardduedateafter ) %] - after [% rule.hardduedate %] - - [% END %] - [% ELSE %] - None defined - [% END %] - - [% rule.fine %] - [% rule.chargeperiod %] - [% IF rule.chargeperiod_charge_at %]Start of interval[% ELSE %]End of interval[% END %] - [% rule.firstremind %] - [% rule.overduefinescap FILTER format("%.2f") %] - - [% IF rule.cap_fine_to_replacement_price %] - - [% ELSE %] - - [% END %] - - [% rule.finedays %] - [% rule.maxsuspensiondays %] - [% rule.renewalsallowed %] - [% rule.renewalperiod %] - [% rule.norenewalbefore %] - - [% IF ( rule.auto_renew ) %] - Yes - [% ELSE %] - No - [% END %] - - [% rule.no_auto_renewal_after %] - [% rule.no_auto_renewal_after_hard_limit %] - [% rule.reservesallowed %] - [% rule.holds_per_record %] - - [% IF rule.onshelfholds == 1 %] - Yes - [% ELSIF rule.onshelfholds == 2 %] - If all unavailable - [% ELSE %] - If any unavailable - [% END %] - [% IF rule.opacitemholds == 'F'%]Force[% ELSIF rule.opacitemholds == 'Y'%]Allow[% ELSE %]Don't allow[% END %] - - [% IF rule.article_requests == 'no' %] - No - [% ELSIF rule.article_requests == 'yes' %] - Yes - [% ELSIF rule.article_requests == 'bib_only' %] - Record only - [% ELSIF rule.article_requests == 'item_only' %] - Item only - [% END %] - - [% rule.rentaldiscount %] - - Edit - Delete - - + [% SET row_count = 0 %] + [% FOREACH c IN categorycodes %] + [% FOREACH i IN itemtypes %] + [% SET maxissueqty = CirculationRules.Get( branchcode, c, i, 'maxissueqty' ) %] + [% SET maxonsiteissueqty = CirculationRules.Get( branchcode, c, i, 'maxonsiteissueqty' ) %] + [% SET issuelength = CirculationRules.Get( branchcode, c, i, 'issuelength' ) %] + [% SET lengthunit = CirculationRules.Get( branchcode, c, i, 'lengthunit' ) %] + [% SET hardduedate = CirculationRules.Get( branchcode, c, i, 'hardduedate' ) %] + [% SET hardduedatecompare = CirculationRules.Get( branchcode, c, i, 'hardduedatecompare' ) %] + [% SET fine = CirculationRules.Get( branchcode, c, i, 'fine' ) %] + [% SET chargeperiod = CirculationRules.Get( branchcode, c, i, 'chargeperiod' ) %] + [% SET chargeperiod_charge_at = CirculationRules.Get( branchcode, c, i, 'chargeperiod_charge_at' ) %] + [% SET firstremind = CirculationRules.Get( branchcode, c, i, 'firstremind' ) %] + [% SET overduefinescap = CirculationRules.Get( branchcode, c, i, 'overduefinescap' ) %] + [% SET cap_fine_to_replacement_price = CirculationRules.Get( branchcode, c, i, 'cap_fine_to_replacement_price' ) %] + [% SET finedays = CirculationRules.Get( branchcode, c, i, 'finedays' ) %] + [% SET maxsuspensiondays = CirculationRules.Get( branchcode, c, i, 'maxsuspensiondays' ) %] + [% SET renewalsallowed = CirculationRules.Get( branchcode, c, i, 'renewalsallowed' ) %] + [% SET renewalperiod = CirculationRules.Get( branchcode, c, i, 'renewalperiod' ) %] + [% SET norenewalbefore = CirculationRules.Get( branchcode, c, i, 'norenewalbefore' ) %] + [% SET auto_renew = CirculationRules.Get( branchcode, c, i, 'auto_renew' ) %] + [% SET no_auto_renewal_after = CirculationRules.Get( branchcode, c, i, 'no_auto_renewal_after' ) %] + [% SET no_auto_renewal_after_hard_limit = CirculationRules.Get( branchcode, c, i, 'no_auto_renewal_after_hard_limit' ) %] + [% SET reservesallowed = CirculationRules.Get( branchcode, c, i, 'reservesallowed' ) %] + [% SET holds_per_record = CirculationRules.Get( branchcode, c, i, 'holds_per_record' ) %] + [% SET onshelfholds = CirculationRules.Get( branchcode, c, i, 'onshelfholds' ) %] + [% SET opacitemholds = CirculationRules.Get( branchcode, c, i, 'opacitemholds' ) %] + [% SET article_requests = CirculationRules.Get( branchcode, c, i, 'article_requests' ) %] + [% SET rentaldiscount = CirculationRules.Get( branchcode, c, i, 'rentaldiscount' ) %] + + [% SET show_rule = maxissueqty || maxonsiteissueqty || issuelength || lengthunit || hardduedate || hardduedatebefore || hardduedateexact || fine || chargeperiod + || chargeperiod_charge_at || firstremind || overduefinescap || cap_fine_to_replacement_price || finedays || maxsuspensiondays || renewalsallowed + || renewalsallowed || norenewalbefore || auto_renew || no_auto_renewal_after || no_auto_renewal_after_hard_limit || reservesallowed + || holds_per_record || onshelfholds || opacitemholds || article_requests || article_requests %] + [% IF show_rule %] + [% SET row_count = row_count + 1 %] + + + [% IF c == '*' %] + All + [% ELSE %] + [% Categories.GetName(c) %] + [% END %] + + + [% IF i == '*' %] + All + [% ELSE %] + [% ItemTypes.GetDescription(i) %] + [% END %] + + + [% IF maxissueqty %] + [% maxissueqty %] + [% ELSE %] + Unlimited + [% END %] + + + [% IF maxonsiteissueqty %] + [% maxonsiteissueqty %] + [% ELSE %] + Unlimited + [% END %] + + [% issuelength %] + + [% lengthunit %] + + + [% IF ( hardduedate ) %] + [% IF ( hardduedatecompare == '-1' ) %] + before [% hardduedate | $KohaDates %] + + [% ELSIF ( hardduedatecompare == '0' ) %] + on [% hardduedate | $KohaDates %] + + [% ELSIF ( hardduedatecompare == '1' ) %] + after [% hardduedate | $KohaDates %] + + [% END %] + [% ELSE %] + None defined + [% END %] + + [% fine %] + [% chargeperiod %] + [% IF chargeperiod_charge_at %]Start of interval[% ELSE %]End of interval[% END %] + [% firstremind %] + [% overduefinescap FILTER format("%.2f") %] + + [% IF cap_fine_to_replacement_price %] + + [% ELSE %] + + [% END %] + + [% finedays %] + [% maxsuspensiondays %] + [% renewalsallowed %] + [% renewalperiod %] + [% norenewalbefore %] + + [% IF auto_renew %] + Yes + [% ELSE %] + No + [% END %] + + [% no_auto_renewal_after %] + [% no_auto_renewal_after_hard_limit %] + [% reservesallowed %] + [% holds_per_record %] + + [% IF onshelfholds == 1 %] + Yes + [% ELSIF onshelfholds == 2 %] + If all unavailable + [% ELSE %] + If any unavailable + [% END %] + + [% IF opacitemholds == 'F'%]Force[% ELSIF opacitemholds == 'Y'%]Allow[% ELSE %]Don't allow[% END %] + + [% IF article_requests == 'no' %] + No + [% ELSIF article_requests == 'yes' %] + Yes + [% ELSIF article_requests == 'bib_only' %] + Record only + [% ELSIF article_requests == 'item_only' %] + Item only + [% END %] + + [% rentaldiscount %] + + Edit + Delete + + + [% END %] + [% END %] [% END %] diff --git a/t/db_dependent/ArticleRequests.t b/t/db_dependent/ArticleRequests.t index a9466a6..01588ce 100755 --- a/t/db_dependent/ArticleRequests.t +++ b/t/db_dependent/ArticleRequests.t @@ -27,6 +27,7 @@ use Koha::Database; use Koha::Biblio; use Koha::Patron; use Koha::Library; +use Koha::CirculationRules; BEGIN { use_ok('Koha::ArticleRequest'); @@ -41,7 +42,7 @@ my $builder = t::lib::TestBuilder->new; my $dbh = C4::Context->dbh; $dbh->{RaiseError} = 1; -$dbh->do("DELETE FROM issuingrules"); +$dbh->do("DELETE FROM circulation_rules"); my $biblio = Koha::Biblio->new()->store(); ok( $biblio->id, 'Koha::Biblio created' ); @@ -144,33 +145,60 @@ $article_request->complete(); $article_request->cancel(); is( $biblio->article_requests_finished()->count(), 1, 'Canceled request not returned for article_requests_finished' ); -my $rule; -$rule = $schema->resultset('Issuingrule') - ->new( { categorycode => '*', itemtype => '*', branchcode => '*', article_requests => 'yes' } )->insert(); +my $rule = Koha::CirculationRules->set_rule( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rule_name => 'article_requests', + rule_value => 'yes', + } +); ok( $biblio->can_article_request($patron), 'Record is requestable with rule type yes' ); is( $biblio->article_request_type($patron), 'yes', 'Biblio article request type is yes' ); ok( $item->can_article_request($patron), 'Item is requestable with rule type yes' ); is( $item->article_request_type($patron), 'yes', 'Item article request type is yes' ); $rule->delete(); -$rule = $schema->resultset('Issuingrule') - ->new( { categorycode => '*', itemtype => '*', branchcode => '*', article_requests => 'bib_only' } )->insert(); +$rule = Koha::CirculationRules->set_rule( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rule_name => 'article_requests', + rule_value => 'bib_only', + } +); ok( $biblio->can_article_request($patron), 'Record is requestable with rule type bib_only' ); is( $biblio->article_request_type($patron), 'bib_only', 'Biblio article request type is bib_only' ); ok( !$item->can_article_request($patron), 'Item is not requestable with rule type bib_only' ); is( $item->article_request_type($patron), 'bib_only', 'Item article request type is bib_only' ); $rule->delete(); -$rule = $schema->resultset('Issuingrule') - ->new( { categorycode => '*', itemtype => '*', branchcode => '*', article_requests => 'item_only' } )->insert(); +$rule = Koha::CirculationRules->set_rule( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rule_name => 'article_requests', + rule_value => 'item_only', + } +); ok( $biblio->can_article_request($patron), 'Record is requestable with rule type item_only' ); is( $biblio->article_request_type($patron), 'item_only', 'Biblio article request type is item_only' ); ok( $item->can_article_request($patron), 'Item is not requestable with rule type item_only' ); is( $item->article_request_type($patron), 'item_only', 'Item article request type is item_only' ); $rule->delete(); -$rule = $schema->resultset('Issuingrule') - ->new( { categorycode => '*', itemtype => '*', branchcode => '*', article_requests => 'no' } )->insert(); +$rule = Koha::CirculationRules->set_rule( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rule_name => 'article_requests', + rule_value => 'no', + } +); ok( !$biblio->can_article_request($patron), 'Record is requestable with rule type no' ); is( $biblio->article_request_type($patron), 'no', 'Biblio article request type is no' ); ok( !$item->can_article_request($patron), 'Item is not requestable with rule type no' ); diff --git a/t/db_dependent/Circulation.t b/t/db_dependent/Circulation.t index 19c1671..f2b5f91 100755 --- a/t/db_dependent/Circulation.t +++ b/t/db_dependent/Circulation.t @@ -33,7 +33,6 @@ use C4::Reserves; use C4::Overdues qw(UpdateFine CalcFine); use Koha::DateUtils; use Koha::Database; -use Koha::IssuingRules; use Koha::Checkouts; use Koha::Patrons; use Koha::CirculationRules; @@ -168,27 +167,24 @@ is( ); # Set a simple circ policy -$dbh->do('DELETE FROM issuingrules'); -Koha::CirculationRules->search()->delete(); -$dbh->do( - q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, - issuelength, lengthunit, - renewalsallowed, renewalperiod, - norenewalbefore, auto_renew, - fine, chargeperiod) - VALUES (?, ?, ?, ?, - ?, ?, - ?, ?, - ?, ?, - ?, ? - ) - }, - {}, - '*', '*', '*', 25, - 14, 'days', - 1, 7, - undef, 0, - .10, 1 +$dbh->do('DELETE FROM circulation_rules'); +Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + reservesallowed => 25, + issuelength => 14, + lengthunit => 'days', + renewalsallowed => 1, + renewalperiod => 7, + norenewalbefore => undef, + auto_renew => 0, + fine => .10, + chargeperiod => 1, + } + } ); # Test C4::Circulation::ProcessOfflinePayment @@ -332,7 +328,15 @@ C4::Context->dbh->do("DELETE FROM accountlines"); ); # Testing of feature to allow the renewal of reserved items if other items on the record can fill all needed holds - C4::Context->dbh->do("UPDATE issuingrules SET onshelfholds = 1"); + Koha::CirculationRules->set_rule( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rule_name => 'onshelfholds', + rule_value => '1', + } + ); t::lib::Mocks::mock_preference('AllowRenewalIfOtherItemsAvailable', 1 ); ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber); is( $renewokay, 1, 'Bug 11634 - Allow renewal of item with unfilled holds if other available items can fill those holds'); @@ -530,7 +534,15 @@ C4::Context->dbh->do("DELETE FROM accountlines"); # Bug 7413 # Test premature manual renewal - $dbh->do('UPDATE issuingrules SET norenewalbefore = 7'); + Koha::CirculationRules->set_rule( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rule_name => 'norenewalbefore', + rule_value => '7', + } + ); ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber); is( $renewokay, 0, 'Bug 7413: Cannot renew, renewal is premature'); @@ -565,7 +577,7 @@ C4::Context->dbh->do("DELETE FROM accountlines"); # 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('UPDATE issuingrules SET norenewalbefore = 0'); + $dbh->do(q{UPDATE circulation_rules SET rule_value = '0' WHERE rule_name = 'norenewalbefore'}); ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $itemnumber4 ); is( $renewokay, 0, 'Bug 14101: Cannot renew, renewal is automatic and premature' ); @@ -575,7 +587,7 @@ C4::Context->dbh->do("DELETE FROM accountlines"); # Change policy so that loans can be renewed 99 days prior to the due date # and test automatic renewal again - $dbh->do('UPDATE issuingrules SET norenewalbefore = 99'); + $dbh->do(q{UPDATE circulation_rules SET rule_value = '99' WHERE rule_name = 'norenewalbefore'}); ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $itemnumber4 ); is( $renewokay, 0, 'Bug 14101: Cannot renew, renewal is automatic' ); @@ -599,43 +611,116 @@ C4::Context->dbh->do("DELETE FROM accountlines"); my $ten_days_ahead = dt_from_string->add( days => 10 ); AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } ); - $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = 9'); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => '7', + no_auto_renewal_after => '9', + } + } + ); ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); is( $renewokay, 0, 'Do not renew, renewal is automatic' ); is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' ); - $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = 10'); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => '7', + no_auto_renewal_after => '10', + } + } + ); ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); is( $renewokay, 0, 'Do not renew, renewal is automatic' ); is( $error, 'auto_too_late', 'Cannot auto renew, too late - no_auto_renewal_after is inclusive(returned code is auto_too_late)' ); - $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = 11'); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => '7', + no_auto_renewal_after => '11', + } + } + ); ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); is( $renewokay, 0, 'Do not renew, renewal is automatic' ); is( $error, 'auto_too_soon', 'Cannot auto renew, too soon - no_auto_renewal_after is defined(returned code is auto_too_soon)' ); - $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 11'); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => '10', + no_auto_renewal_after => '11', + } + } + ); ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); is( $renewokay, 0, 'Do not renew, renewal is automatic' ); is( $error, 'auto_renew', 'Cannot renew, renew is automatic' ); - $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = NULL, no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => -1 ) ); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => '10', + no_auto_renewal_after => undef, + no_auto_renewal_after_hard_limit => dt_from_string->add( days => -1 ), + } + } + ); ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); is( $renewokay, 0, 'Do not renew, renewal is automatic' ); is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' ); - $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = 15, no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => -1 ) ); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => '7', + no_auto_renewal_after => '15', + no_auto_renewal_after_hard_limit => dt_from_string->add( days => -1 ), + } + } + ); ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); is( $renewokay, 0, 'Do not renew, renewal is automatic' ); is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' ); - $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = NULL, no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => 1 ) ); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => '10', + no_auto_renewal_after => undef, + no_auto_renewal_after_hard_limit => dt_from_string->add( days => 1 ), + } + } + ); ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); is( $renewokay, 0, 'Do not renew, renewal is automatic' ); @@ -657,7 +742,17 @@ C4::Context->dbh->do("DELETE FROM accountlines"); my $ten_days_ahead = dt_from_string->add( days => 10 ); AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } ); - $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 11'); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => '10', + no_auto_renewal_after => '11', + } + } + ); C4::Context->set_preference('OPACFineNoRenewalsBlockAutoRenew','1'); C4::Context->set_preference('OPACFineNoRenewals','10'); my $fines_amount = 5; @@ -697,31 +792,89 @@ C4::Context->dbh->do("DELETE FROM accountlines"); my $ten_days_before = dt_from_string->add( days => -10 ); my $ten_days_ahead = dt_from_string->add( days => 10 ); AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } ); - $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = "", no_auto_renewal_after_hard_limit = NULL'); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => '7', + no_auto_renewal_after => '', + no_auto_renewal_after_hard_limit => undef, + } + } + ); my $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); is( $latest_auto_renew_date, undef, 'GetLatestAutoRenewDate should return undef if no_auto_renewal_after or no_auto_renewal_after_hard_limit are not defined' ); my $five_days_before = dt_from_string->add( days => -5 ); - $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 5, no_auto_renewal_after_hard_limit = NULL'); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => '10', + no_auto_renewal_after => '5', + no_auto_renewal_after_hard_limit => undef, + } + } + ); $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); is( $latest_auto_renew_date->truncate( to => 'minute' ), $five_days_before->truncate( to => 'minute' ), 'GetLatestAutoRenewDate should return -5 days if no_auto_renewal_after = 5 and date_due is 10 days before' ); my $five_days_ahead = dt_from_string->add( days => 5 ); - $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 15, no_auto_renewal_after_hard_limit = NULL'); + $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::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => '10', + no_auto_renewal_after => '15', + no_auto_renewal_after_hard_limit => undef, + } + } + ); $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); is( $latest_auto_renew_date->truncate( to => 'minute' ), $five_days_ahead->truncate( to => 'minute' ), 'GetLatestAutoRenewDate should return +5 days if no_auto_renewal_after = 15 and date_due is 10 days before' ); my $two_days_ahead = dt_from_string->add( days => 2 ); - $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = "", no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => 2 ) ); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => '10', + no_auto_renewal_after => '', + no_auto_renewal_after_hard_limit => dt_from_string->add( days => 2 ), + } + } + ); $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); is( $latest_auto_renew_date->truncate( to => 'day' ), $two_days_ahead->truncate( to => 'day' ), 'GetLatestAutoRenewDate should return +2 days if no_auto_renewal_after_hard_limit is defined and not no_auto_renewal_after' ); - $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 15, no_auto_renewal_after_hard_limit = ?', undef, dt_from_string->add( days => 2 ) ); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => '10', + no_auto_renewal_after => '15', + no_auto_renewal_after_hard_limit => dt_from_string->add( days => 2 ), + } + } + ); $latest_auto_renew_date = GetLatestAutoRenewDate( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); is( $latest_auto_renew_date->truncate( to => 'day' ), $two_days_ahead->truncate( to => 'day' ), @@ -729,11 +882,20 @@ C4::Context->dbh->do("DELETE FROM accountlines"); ); }; - # Too many renewals # set policy to forbid renewals - $dbh->do('UPDATE issuingrules SET norenewalbefore = NULL, renewalsallowed = 0'); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + norenewalbefore => undef, + renewalsallowed => 0, + } + } + ); ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber); is( $renewokay, 0, 'Cannot renew, 0 renewals allowed'); @@ -946,30 +1108,26 @@ C4::Context->dbh->do("DELETE FROM accountlines"); { $dbh->do('DELETE FROM issues'); $dbh->do('DELETE FROM items'); - $dbh->do('DELETE FROM issuingrules'); - Koha::CirculationRules->search()->delete(); - $dbh->do( - q{ - INSERT INTO issuingrules ( categorycode, branchcode, itemtype, reservesallowed, issuelength, lengthunit, renewalsallowed, renewalperiod, - norenewalbefore, auto_renew, fine, chargeperiod ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) - }, - {}, - '*', '*', '*', 25, - 14, 'days', - 1, 7, - undef, 0, - .10, 1 - ); - Koha::CirculationRules->set_rules( - { - categorycode => '*', - itemtype => '*', - branchcode => '*', - rules => { - maxissueqty => 20 - } - } - ); + $dbh->do('DELETE FROM circulation_rules'); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + reservesallowed => 25, + issuelength => 14, + lengthunit => 'days', + renewalsallowed => 1, + renewalperiod => 7, + norenewalbefore => undef, + auto_renew => 0, + fine => .10, + chargeperiod => 1, + maxissueqty => 20 + } + } + ); my $biblio = MARC::Record->new(); my ( $biblionumber, $biblioitemnumber ) = AddBiblio( $biblio, '' ); @@ -1021,22 +1179,58 @@ C4::Context->dbh->do("DELETE FROM accountlines"); undef, undef, undef ); - C4::Context->dbh->do("UPDATE issuingrules SET onshelfholds = 0"); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + onshelfholds => 0, + } + } + ); t::lib::Mocks::mock_preference( 'AllowRenewalIfOtherItemsAvailable', 0 ); ( $renewokay, $error ) = CanBookBeRenewed( $borrowernumber1, $itemnumber1 ); is( $renewokay, 0, 'Bug 14337 - Verify the borrower cannot renew with a hold on the record if AllowRenewalIfOtherItemsAvailable and onshelfholds are disabled' ); - C4::Context->dbh->do("UPDATE issuingrules SET onshelfholds = 0"); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + onshelfholds => 0, + } + } + ); t::lib::Mocks::mock_preference( 'AllowRenewalIfOtherItemsAvailable', 1 ); ( $renewokay, $error ) = CanBookBeRenewed( $borrowernumber1, $itemnumber1 ); is( $renewokay, 0, 'Bug 14337 - Verify the borrower cannot renew with a hold on the record if AllowRenewalIfOtherItemsAvailable is enabled and onshelfholds is disabled' ); - C4::Context->dbh->do("UPDATE issuingrules SET onshelfholds = 1"); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + onshelfholds => 1, + } + } + ); t::lib::Mocks::mock_preference( 'AllowRenewalIfOtherItemsAvailable', 0 ); ( $renewokay, $error ) = CanBookBeRenewed( $borrowernumber1, $itemnumber1 ); is( $renewokay, 0, 'Bug 14337 - Verify the borrower cannot renew with a hold on the record if AllowRenewalIfOtherItemsAvailable is disabled and onshelfhold is enabled' ); - C4::Context->dbh->do("UPDATE issuingrules SET onshelfholds = 1"); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + onshelfholds => 1, + } + } + ); t::lib::Mocks::mock_preference( 'AllowRenewalIfOtherItemsAvailable', 1 ); ( $renewokay, $error ) = CanBookBeRenewed( $borrowernumber1, $itemnumber1 ); is( $renewokay, 1, 'Bug 14337 - Verify the borrower can renew with a hold on the record if AllowRenewalIfOtherItemsAvailable and onshelfhold are enabled' ); @@ -1557,20 +1751,21 @@ subtest 'AddReturn + CumulativeRestrictionPeriods' => sub { } ); - # And the issuing rule - Koha::IssuingRules->search->delete; - my $rule = Koha::IssuingRule->new( + # And the circulation rule + Koha::CirculationRules->search->delete; + Koha::CirculationRules->set_rules( { categorycode => '*', itemtype => '*', branchcode => '*', - issuelength => 1, - firstremind => 1, # 1 day of grace - finedays => 2, # 2 days of fine per day of overdue - lengthunit => 'days', + rules => { + issuelength => 1, + firstremind => 1, # 1 day of grace + finedays => 2, # 2 days of fine per day of overdue + lengthunit => 'days', + } } ); - $rule->store(); # Patron cannot issue item_1, they have overdues my $five_days_ago = dt_from_string->subtract( days => 5 ); @@ -1672,20 +1867,21 @@ subtest 'AddReturn | is_overdue' => sub { } ); - Koha::IssuingRules->search->delete; - my $rule = Koha::IssuingRule->new( + Koha::CirculationRules->search->delete; + my $rule = Koha::CirculationRules->set_rules( { categorycode => '*', itemtype => '*', branchcode => '*', - maxissueqty => 99, - issuelength => 6, - lengthunit => 'days', - fine => 1, # Charge 1 every day of overdue - chargeperiod => 1, + rules => { + maxissueqty => 99, + issuelength => 6, + lengthunit => 'days', + fine => 1, # Charge 1 every day of overdue + chargeperiod => 1, + } } ); - $rule->store(); my $one_day_ago = dt_from_string->subtract( days => 1 ); my $five_days_ago = dt_from_string->subtract( days => 5 ); diff --git a/t/db_dependent/Circulation/CalcDateDue.t b/t/db_dependent/Circulation/CalcDateDue.t index e533806..ee58421 100644 --- a/t/db_dependent/Circulation/CalcDateDue.t +++ b/t/db_dependent/Circulation/CalcDateDue.t @@ -9,6 +9,8 @@ use DateTime; use t::lib::Mocks; use t::lib::TestBuilder; +use Koha::CirculationRules; + use_ok('C4::Circulation'); my $schema = Koha::Database->new->schema; @@ -22,14 +24,19 @@ my $issuelength = 10; my $renewalperiod = 5; my $lengthunit = 'days'; -Koha::Database->schema->resultset('Issuingrule')->create({ - categorycode => $categorycode, - itemtype => $itemtype, - branchcode => $branchcode, - issuelength => $issuelength, - renewalperiod => $renewalperiod, - lengthunit => $lengthunit, -}); +Koha::CirculationRules->search()->delete(); +Koha::CirculationRules->set_rules( + { + categorycode => $categorycode, + itemtype => $itemtype, + branchcode => $branchcode, + rules => { + issuelength => $issuelength, + renewalperiod => $renewalperiod, + lengthunit => $lengthunit, + } + } +); #Set syspref ReturnBeforeExpiry = 1 and useDaysMode = 'Days' t::lib::Mocks::mock_preference('ReturnBeforeExpiry', 1); diff --git a/t/db_dependent/Circulation/CalcFine.t b/t/db_dependent/Circulation/CalcFine.t index 862673f..89dbb2d 100644 --- a/t/db_dependent/Circulation/CalcFine.t +++ b/t/db_dependent/Circulation/CalcFine.t @@ -66,19 +66,12 @@ my $item = $builder->build( subtest 'Test basic functionality' => sub { plan tests => 1; - my $rule = $builder->schema->resultset('Issuingrule')->find({ - branchcode => '*', - categorycode => '*', - itemtype => '*', - }); - $rule->delete if $rule; - my $issuingrule = $builder->build( + Koha::CirculationRules->set_rules( { - source => 'Issuingrule', - value => { - branchcode => '*', - categorycode => '*', - itemtype => '*', + branchcode => '*', + categorycode => '*', + itemtype => '*', + rules => { fine => '1.00', lengthunit => 'days', finedays => 0, @@ -86,8 +79,8 @@ subtest 'Test basic functionality' => sub { chargeperiod => 1, overduefinescap => undef, cap_fine_to_replacement_price => 0, - }, - } + } + }, ); my $start_dt = DateTime->new( @@ -111,13 +104,12 @@ subtest 'Test basic functionality' => sub { subtest 'Test cap_fine_to_replacement_price' => sub { plan tests => 1; - my $issuingrule = $builder->build( + Koha::CirculationRules->set_rules( { - source => 'Issuingrule', - value => { - branchcode => '*', - categorycode => '*', - itemtype => '*', + branchcode => '*', + categorycode => '*', + itemtype => '*', + rules => { fine => '1.00', lengthunit => 'days', finedays => 0, @@ -149,5 +141,5 @@ subtest 'Test cap_fine_to_replacement_price' => sub { }; sub teardown { - $dbh->do(q|DELETE FROM issuingrules|); + $dbh->do(q|DELETE FROM circulation_rules|); } diff --git a/t/db_dependent/Circulation/GetHardDueDate.t b/t/db_dependent/Circulation/GetHardDueDate.t index 064356e..8a0adfa 100644 --- a/t/db_dependent/Circulation/GetHardDueDate.t +++ b/t/db_dependent/Circulation/GetHardDueDate.t @@ -4,7 +4,7 @@ use Modern::Perl; use C4::Context; use DateTime; use Koha::DateUtils; -use Koha::IssuingRules; +use Koha::CirculationRules; use Koha::Library; use Test::More tests => 10; @@ -31,7 +31,7 @@ $dbh->do(q|DELETE FROM borrowers|); $dbh->do(q|DELETE FROM edifact_ean|); $dbh->do(q|DELETE FROM branches|); $dbh->do(q|DELETE FROM categories|); -$dbh->do(q|DELETE FROM issuingrules|); +$dbh->do(q|DELETE FROM circulation_rules|); #Add sample datas @@ -111,228 +111,123 @@ my $default = { lengthunit => 'days' }; -#Test GetIssuingRule +#Test get_effective_rules my $sampleissuingrule1 = { - reservecharge => '0.000000', - chargename => 'Null', - restrictedtype => 0, - accountsent => 0, - finedays => 0, - lengthunit => 'days', - renewalperiod => 5, - norenewalbefore => 6, - auto_renew => 0, - issuelength => 5, - chargeperiod => 0, - chargeperiod_charge_at => 0, - rentaldiscount => '2.000000', - reservesallowed => 0, - hardduedate => '2013-01-01', - branchcode => $samplebranch1->{branchcode}, - fine => '0.000000', - hardduedatecompare => 5, - overduefinescap => '0.000000', - renewalsallowed => 0, - firstremind => 0, - itemtype => 'BOOK', - categorycode => $samplecat->{categorycode}, - maxsuspensiondays => 0, - onshelfholds => 0, - opacitemholds => 'N', - cap_fine_to_replacement_price => 0, - holds_per_record => 1, - article_requests => 'yes', - no_auto_renewal_after => undef, - no_auto_renewal_after_hard_limit => undef, + branchcode => $samplebranch1->{branchcode}, + categorycode => $samplecat->{categorycode}, + itemtype => 'BOOK', + rules => { + reservecharge => '0.000000', + chargename => 'Null', + restrictedtype => 0, + accountsent => 0, + finedays => 0, + lengthunit => 'days', + renewalperiod => 5, + norenewalbefore => 6, + auto_renew => 0, + issuelength => 5, + chargeperiod => 0, + chargeperiod_charge_at => 0, + rentaldiscount => '2.000000', + reservesallowed => 0, + hardduedate => '2013-01-01', + fine => '0.000000', + hardduedatecompare => 5, + overduefinescap => '0.000000', + renewalsallowed => 0, + firstremind => 0, + maxsuspensiondays => 0, + onshelfholds => 0, + opacitemholds => 'N', + cap_fine_to_replacement_price => 0, + holds_per_record => 1, + article_requests => 'yes', + } }; my $sampleissuingrule2 = { - branchcode => $samplebranch2->{branchcode}, - categorycode => $samplecat->{categorycode}, - itemtype => 'BOOK', - renewalsallowed => 'Null', - renewalperiod => 2, - norenewalbefore => 7, - auto_renew => 0, - reservesallowed => 'Null', - issuelength => 2, - lengthunit => 'days', - hardduedate => 2, - hardduedatecompare => 'Null', - fine => 'Null', - finedays => 'Null', - firstremind => 'Null', - chargeperiod => 'Null', - chargeperiod_charge_at => 0, - rentaldiscount => 2.00, - overduefinescap => 'Null', - accountsent => 'Null', - reservecharge => 'Null', - chargename => 'Null', - restrictedtype => 'Null', - maxsuspensiondays => 0, - onshelfholds => 1, - opacitemholds => 'Y', - cap_fine_to_replacement_price => 0, - holds_per_record => 1, - article_requests => 'yes', + branchcode => $samplebranch2->{branchcode}, + categorycode => $samplecat->{categorycode}, + itemtype => 'BOOK', + rules => { + renewalsallowed => 'Null', + renewalperiod => 2, + norenewalbefore => 7, + auto_renew => 0, + reservesallowed => 'Null', + issuelength => 2, + lengthunit => 'days', + hardduedate => 2, + hardduedatecompare => 'Null', + fine => 'Null', + finedays => 'Null', + firstremind => 'Null', + chargeperiod => 'Null', + chargeperiod_charge_at => 0, + rentaldiscount => 2.00, + overduefinescap => 'Null', + accountsent => 'Null', + reservecharge => 'Null', + chargename => 'Null', + restrictedtype => 'Null', + maxsuspensiondays => 0, + onshelfholds => 1, + opacitemholds => 'Y', + cap_fine_to_replacement_price => 0, + holds_per_record => 1, + article_requests => 'yes', + } }; my $sampleissuingrule3 = { - branchcode => $samplebranch1->{branchcode}, - categorycode => $samplecat->{categorycode}, - itemtype => 'DVD', - renewalsallowed => 'Null', - renewalperiod => 3, - norenewalbefore => 8, - auto_renew => 0, - reservesallowed => 'Null', - issuelength => 3, - lengthunit => 'days', - hardduedate => 3, - hardduedatecompare => 'Null', - fine => 'Null', - finedays => 'Null', - firstremind => 'Null', - chargeperiod => 'Null', - chargeperiod_charge_at => 0, - rentaldiscount => 3.00, - overduefinescap => 'Null', - accountsent => 'Null', - reservecharge => 'Null', - chargename => 'Null', - restrictedtype => 'Null', - maxsuspensiondays => 0, - onshelfholds => 1, - opacitemholds => 'F', - cap_fine_to_replacement_price => 0, - holds_per_record => 1, - article_requests => 'yes', + branchcode => $samplebranch1->{branchcode}, + categorycode => $samplecat->{categorycode}, + itemtype => 'DVD', + rules => { + renewalsallowed => 'Null', + renewalperiod => 3, + norenewalbefore => 8, + auto_renew => 0, + reservesallowed => 'Null', + issuelength => 3, + lengthunit => 'days', + hardduedate => 3, + hardduedatecompare => 'Null', + fine => 'Null', + finedays => 'Null', + firstremind => 'Null', + chargeperiod => 'Null', + chargeperiod_charge_at => 0, + rentaldiscount => 3.00, + overduefinescap => 'Null', + accountsent => 'Null', + reservecharge => 'Null', + chargename => 'Null', + restrictedtype => 'Null', + maxsuspensiondays => 0, + onshelfholds => 1, + opacitemholds => 'F', + cap_fine_to_replacement_price => 0, + holds_per_record => 1, + article_requests => 'yes', + } }; -$query = 'INSERT INTO issuingrules ( - branchcode, - categorycode, - itemtype, - renewalsallowed, - renewalperiod, - norenewalbefore, - auto_renew, - reservesallowed, - issuelength, - lengthunit, - hardduedate, - hardduedatecompare, - fine, - finedays, - firstremind, - chargeperiod, - chargeperiod_charge_at, - rentaldiscount, - overduefinescap, - accountsent, - reservecharge, - chargename, - restrictedtype, - maxsuspensiondays, - onshelfholds, - opacitemholds, - cap_fine_to_replacement_price, - article_requests - ) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)'; -my $sth = $dbh->prepare($query); -$sth->execute( - $sampleissuingrule1->{branchcode}, - $sampleissuingrule1->{categorycode}, - $sampleissuingrule1->{itemtype}, - $sampleissuingrule1->{renewalsallowed}, - $sampleissuingrule1->{renewalperiod}, - $sampleissuingrule1->{norenewalbefore}, - $sampleissuingrule1->{auto_renew}, - $sampleissuingrule1->{reservesallowed}, - $sampleissuingrule1->{issuelength}, - $sampleissuingrule1->{lengthunit}, - $sampleissuingrule1->{hardduedate}, - $sampleissuingrule1->{hardduedatecompare}, - $sampleissuingrule1->{fine}, - $sampleissuingrule1->{finedays}, - $sampleissuingrule1->{firstremind}, - $sampleissuingrule1->{chargeperiod}, - $sampleissuingrule1->{chargeperiod_charge_at}, - $sampleissuingrule1->{rentaldiscount}, - $sampleissuingrule1->{overduefinescap}, - $sampleissuingrule1->{accountsent}, - $sampleissuingrule1->{reservecharge}, - $sampleissuingrule1->{chargename}, - $sampleissuingrule1->{restrictedtype}, - $sampleissuingrule1->{maxsuspensiondays}, - $sampleissuingrule1->{onshelfholds}, - $sampleissuingrule1->{opacitemholds}, - $sampleissuingrule1->{cap_fine_to_replacement_price}, - $sampleissuingrule1->{article_requests}, -); -$sth->execute( - $sampleissuingrule2->{branchcode}, - $sampleissuingrule2->{categorycode}, - $sampleissuingrule2->{itemtype}, - $sampleissuingrule2->{renewalsallowed}, - $sampleissuingrule2->{renewalperiod}, - $sampleissuingrule2->{norenewalbefore}, - $sampleissuingrule2->{auto_renew}, - $sampleissuingrule2->{reservesallowed}, - $sampleissuingrule2->{issuelength}, - $sampleissuingrule2->{lengthunit}, - $sampleissuingrule2->{hardduedate}, - $sampleissuingrule2->{hardduedatecompare}, - $sampleissuingrule2->{fine}, - $sampleissuingrule2->{finedays}, - $sampleissuingrule2->{firstremind}, - $sampleissuingrule2->{chargeperiod}, - $sampleissuingrule2->{chargeperiod_charge_at}, - $sampleissuingrule2->{rentaldiscount}, - $sampleissuingrule2->{overduefinescap}, - $sampleissuingrule2->{accountsent}, - $sampleissuingrule2->{reservecharge}, - $sampleissuingrule2->{chargename}, - $sampleissuingrule2->{restrictedtype}, - $sampleissuingrule2->{maxsuspensiondays}, - $sampleissuingrule2->{onshelfholds}, - $sampleissuingrule2->{opacitemholds}, - $sampleissuingrule2->{cap_fine_to_replacement_price}, - $sampleissuingrule2->{article_requests}, -); -$sth->execute( - $sampleissuingrule3->{branchcode}, - $sampleissuingrule3->{categorycode}, - $sampleissuingrule3->{itemtype}, - $sampleissuingrule3->{renewalsallowed}, - $sampleissuingrule3->{renewalperiod}, - $sampleissuingrule3->{norenewalbefore}, - $sampleissuingrule3->{auto_renew}, - $sampleissuingrule3->{reservesallowed}, - $sampleissuingrule3->{issuelength}, - $sampleissuingrule3->{lengthunit}, - $sampleissuingrule3->{hardduedate}, - $sampleissuingrule3->{hardduedatecompare}, - $sampleissuingrule3->{fine}, - $sampleissuingrule3->{finedays}, - $sampleissuingrule3->{firstremind}, - $sampleissuingrule3->{chargeperiod}, - $sampleissuingrule3->{chargeperiod_charge_at}, - $sampleissuingrule3->{rentaldiscount}, - $sampleissuingrule3->{overduefinescap}, - $sampleissuingrule3->{accountsent}, - $sampleissuingrule3->{reservecharge}, - $sampleissuingrule3->{chargename}, - $sampleissuingrule3->{restrictedtype}, - $sampleissuingrule3->{maxsuspensiondays}, - $sampleissuingrule3->{onshelfholds}, - $sampleissuingrule3->{opacitemholds}, - $sampleissuingrule3->{cap_fine_to_replacement_price}, - $sampleissuingrule3->{article_requests}, -); +Koha::CirculationRules->set_rules( $sampleissuingrule1 ); +Koha::CirculationRules->set_rules( $sampleissuingrule2 ); +Koha::CirculationRules->set_rules( $sampleissuingrule3 ); + +my $rules = Koha::CirculationRules->get_effective_rules( + { + categorycode => $sampleissuingrule1->{categorycode}, + itemtype => $sampleissuingrule1->{itemtype}, + branchcode => $sampleissuingrule1->{branchcode}, + rules => [ keys %{ $sampleissuingrule1->{rules} } ] + } + ); is_deeply( - Koha::IssuingRules->find({ categorycode => $samplecat->{categorycode}, itemtype => 'Book', branchcode => $samplebranch1->{branchcode} })->unblessed, - $sampleissuingrule1, + $rules, + $sampleissuingrule1->{rules}, "GetIssuingCharge returns issuingrule1's informations" ); @@ -382,8 +277,8 @@ my @hardduedate = C4::Circulation::GetHardDueDate( $samplecat->{categorycode}, is_deeply( \@hardduedate, [ - dt_from_string( $sampleissuingrule1->{hardduedate}, 'iso' ), - $sampleissuingrule1->{hardduedatecompare} + dt_from_string( $sampleissuingrule1->{rules}->{hardduedate}, 'iso' ), + $sampleissuingrule1->{rules}->{hardduedatecompare} ], "GetHardDueDate returns the duedate and the duedatecompare" ); diff --git a/t/db_dependent/Circulation/IssuingRules/maxsuspensiondays.t b/t/db_dependent/Circulation/IssuingRules/maxsuspensiondays.t index 9e41b46..8257c9e 100644 --- a/t/db_dependent/Circulation/IssuingRules/maxsuspensiondays.t +++ b/t/db_dependent/Circulation/IssuingRules/maxsuspensiondays.t @@ -30,17 +30,16 @@ my $userenv->{branch} = $branchcode; *C4::Context::userenv = \&Mock_userenv; # Test without maxsuspensiondays set -Koha::IssuingRules->search->delete; -$builder->build( +Koha::CirculationRules->search->delete; +Koha::CirculationRules->set_rules( { - source => 'Issuingrule', - value => { - categorycode => '*', - itemtype => '*', - branchcode => '*', - firstremind => 0, - finedays => 2, - lengthunit => 'days', + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + firstremind => 0, + finedays => 2, + lengthunit => 'days', } } ); @@ -87,8 +86,16 @@ is( DelDebarment( $debarments->[0]->{borrower_debarment_id} ); # Test with maxsuspensiondays = 10 days -my $issuing_rule = Koha::IssuingRules->search->next; -$issuing_rule->maxsuspensiondays( 10 )->store; +Koha::CirculationRules->set_rules( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + maxsuspensiondays => 10, + } + } +); my $daysafter10 = dt_from_string->add_duration(DateTime::Duration->new(days => 10)); AddIssue( $borrower, $barcode, $daysago20 ); diff --git a/t/db_dependent/Circulation/Returns.t b/t/db_dependent/Circulation/Returns.t index 802b9ef..955e619 100644 --- a/t/db_dependent/Circulation/Returns.t +++ b/t/db_dependent/Circulation/Returns.t @@ -48,16 +48,16 @@ my $schema = Koha::Database->schema; $schema->storage->txn_begin; my $builder = t::lib::TestBuilder->new(); -Koha::IssuingRules->search->delete; -my $rule = Koha::IssuingRule->new( +Koha::CirculationRules->search->delete; +Koha::CirculationRules->set_rule( { categorycode => '*', itemtype => '*', branchcode => '*', - issuelength => 1, + rule_name => 'issuelength', + rule_value => 1, } ); -$rule->store(); subtest "InProcessingToShelvingCart tests" => sub { @@ -281,7 +281,18 @@ subtest 'Handle ids duplication' => sub { t::lib::Mocks::mock_preference( 'item-level_itypes', 1 ); t::lib::Mocks::mock_preference( 'CalculateFinesOnReturn', 1 ); t::lib::Mocks::mock_preference( 'finesMode', 'production' ); - Koha::IssuingRules->search->update({ chargeperiod => 1, fine => 1, firstremind => 1, }); + Koha::CirculationRules->set_rules( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + chargeperiod => 1, + fine => 1, + firstremind => 1, + } + } + ); my $biblio = $builder->build( { source => 'Biblio' } ); my $itemtype = $builder->build( { source => 'Itemtype', value => { rentalcharge => 5 } } ); diff --git a/t/db_dependent/Circulation/SwitchOnSiteCheckouts.t b/t/db_dependent/Circulation/SwitchOnSiteCheckouts.t index 992980a..5eac1c4 100644 --- a/t/db_dependent/Circulation/SwitchOnSiteCheckouts.t +++ b/t/db_dependent/Circulation/SwitchOnSiteCheckouts.t @@ -37,12 +37,8 @@ $schema->storage->txn_begin; our $dbh = C4::Context->dbh; -$dbh->do(q|DELETE FROM branch_item_rules|); $dbh->do(q|DELETE FROM issues|); -$dbh->do(q|DELETE FROM default_branch_circ_rules|); -$dbh->do(q|DELETE FROM default_circ_rules|); -$dbh->do(q|DELETE FROM default_branch_item_rules|); -$dbh->do(q|DELETE FROM issuingrules|); +$dbh->do(q|DELETE FROM circulation_rules|); my $builder = t::lib::TestBuilder->new(); @@ -76,16 +72,6 @@ my $item = $builder->build({ }, }); -my $issuingrule = $builder->build({ - source => 'Issuingrule', - value => { - branchcode => $branch->{branchcode}, - categorycode => '*', - itemtype => '*', - lengthunit => 'days', - issuelength => 5, - }, -}); Koha::CirculationRules->search()->delete(); Koha::CirculationRules->set_rules( { @@ -95,6 +81,11 @@ Koha::CirculationRules->set_rules( rules => { maxissueqty => 2, maxonsiteissueqty => 1, + branchcode => $branch->{branchcode}, + categorycode => '*', + itemtype => '*', + lengthunit => 'days', + issuelength => 5, } } ); diff --git a/t/db_dependent/Circulation/TooMany.t b/t/db_dependent/Circulation/TooMany.t index f9830b2..f590bfb 100644 --- a/t/db_dependent/Circulation/TooMany.t +++ b/t/db_dependent/Circulation/TooMany.t @@ -43,12 +43,7 @@ $dbh->do(q|DELETE FROM branches|); $dbh->do(q|DELETE FROM categories|); $dbh->do(q|DELETE FROM accountlines|); $dbh->do(q|DELETE FROM itemtypes|); -$dbh->do(q|DELETE FROM branch_item_rules|); -$dbh->do(q|DELETE FROM default_branch_circ_rules|); -$dbh->do(q|DELETE FROM default_circ_rules|); -$dbh->do(q|DELETE FROM default_branch_item_rules|); -$dbh->do(q|DELETE FROM issuingrules|); -Koha::CirculationRules->search()->delete(); +$dbh->do(q|DELETE FROM circulation_rules|); my $builder = t::lib::TestBuilder->new(); t::lib::Mocks::mock_preference('item-level_itypes', 1); # Assuming the item type is defined at item level @@ -370,6 +365,17 @@ subtest '1 BranchBorrowerCircRule exist: 1 CO allowed, 1 OSCO allowed' => sub { ); teardown(); + Koha::CirculationRules->set_rules( + { + branchcode => $branch->{branchcode}, + categorycode => $category->{categorycode}, + itemtype => undef, + rules => { + maxissueqty => 1, + maxonsiteissueqty => 1, + } + } + ); $issue = C4::Circulation::AddIssue( $patron, $item->{barcode}, dt_from_string(), undef, undef, undef, { onsite_checkout => 1 } ); like( $issue->issue_id, qr|^\d+$|, 'The issue should have been inserted' ); @@ -417,7 +423,7 @@ $schema->storage->txn_rollback; sub teardown { $dbh->do(q|DELETE FROM issues|); - $dbh->do(q|DELETE FROM issuingrules|); + $dbh->do(q|DELETE FROM circulation_rules|); } 1; diff --git a/t/db_dependent/Circulation/issue.t b/t/db_dependent/Circulation/issue.t index 5adb123..66b2c41 100644 --- a/t/db_dependent/Circulation/issue.t +++ b/t/db_dependent/Circulation/issue.t @@ -33,6 +33,7 @@ use Koha::Database; use Koha::DateUtils; use Koha::Library; use Koha::Patrons; +use Koha::CirculationRules; BEGIN { require_ok('C4::Circulation'); @@ -65,7 +66,7 @@ $dbh->do(q|DELETE FROM borrowers|); $dbh->do(q|DELETE FROM branches|); $dbh->do(q|DELETE FROM categories|); $dbh->do(q|DELETE FROM accountlines|); -$dbh->do(q|DELETE FROM issuingrules|); +$dbh->do(q|DELETE FROM circulation_rules|); $dbh->do(q|DELETE FROM reserves|); $dbh->do(q|DELETE FROM old_reserves|); $dbh->do(q|DELETE FROM statistics|); @@ -287,10 +288,17 @@ is_deeply( #With something in DB # Add a default rule: No renewal allowed -$dbh->do(q| - INSERT INTO issuingrules( categorycode, itemtype, branchcode, issuelength, renewalsallowed ) - VALUES ( '*', '*', '*', 10, 0 ) -|); +Koha::CirculationRules->set_rules( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + issuelength => 10, + renewalsallowed => 0, + } + } +); @renewcount = C4::Circulation::GetRenewCount(); is_deeply( \@renewcount, @@ -311,9 +319,16 @@ is_deeply( ); # Add a default rule: renewal is allowed -$dbh->do(q| - UPDATE issuingrules SET renewalsallowed = 3 -|); +Koha::CirculationRules->set_rules( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + renewalsallowed => 3, + } + } +); @renewcount = C4::Circulation::GetRenewCount($borrower_id1, $item_id1); is_deeply( \@renewcount, diff --git a/t/db_dependent/DecreaseLoanHighHolds.t b/t/db_dependent/DecreaseLoanHighHolds.t index d4faaa3..88ec105 100755 --- a/t/db_dependent/DecreaseLoanHighHolds.t +++ b/t/db_dependent/DecreaseLoanHighHolds.t @@ -24,6 +24,7 @@ use Koha::Biblio; use Koha::Item; use Koha::Holds; use Koha::Hold; +use Koha::CirculationRules; use t::lib::TestBuilder; use t::lib::Mocks; @@ -38,7 +39,7 @@ $dbh->{RaiseError} = 1; $schema->storage->txn_begin(); $dbh->do('DELETE FROM issues'); -$dbh->do('DELETE FROM issuingrules'); +$dbh->do('DELETE FROM circulation_rules'); $dbh->do('DELETE FROM borrowers'); $dbh->do('DELETE FROM items'); @@ -87,15 +88,14 @@ for my $i ( 0 .. 5 ) { )->store(); } -$builder->build( +Koha::CirculationRules->set_rules( { - source => 'Issuingrule', - value => { - branchcode => '*', - categorycode => '*', - itemtype => '*', - issuelength => '14', - lengthunit => 'days', + branchcode => '*', + categorycode => '*', + itemtype => '*', + rules => { + issuelength => '14', + lengthunit => 'days', reservesallowed => '99', } } diff --git a/t/db_dependent/Fines.t b/t/db_dependent/Fines.t index 1f273ba..20d34ce 100644 --- a/t/db_dependent/Fines.t +++ b/t/db_dependent/Fines.t @@ -16,19 +16,21 @@ my $schema = Koha::Database->new()->schema(); $dbh->{RaiseError} = 1; $dbh->{AutoCommit} = 0; -$dbh->do(q|DELETE FROM issuingrules|); +$dbh->do(q|DELETE FROM circulation_rules|); -my $issuingrule = $schema->resultset('Issuingrule')->create( +my $issuingrule = Koha::CirculationRules->set_rules( { - categorycode => '*', - itemtype => '*', - branchcode => '*', - fine => 1, - finedays => 0, - chargeperiod => 7, - chargeperiod_charge_at => 0, - lengthunit => 'days', - issuelength => 1, + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + fine => 1, + finedays => 0, + chargeperiod => 7, + chargeperiod_charge_at => 0, + lengthunit => 'days', + issuelength => 1, + } } ); @@ -45,7 +47,16 @@ $period_end = dt_from_string('2000-01-10'); is( $fine, 1, '9 days overdue, charge period 7 days, charge at end of interval gives fine of $1' ); # Test charging fine at the *beginning* of each charge period -$issuingrule->update( { chargeperiod_charge_at => 1 } ); +my $issuingrule = Koha::CirculationRules->set_rules( + { + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + chargeperiod_charge_at => 1, + } + } +); $period_end = dt_from_string('2000-01-05'); ( $fine ) = CalcFine( {}, q{}, q{}, $period_start, $period_end ); diff --git a/t/db_dependent/Holds.t b/t/db_dependent/Holds.t index 1d4496d..3a40c5e 100755 --- a/t/db_dependent/Holds.t +++ b/t/db_dependent/Holds.t @@ -250,18 +250,28 @@ is( $reserve->{'priority'}, '5', "Test AlterPriority(), move to bottom" ); my ($foreign_bibnum, $foreign_title, $foreign_bibitemnum) = create_helper_biblio('DUMMY'); my ($foreign_item_bibnum, $foreign_item_bibitemnum, $foreign_itemnumber) = AddItem({ homebranch => $branch_2, holdingbranch => $branch_2 } , $foreign_bibnum); -$dbh->do('DELETE FROM issuingrules'); -$dbh->do( - q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_record) - VALUES (?, ?, ?, ?, ?)}, - {}, - '*', '*', '*', 25, 99 +$dbh->do('DELETE FROM circulation_rules'); +Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + reservesallowed => 25, + holds_per_record => 99, + } + } ); -$dbh->do( - q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_record) - VALUES (?, ?, ?, ?, ?)}, - {}, - '*', '*', 'CANNOT', 0, 99 +Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => 'CANNOT', + rules => { + reservesallowed => 0, + holds_per_record => 99, + } + } ); # make sure some basic sysprefs are set @@ -270,8 +280,8 @@ t::lib::Mocks::mock_preference('item-level_itypes', 1); # if IndependentBranches is OFF, a $branch_1 patron can reserve an $branch_2 item t::lib::Mocks::mock_preference('IndependentBranches', 0); -ok( - CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber) eq 'OK', +is( + CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber), 'OK', '$branch_1 patron allowed to reserve $branch_2 item with IndependentBranches OFF (bug 2394)' ); @@ -401,13 +411,17 @@ ok( # Test branch item rules -$dbh->do('DELETE FROM issuingrules'); $dbh->do('DELETE FROM circulation_rules'); -$dbh->do( - q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed) - VALUES (?, ?, ?, ?)}, - {}, - '*', '*', '*', 25 +Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + reservesallowed => 25, + holds_per_record => 99, + } + } ); Koha::CirculationRules->set_rules( { @@ -461,11 +475,16 @@ $dbh->do('DELETE FROM biblio'); ( $item_bibnum, $item_bibitemnum, $itemnumber ) = AddItem( { homebranch => $branch_1, holdingbranch => $branch_1 }, $bibnum ); -$dbh->do( - q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_record) - VALUES (?, ?, ?, ?, ?)}, - {}, - '*', '*', 'ONLY1', 1, 99 +Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => 'ONLY1', + rules => { + reservesallowed => 1, + holds_per_record => 99, + } + } ); is( CanItemBeReserved( $borrowernumbers[0], $itemnumber ), 'OK', 'Patron can reserve item with hold limit of 1, no holds placed' ); @@ -479,20 +498,22 @@ subtest 'Test max_holds per library/patron category' => sub { plan tests => 6; $dbh->do('DELETE FROM reserves'); - $dbh->do('DELETE FROM issuingrules'); $dbh->do('DELETE FROM circulation_rules'); ( $bibnum, $title, $bibitemnum ) = create_helper_biblio('TEST'); ( $item_bibnum, $item_bibitemnum, $itemnumber ) = AddItem( { homebranch => $branch_1, holdingbranch => $branch_1 }, $bibnum ); - $dbh->do( - q{ - INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_record) - VALUES (?, ?, ?, ?, ?) - }, - {}, - '*', '*', 'TEST', 99, 99 + Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => 'TEST', + rules => { + reservesallowed => 99, + holds_per_record => 99, + } + } ); AddReserve( $branch_1, $borrowernumbers[0], $bibnum, '', 1, ); AddReserve( $branch_1, $borrowernumbers[0], $bibnum, '', 1, ); diff --git a/t/db_dependent/Holds/DisallowHoldIfItemsAvailable.t b/t/db_dependent/Holds/DisallowHoldIfItemsAvailable.t index 1958caa..4a1ffcd 100755 --- a/t/db_dependent/Holds/DisallowHoldIfItemsAvailable.t +++ b/t/db_dependent/Holds/DisallowHoldIfItemsAvailable.t @@ -5,7 +5,7 @@ use Modern::Perl; use C4::Context; use C4::Items; use C4::Circulation; -use Koha::IssuingRule; +use Koha::CirculationRules; use Test::More tests => 4; @@ -86,19 +86,20 @@ my $itemnumber2 = my $item2 = GetItem( $itemnumber2 ); -$dbh->do("DELETE FROM issuingrules"); -my $rule = Koha::IssuingRule->new( +$dbh->do("DELETE FROM circulation_rules"); +Koha::CirculationRules->set_rules( { categorycode => '*', itemtype => '*', branchcode => '*', - issuelength => 7, - lengthunit => 8, - reservesallowed => 99, - onshelfholds => 2, + rules => { + issuelength => 7, + lengthunit => 8, + reservesallowed => 99, + onshelfholds => 2, + } } ); -$rule->store(); my $is = IsAvailableForItemLevelRequest( $item1, $borrower1); is( $is, 0, "Item cannot be held, 2 items available" ); diff --git a/t/db_dependent/Koha/IssuingRules.t b/t/db_dependent/Koha/IssuingRules.t index 2285be1..f9bfcd5 100644 --- a/t/db_dependent/Koha/IssuingRules.t +++ b/t/db_dependent/Koha/IssuingRules.t @@ -23,7 +23,7 @@ use Test::More tests => 1; use Benchmark; -use Koha::IssuingRules; +use Koha::CirculationRules; use t::lib::TestBuilder; @@ -46,26 +46,29 @@ subtest 'get_effective_issuing_rule' => sub { plan tests => 4; my $rule; - Koha::IssuingRules->delete; + Koha::CirculationRules->delete; - is(Koha::IssuingRules->search->count, 0, 'There are no issuing rules.'); - $rule = Koha::IssuingRules->get_effective_issuing_rule({ + is(Koha::CirculationRules->search->count, 0, 'There are no issuing rules.'); + $rule = Koha::CirculationRules->get_effective_rule({ branchcode => undef, categorycode => undef, itemtype => undef, + rule_name => 'fine', }); is($rule, undef, 'When I attempt to get effective issuing rule by' .' providing undefined values, then undef is returned.'); - ok(Koha::IssuingRule->new({ + ok(Koha::CirculationRule->new({ branchcode => '*', categorycode => '*', itemtype => '*', + rule_name => 'fine', })->store, 'Given I added an issuing rule branchcode => *,' .' categorycode => *, itemtype => *,'); - $rule = Koha::IssuingRules->get_effective_issuing_rule({ - branchcode => undef, - categorycode => undef, - itemtype => undef, + $rule = Koha::CirculationRules->get_effective_rule({ + branchcode => '*', + categorycode => '*', + itemtype => '*', + rule_name => 'fine', }); ok(_row_match($rule, '*', '*', '*'), 'When I attempt to get effective' .' issuing rule by providing undefined values, then the above one is' @@ -76,116 +79,133 @@ subtest 'get_effective_issuing_rule' => sub { plan tests => 18; my $rule; - Koha::IssuingRules->delete; - is(Koha::IssuingRules->search->count, 0, 'There are no issuing rules.'); - $rule = Koha::IssuingRules->get_effective_issuing_rule({ + Koha::CirculationRules->delete; + is(Koha::CirculationRules->search->count, 0, 'There are no issuing rules.'); + $rule = Koha::CirculationRules->get_effective_rule({ branchcode => $branchcode, categorycode => $categorycode, itemtype => $itemtype, + rule_name => 'fine', }); is($rule, undef, 'When I attempt to get effective issuing rule, then undef' .' is returned.'); - ok(Koha::IssuingRule->new({ + ok(Koha::CirculationRule->new({ branchcode => '*', categorycode => '*', itemtype => '*', + rule_name => 'fine', })->store, 'Given I added an issuing rule branchcode => *, categorycode => *, itemtype => *,'); - $rule = Koha::IssuingRules->get_effective_issuing_rule({ + $rule = Koha::CirculationRules->get_effective_rule({ branchcode => $branchcode, categorycode => $categorycode, itemtype => $itemtype, + rule_name => 'fine', }); ok(_row_match($rule, '*', '*', '*'), 'When I attempt to get effective issuing rule,' .' then the above one is returned.'); - ok(Koha::IssuingRule->new({ + ok(Koha::CirculationRule->new({ branchcode => '*', categorycode => '*', itemtype => $itemtype, + rule_name => 'fine', })->store, "Given I added an issuing rule branchcode => *, categorycode => *, itemtype => $itemtype,"); - $rule = Koha::IssuingRules->get_effective_issuing_rule({ + $rule = Koha::CirculationRules->get_effective_rule({ branchcode => $branchcode, categorycode => $categorycode, itemtype => $itemtype, + rule_name => 'fine', }); ok(_row_match($rule, '*', '*', $itemtype), 'When I attempt to get effective issuing rule,' .' then the above one is returned.'); - ok(Koha::IssuingRule->new({ + ok(Koha::CirculationRule->new({ branchcode => '*', categorycode => $categorycode, itemtype => '*', + rule_name => 'fine', })->store, "Given I added an issuing rule branchcode => *, categorycode => $categorycode, itemtype => *,"); - $rule = Koha::IssuingRules->get_effective_issuing_rule({ + $rule = Koha::CirculationRules->get_effective_rule({ branchcode => $branchcode, categorycode => $categorycode, itemtype => $itemtype, + rule_name => 'fine', }); ok(_row_match($rule, '*', $categorycode, '*'), 'When I attempt to get effective issuing rule,' .' then the above one is returned.'); - ok(Koha::IssuingRule->new({ + ok(Koha::CirculationRule->new({ branchcode => '*', categorycode => $categorycode, itemtype => $itemtype, + rule_name => 'fine', })->store, "Given I added an issuing rule branchcode => *, categorycode => $categorycode, itemtype => $itemtype,"); - $rule = Koha::IssuingRules->get_effective_issuing_rule({ + $rule = Koha::CirculationRules->get_effective_rule({ branchcode => $branchcode, categorycode => $categorycode, itemtype => $itemtype, + rule_name => 'fine', }); ok(_row_match($rule, '*', $categorycode, $itemtype), 'When I attempt to get effective issuing rule,' .' then the above one is returned.'); - ok(Koha::IssuingRule->new({ + ok(Koha::CirculationRule->new({ branchcode => $branchcode, categorycode => '*', itemtype => '*', + rule_name => 'fine', })->store, "Given I added an issuing rule branchcode => $branchcode, categorycode => '*', itemtype => '*',"); - $rule = Koha::IssuingRules->get_effective_issuing_rule({ + $rule = Koha::CirculationRules->get_effective_rule({ branchcode => $branchcode, categorycode => $categorycode, itemtype => $itemtype, + rule_name => 'fine', }); ok(_row_match($rule, $branchcode, '*', '*'), 'When I attempt to get effective issuing rule,' .' then the above one is returned.'); - ok(Koha::IssuingRule->new({ + ok(Koha::CirculationRule->new({ branchcode => $branchcode, categorycode => '*', itemtype => $itemtype, + rule_name => 'fine', })->store, "Given I added an issuing rule branchcode => $branchcode, categorycode => '*', itemtype => $itemtype,"); - $rule = Koha::IssuingRules->get_effective_issuing_rule({ + $rule = Koha::CirculationRules->get_effective_rule({ branchcode => $branchcode, categorycode => $categorycode, itemtype => $itemtype, + rule_name => 'fine', }); ok(_row_match($rule, $branchcode, '*', $itemtype), 'When I attempt to get effective issuing rule,' .' then the above one is returned.'); - ok(Koha::IssuingRule->new({ + ok(Koha::CirculationRule->new({ branchcode => $branchcode, categorycode => $categorycode, itemtype => '*', + rule_name => 'fine', })->store, "Given I added an issuing rule branchcode => $branchcode, categorycode => $categorycode, itemtype => '*',"); - $rule = Koha::IssuingRules->get_effective_issuing_rule({ + $rule = Koha::CirculationRules->get_effective_rule({ branchcode => $branchcode, categorycode => $categorycode, itemtype => $itemtype, + rule_name => 'fine', }); ok(_row_match($rule, $branchcode, $categorycode, '*'), 'When I attempt to get effective issuing rule,' .' then the above one is returned.'); - ok(Koha::IssuingRule->new({ + ok(Koha::CirculationRule->new({ branchcode => $branchcode, categorycode => $categorycode, itemtype => $itemtype, + rule_name => 'fine', })->store, "Given I added an issuing rule branchcode => $branchcode, categorycode => $categorycode, itemtype => $itemtype,"); - $rule = Koha::IssuingRules->get_effective_issuing_rule({ + $rule = Koha::CirculationRules->get_effective_rule({ branchcode => $branchcode, categorycode => $categorycode, itemtype => $itemtype, + rule_name => 'fine', }); ok(_row_match($rule, $branchcode, $categorycode, $itemtype), 'When I attempt to get effective issuing rule,' .' then the above one is returned.'); @@ -195,34 +215,38 @@ subtest 'get_effective_issuing_rule' => sub { plan tests => 4; my $worst_case = timethis(500, - sub { Koha::IssuingRules->get_effective_issuing_rule({ + sub { Koha::CirculationRules->get_effective_rule({ branchcode => 'nonexistent', categorycode => 'nonexistent', itemtype => 'nonexistent', + rule_name => 'nonexistent', }); } ); my $mid_case = timethis(500, - sub { Koha::IssuingRules->get_effective_issuing_rule({ + sub { Koha::CirculationRules->get_effective_rule({ branchcode => $branchcode, categorycode => 'nonexistent', itemtype => 'nonexistent', + rule_name => 'nonexistent', }); } ); my $sec_best_case = timethis(500, - sub { Koha::IssuingRules->get_effective_issuing_rule({ + sub { Koha::CirculationRules->get_effective_rule({ branchcode => $branchcode, categorycode => $categorycode, itemtype => 'nonexistent', + rule_name => 'nonexistent', }); } ); my $best_case = timethis(500, - sub { Koha::IssuingRules->get_effective_issuing_rule({ + sub { Koha::CirculationRules->get_effective_rule({ branchcode => $branchcode, categorycode => $categorycode, itemtype => $itemtype, + rule_name => 'nonexistent', }); } ); diff --git a/t/db_dependent/Koha/Objects.t b/t/db_dependent/Koha/Objects.t index f5f9472..47f24da 100644 --- a/t/db_dependent/Koha/Objects.t +++ b/t/db_dependent/Koha/Objects.t @@ -24,7 +24,6 @@ use Test::Warn; use Koha::Authority::Types; use Koha::Cities; -use Koha::IssuingRules; use Koha::Patron::Category; use Koha::Patron::Categories; use Koha::Patrons; @@ -116,7 +115,7 @@ subtest 'new' => sub { }; subtest 'find' => sub { - plan tests => 5; + plan tests => 4; # check find on a single PK my $patron = $builder->build({ source => 'Borrower' }); @@ -134,12 +133,6 @@ subtest 'find' => sub { { where => { surname => { '!=', $patron->{surname} }}}, ), undef, 'Additional where clause in find call' ); - # check find with a composite FK - my $rule = $builder->build({ source => 'Issuingrule' }); - my @pk = ( $rule->{branchcode}, $rule->{categorycode}, $rule->{itemtype} ); - is( ref(Koha::IssuingRules->find(@pk)), "Koha::IssuingRule", - 'Find returned a Koha object for composite primary key' ); - is( Koha::Patrons->find(), undef, 'Find returns undef if no params passed' ); }; diff --git a/t/db_dependent/Reserves.t b/t/db_dependent/Reserves.t index c961069..424809c 100755 --- a/t/db_dependent/Reserves.t +++ b/t/db_dependent/Reserves.t @@ -199,12 +199,17 @@ $requesters{$branch_3} = AddMember( # to request its items, while $branch_2 will allow its items # to fill holds from anywhere. -$dbh->do('DELETE FROM issuingrules'); -$dbh->do( - q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed) - VALUES (?, ?, ?, ?)}, - {}, - '*', '*', '*', 25 +$dbh->do('DELETE FROM circulation_rules'); +Koha::CirculationRules->set_rules( + { + branchcode => '*', + categorycode => '*', + itemtype => '*', + rules => { + reservesallowed => 25, + holds_per_record => 1, + } + } ); # CPL allows only its own patrons to request its items @@ -565,24 +570,27 @@ ok( C4::Reserves::IsAvailableForItemLevelRequest($item, $borrower), "Reserving a my $itype = C4::Reserves::_get_itype($item); my $categorycode = $borrower->{categorycode}; my $holdingbranch = $item->{holdingbranch}; -my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule( +Koha::CirculationRules->set_rules( { categorycode => $categorycode, itemtype => $itype, - branchcode => $holdingbranch + branchcode => $holdingbranch, + rules => { + onshelfholds => 1, + } } ); -$dbh->do( - "UPDATE issuingrules SET onshelfholds = 1 WHERE categorycode = ? AND itemtype= ? and branchcode = ?", - undef, - $issuing_rule->categorycode, $issuing_rule->itemtype, $issuing_rule->branchcode -); ok( C4::Reserves::OnShelfHoldsAllowed($item, $borrower), "OnShelfHoldsAllowed() allowed" ); -$dbh->do( - "UPDATE issuingrules SET onshelfholds = 0 WHERE categorycode = ? AND itemtype= ? and branchcode = ?", - undef, - $issuing_rule->categorycode, $issuing_rule->itemtype, $issuing_rule->branchcode +Koha::CirculationRules->set_rules( + { + categorycode => $categorycode, + itemtype => $itype, + branchcode => $holdingbranch, + rules => { + onshelfholds => 0, + } + } ); ok( !C4::Reserves::OnShelfHoldsAllowed($item, $borrower), "OnShelfHoldsAllowed() disallowed" ); diff --git a/t/db_dependent/Reserves/MultiplePerRecord.t b/t/db_dependent/Reserves/MultiplePerRecord.t index 293ab6a..bb6aeab 100755 --- a/t/db_dependent/Reserves/MultiplePerRecord.t +++ b/t/db_dependent/Reserves/MultiplePerRecord.t @@ -115,19 +115,20 @@ my $item3 = $builder->build( } ); -my $rules_rs = Koha::Database->new()->schema()->resultset('Issuingrule'); -$rules_rs->delete(); +Koha::CirculationRules->delete(); # Test GetMaxPatronHoldsForRecord and GetHoldRule -my $rule1 = $rules_rs->new( +Koha::CirculationRules->set_rules( { - categorycode => '*', - itemtype => '*', - branchcode => '*', - reservesallowed => 1, - holds_per_record => 1, + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + reservesallowed => 1, + holds_per_record => 1, + } } -)->insert(); +); t::lib::Mocks::mock_preference('item-level_itypes', 1); # Assuming the item type is defined at item level @@ -144,15 +145,17 @@ is( $rule->{branchcode}, '*', 'Got rule with universal branchcode' ); is( $rule->{reservesallowed}, 1, 'Got reservesallowed of 1' ); is( $rule->{holds_per_record}, 1, 'Got holds_per_record of 1' ); -my $rule2 = $rules_rs->new( +Koha::CirculationRules->set_rules( { - categorycode => $category->{categorycode}, - itemtype => '*', - branchcode => '*', - reservesallowed => 2, - holds_per_record => 2, + categorycode => $category->{categorycode}, + itemtype => '*', + branchcode => '*', + rules => { + reservesallowed => 2, + holds_per_record => 2, + } } -)->insert(); +); $max = GetMaxPatronHoldsForRecord( $patron->{borrowernumber}, $biblio->{biblionumber} ); is( $max, 2, 'GetMaxPatronHoldsForRecord returns max of 2' ); @@ -167,15 +170,17 @@ is( $rule->{branchcode}, '*', 'Got rule with univers is( $rule->{reservesallowed}, 2, 'Got reservesallowed of 2' ); is( $rule->{holds_per_record}, 2, 'Got holds_per_record of 2' ); -my $rule3 = $rules_rs->new( +Koha::CirculationRules->set_rules( { - categorycode => $category->{categorycode}, - itemtype => $itemtype1->{itemtype}, - branchcode => '*', - reservesallowed => 3, - holds_per_record => 3, + categorycode => $category->{categorycode}, + itemtype => $itemtype1->{itemtype}, + branchcode => '*', + rules => { + reservesallowed => 3, + holds_per_record => 3, + } } -)->insert(); +); $max = GetMaxPatronHoldsForRecord( $patron->{borrowernumber}, $biblio->{biblionumber} ); is( $max, 3, 'GetMaxPatronHoldsForRecord returns max of 3' ); @@ -190,15 +195,17 @@ is( $rule->{branchcode}, '*', 'Got rule with univers is( $rule->{reservesallowed}, 3, 'Got reservesallowed of 3' ); is( $rule->{holds_per_record}, 3, 'Got holds_per_record of 3' ); -my $rule4 = $rules_rs->new( +Koha::CirculationRules->set_rules( { - categorycode => $category->{categorycode}, - itemtype => $itemtype2->{itemtype}, - branchcode => '*', - reservesallowed => 4, - holds_per_record => 4, + categorycode => $category->{categorycode}, + itemtype => $itemtype2->{itemtype}, + branchcode => '*', + rules => { + reservesallowed => 4, + holds_per_record => 4, + } } -)->insert(); +); $max = GetMaxPatronHoldsForRecord( $patron->{borrowernumber}, $biblio->{biblionumber} ); is( $max, 4, 'GetMaxPatronHoldsForRecord returns max of 4' ); @@ -213,15 +220,17 @@ is( $rule->{branchcode}, '*', 'Got rule with univers is( $rule->{reservesallowed}, 4, 'Got reservesallowed of 4' ); is( $rule->{holds_per_record}, 4, 'Got holds_per_record of 4' ); -my $rule5 = $rules_rs->new( +Koha::CirculationRules->set_rules( { - categorycode => $category->{categorycode}, - itemtype => $itemtype2->{itemtype}, - branchcode => $library->{branchcode}, - reservesallowed => 5, - holds_per_record => 5, + categorycode => $category->{categorycode}, + itemtype => $itemtype2->{itemtype}, + branchcode => $library->{branchcode}, + rules => { + reservesallowed => 5, + holds_per_record => 5, + } } -)->insert(); +); $max = GetMaxPatronHoldsForRecord( $patron->{borrowernumber}, $biblio->{biblionumber} ); is( $max, 5, 'GetMaxPatronHoldsForRecord returns max of 1' ); @@ -236,11 +245,7 @@ is( $rule->{branchcode}, $library->{branchcode}, 'Got rule with specifi is( $rule->{reservesallowed}, 5, 'Got reservesallowed of 5' ); is( $rule->{holds_per_record}, 5, 'Got holds_per_record of 5' ); -$rule1->delete(); -$rule2->delete(); -$rule3->delete(); -$rule4->delete(); -$rule5->delete(); +Koha::CirculationRules->delete(); my $holds = Koha::Holds->search( { borrowernumber => $patron->{borrowernumber} } ); is( $holds->forced_hold_level, undef, "No holds does not force an item or record level hold" ); @@ -266,15 +271,17 @@ is( $holds->forced_hold_level, 'item', "Item level hold forces item level holds" $hold->delete(); # Test multi-hold via AddReserve -$rule = $rules_rs->new( +Koha::CirculationRules->set_rules( { - categorycode => '*', - itemtype => '*', - branchcode => '*', - reservesallowed => 2, - holds_per_record => 2, + categorycode => '*', + itemtype => '*', + branchcode => '*', + rules => { + reservesallowed => 2, + holds_per_record => 2, + } } -)->insert(); +); my $can = CanBookBeReserved($patron->{borrowernumber}, $biblio->{biblionumber}); is( $can, 'OK', 'Hold can be placed with 0 holds' ); diff --git a/t/db_dependent/TestBuilder.t b/t/db_dependent/TestBuilder.t index 03f58eb..9ed580e 100644 --- a/t/db_dependent/TestBuilder.t +++ b/t/db_dependent/TestBuilder.t @@ -354,7 +354,7 @@ subtest 'build_object() tests' => sub { my $itemtype = $builder->build( { source => 'Itemtype' } )->{itemtype}; my $issuing_rule = $builder->build_object( - { class => 'Koha::IssuingRules', + { class => 'Koha::CirculationRules', value => { categorycode => $categorycode, itemtype => $itemtype @@ -362,7 +362,7 @@ subtest 'build_object() tests' => sub { } ); - is( ref($issuing_rule), 'Koha::IssuingRule', 'Type is correct' ); + is( ref($issuing_rule), 'Koha::CirculationRule', 'Type is correct' ); is( $issuing_rule->categorycode, $categorycode, 'Category code correctly set' ); is( $issuing_rule->itemtype, $itemtype, 'Item type correctly set' ); diff --git a/t/db_dependent/api/v1/holds.t b/t/db_dependent/api/v1/holds.t index d1f7978..9c9ce94 100644 --- a/t/db_dependent/api/v1/holds.t +++ b/t/db_dependent/api/v1/holds.t @@ -32,6 +32,7 @@ use Koha::Biblios; use Koha::Biblioitems; use Koha::Items; use Koha::Patrons; +use Koha::CirculationRules; my $schema = Koha::Database->new->schema; my $builder = t::lib::TestBuilder->new(); @@ -120,11 +121,17 @@ my $itemnumber2 = create_item($biblionumber2, 'TEST000002'); my $dbh = C4::Context->dbh; $dbh->do('DELETE FROM reserves'); -$dbh->do('DELETE FROM issuingrules'); - $dbh->do(q{ - INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed) - VALUES (?, ?, ?, ?) - }, {}, '*', '*', '*', 1); +$dbh->do('DELETE FROM circulation_rules'); +Koha::CirculationRules->set_rules( + { + categorycode => '*', + branchcode => '*', + itemtype => '*', + rules => { + reservesallowed => 1 + } + } +); my $reserve_id = C4::Reserves::AddReserve($branchcode, $borrowernumber, $biblionumber, undef, 1, undef, undef, undef, '', $itemnumber); -- 2.10.2