From 62676b7ca26066714df731b4d78488be5ca235b9 Mon Sep 17 00:00:00 2001 From: Alex Arnaud Date: Wed, 28 Jun 2017 13:50:20 +0000 Subject: [PATCH] Bug 8137: Add Default checkout limit by patron category with priority. This patch add the ability to make a 'Default checkout limit by patron category' rule has priority. When a rule has priority, it overrides all others for the same categorycode. For "normal" rule, the behavior is the same than before (like a default rule if no one is specified at branch level). Rule with priority can only be created on the circulation and fine rules page for *all libraries*. The goal is to allow librarian to limit the total number of checkouts by patron category for all libraries. test plan: - Create a rule with 4 checkouts allowed in default checkout limit table for a patron category and make it has priority, - create more permissive rules for all other branches (at least 5 checkouts allowed), - Checkout items of different branches for a patron with the same category, - Patron should be limited to 4 checkouts https://bugs.koha-community.org/show_bug.cgi?id=8137 Rebased: 2018-03-14, by: Alex Arnaud Rebased: 2020-07-23, by: Arthur Suzuki Signed-off-by: Andrew Fuerste-Henry Signed-off-by: Kyle M Hall --- admin/smart-rules.pl | 6 + .../Bug_8137-add-column-has_priority.sql | 5 + .../prog/en/modules/admin/smart-rules.tt | 129 ++++++++++++++++++ t/db_dependent/Circulation/Branch.t | 24 ++++ 4 files changed, 164 insertions(+) create mode 100644 installer/data/mysql/atomicupdate/Bug_8137-add-column-has_priority.sql diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl index b74a0ceeab..345904ae45 100755 --- a/admin/smart-rules.pl +++ b/admin/smart-rules.pl @@ -417,6 +417,8 @@ elsif ($op eq "add-branch-cat") { $patron_maxonsiteissueqty = strip_non_numeric($patron_maxonsiteissueqty); my $max_holds = $input->param('max_holds'); $max_holds = strip_non_numeric($max_holds); + my $has_priority = $input->param('has_priority'); + $has_priority = $has_priority ? 1 : 0; if ($branch eq "*") { if ($categorycode eq "*") { @@ -432,6 +434,7 @@ elsif ($op eq "add-branch-cat") { } ); } else { + Koha::CirculationRules->set_rules( { categorycode => $categorycode, @@ -440,6 +443,7 @@ elsif ($op eq "add-branch-cat") { max_holds => $max_holds, patron_maxissueqty => $patron_maxissueqty, patron_maxonsiteissueqty => $patron_maxonsiteissueqty, + has_priority => $has_priority, } } ); @@ -453,6 +457,7 @@ elsif ($op eq "add-branch-cat") { max_holds => $max_holds, patron_maxissueqty => $patron_maxissueqty, patron_maxonsiteissueqty => $patron_maxonsiteissueqty, + has_priority => $has_priority, } } ); @@ -465,6 +470,7 @@ elsif ($op eq "add-branch-cat") { max_holds => $max_holds, patron_maxissueqty => $patron_maxissueqty, patron_maxonsiteissueqty => $patron_maxonsiteissueqty, + has_priority => $has_priority, } } ); diff --git a/installer/data/mysql/atomicupdate/Bug_8137-add-column-has_priority.sql b/installer/data/mysql/atomicupdate/Bug_8137-add-column-has_priority.sql new file mode 100644 index 0000000000..fc7c42fcc0 --- /dev/null +++ b/installer/data/mysql/atomicupdate/Bug_8137-add-column-has_priority.sql @@ -0,0 +1,5 @@ +ALTER TABLE default_borrower_circ_rules ADD has_priority INT(1) DEFAULT 0; +ALTER TABLE default_borrower_circ_rules DROP foreign key borrower_borrower_circ_rules_ibfk_1; +ALTER TABLE default_borrower_circ_rules DROP primary key; +ALTER TABLE default_borrower_circ_rules ADD primary key(categorycode, has_priority); +ALTER TABLE default_borrower_circ_rules ADD CONSTRAINT borrower_borrower_circ_rules_ibfk_1 FOREIGN KEY (categorycode) REFERENCES categories (categorycode) ON DELETE CASCADE ON UPDATE CASCADE; \ No newline at end of file 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 2fba8747e4..2057ed62ef 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 @@ -1288,6 +1288,135 @@ [% SET holdallowed = CirculationRules.Search( branchcode, undef, i.itemtype, 'holdallowed' ) %] [% SET hold_fulfillment_policy = CirculationRules.Search( branchcode, undef, i.itemtype, 'hold_fulfillment_policy' ) %] [% SET returnbranch = CirculationRules.Search( branchcode, undef, i.itemtype, 'returnbranch' ) %] + + + + + + + Unset + + + + + + [% IF ( show_branch_cat_rule_form ) %] +
+

[% IF humanbranch %]Checkout, hold policy by patron category for [% Branches.GetName( humanbranch ) | html %][% ELSE %]Default checkout, hold policy by patron category[% END %]

+

For this library, you can specify the maximum number of loans that + a patron of a given category can make, regardless of the item type. +

+

If the total amount loanable for a given patron category is left blank, + no limit applies, except possibly for a limit you define for a specific item type. +

+

+ Has priority: If checked, the rule will override those for all branches. Else + it behaves like a default one: used if no rule existe for the coresponding branch. +

+
+ + + + + + + + + [% UNLESS humanbranch %][% END %] + + + [% FOREACH c IN categorycodes %] + [% NEXT UNLESS c %] + [% SET patron_maxissueqty = CirculationRules.Search( branchcode, c, undef, 'patron_maxissueqty' ) %] + [% SET patron_maxonsiteissueqty = CirculationRules.Search( branchcode, c, undef, 'patron_maxonsiteissueqty' ) %] + [% SET max_holds = CirculationRules.Search( branchcode, c, undef, 'max_holds' ) %] + + [% IF ( patron_maxissueqty.defined && patron_maxissueqty != '' ) || ( patron_maxonsiteissueqty.defined && patron_maxonsiteissueqty != '' ) || ( max_holds.defined && max_holds != '' ) %] + + + + + + [% UNLESS humanbranch %] + + [% END %] + + + + [% END %] + [% END %] + + + + + + [% UNLESS humanbranch %] + + [% END %] + + +
Patron categoryTotal current checkouts allowedTotal current on-site checkouts allowedTotal holds allowedHas priority 
+ [% IF c == undef %] + Default + [% ELSE %] + [% Categories.GetName(c) | html %] + [% END %] + + [% IF patron_maxissueqty.defined && patron_maxissueqty != '' %] + [% patron_maxissueqty | html %] + [% ELSE %] + Unlimited + [% END %] + + [% IF patron_maxonsiteissueqty.defined && patron_maxonsiteissueqty != '' %] + [% patron_maxonsiteissueqty | html %] + [% ELSE %] + Unlimited + [% END %] + + [% IF max_holds.defined && max_holds != '' %] + [% max_holds | html %] + [% ELSE %] + Unlimited + [% END %] + + + + Delete +
+ + + +
+
+
+ [% END %] [% IF holdallowed || hold_fulfillment_policy || returnbranch %] diff --git a/t/db_dependent/Circulation/Branch.t b/t/db_dependent/Circulation/Branch.t index 53e26d2d6a..81ba4331f4 100755 --- a/t/db_dependent/Circulation/Branch.t +++ b/t/db_dependent/Circulation/Branch.t @@ -232,7 +232,15 @@ Koha::CirculationRules->set_rules( } ); +$query = q| + INSERT INTO default_borrower_circ_rules + (categorycode, maxissueqty, maxonsiteissueqty, has_priority) + VALUES( ?, ?, ?, ? ) +|; +$dbh->do($query, {}, $samplecat->{categorycode}, 3, 3, 0); + #Test GetBranchBorrowerCircRule +# is_deeply( GetBranchBorrowerCircRule(), { patron_maxissueqty => 4, patron_maxonsiteissueqty => 5 }, @@ -257,6 +265,22 @@ is_deeply( "GetBranchBorrower with wrong parameters returns the patron_maxissueqty and patron_maxonsiteissueqty of default_circ_rules" ); +$query = q| + INSERT INTO default_borrower_circ_rules + (categorycode, maxissueqty, maxonsiteissueqty, has_priority) + VALUES( ?, ?, ?, ? ) +|; +$dbh->do($query, {}, $samplecat->{categorycode}, 3, 3, 1); + +is_deeply( + GetBranchBorrowerCircRule( + $samplebranch1->{branchcode}, + $samplecat->{categorycode} + ), + { maxissueqty => 3, maxonsiteissueqty => 3, has_priority => 1 }, + "GetBranchBorrower returns the rule having priority" +); + #Test GetBranchItemRule my @lazy_any = ( 'hold_fulfillment_policy' => 'any' ); is_deeply( -- 2.25.1