Increment version for 3.22.21
[koha.git] / admin / smart-rules.pl
1 #!/usr/bin/perl
2 # Copyright 2000-2002 Katipo Communications
3 # copyright 2010 BibLibre
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20 use strict;
21 use warnings;
22 use CGI qw ( -utf8 );
23 use C4::Context;
24 use C4::Output;
25 use C4::Auth;
26 use C4::Koha;
27 use C4::Debug;
28 use C4::Branch; # GetBranches
29 use Koha::DateUtils;
30 use Koha::Database;
31
32 my $input = CGI->new;
33 my $dbh = C4::Context->dbh;
34
35 # my $flagsrequired;
36 # $flagsrequired->{circulation}=1;
37 my ($template, $loggedinuser, $cookie)
38     = get_template_and_user({template_name => "admin/smart-rules.tt",
39                             query => $input,
40                             type => "intranet",
41                             authnotrequired => 0,
42                             flagsrequired => {parameters => 'manage_circ_rules'},
43                             debug => 1,
44                             });
45
46 my $type=$input->param('type');
47 my $branch = $input->param('branch') || ( C4::Branch::onlymine() ? ( C4::Branch::mybranch() || '*' ) : '*' );
48 my $op = $input->param('op') || q{};
49 my $language = C4::Languages::getlanguage();
50
51 if ($op eq 'delete') {
52     my $itemtype     = $input->param('itemtype');
53     my $categorycode = $input->param('categorycode');
54     $debug and warn "deleting $1 $2 $branch";
55
56     my $sth_Idelete = $dbh->prepare("delete from issuingrules where branchcode=? and categorycode=? and itemtype=?");
57     $sth_Idelete->execute($branch, $categorycode, $itemtype);
58 }
59 elsif ($op eq 'delete-branch-cat') {
60     my $categorycode  = $input->param('categorycode');
61     if ($branch eq "*") {
62         if ($categorycode eq "*") {
63             my $sth_delete = $dbh->prepare("DELETE FROM default_circ_rules");
64             $sth_delete->execute();
65         } else {
66             my $sth_delete = $dbh->prepare("DELETE FROM default_borrower_circ_rules
67                                             WHERE categorycode = ?");
68             $sth_delete->execute($categorycode);
69         }
70     } elsif ($categorycode eq "*") {
71         my $sth_delete = $dbh->prepare("DELETE FROM default_branch_circ_rules
72                                         WHERE branchcode = ?");
73         $sth_delete->execute($branch);
74     } else {
75         my $sth_delete = $dbh->prepare("DELETE FROM branch_borrower_circ_rules
76                                         WHERE branchcode = ?
77                                         AND categorycode = ?");
78         $sth_delete->execute($branch, $categorycode);
79     }
80 }
81 elsif ($op eq 'delete-branch-item') {
82     my $itemtype  = $input->param('itemtype');
83     if ($branch eq "*") {
84         if ($itemtype eq "*") {
85             my $sth_delete = $dbh->prepare("DELETE FROM default_circ_rules");
86             $sth_delete->execute();
87         } else {
88             my $sth_delete = $dbh->prepare("DELETE FROM default_branch_item_rules
89                                             WHERE itemtype = ?");
90             $sth_delete->execute($itemtype);
91         }
92     } elsif ($itemtype eq "*") {
93         my $sth_delete = $dbh->prepare("DELETE FROM default_branch_circ_rules
94                                         WHERE branchcode = ?");
95         $sth_delete->execute($branch);
96     } else {
97         my $sth_delete = $dbh->prepare("DELETE FROM branch_item_rules
98                                         WHERE branchcode = ?
99                                         AND itemtype = ?");
100         $sth_delete->execute($branch, $itemtype);
101     }
102 }
103 # save the values entered
104 elsif ($op eq 'add') {
105     my $br = $branch; # branch
106     my $bor  = $input->param('categorycode'); # borrower category
107     my $itemtype  = $input->param('itemtype');     # item type
108     my $fine = $input->param('fine');
109     my $finedays     = $input->param('finedays');
110     my $maxsuspensiondays = $input->param('maxsuspensiondays');
111     $maxsuspensiondays = undef if $maxsuspensiondays eq q||;
112     my $firstremind  = $input->param('firstremind');
113     my $chargeperiod = $input->param('chargeperiod');
114     my $chargeperiod_charge_at = $input->param('chargeperiod_charge_at');
115     my $maxissueqty  = $input->param('maxissueqty');
116     my $maxonsiteissueqty  = $input->param('maxonsiteissueqty');
117     my $renewalsallowed  = $input->param('renewalsallowed');
118     my $renewalperiod    = $input->param('renewalperiod');
119     my $norenewalbefore  = $input->param('norenewalbefore');
120     $norenewalbefore = undef if $norenewalbefore =~ /^\s*$/;
121     my $auto_renew = $input->param('auto_renew') eq 'yes' ? 1 : 0;
122     my $reservesallowed  = $input->param('reservesallowed');
123     my $onshelfholds     = $input->param('onshelfholds') || 0;
124     $maxissueqty =~ s/\s//g;
125     $maxissueqty = undef if $maxissueqty !~ /^\d+/;
126     $maxonsiteissueqty =~ s/\s//g;
127     $maxonsiteissueqty = undef if $maxonsiteissueqty !~ /^\d+/;
128     my $issuelength  = $input->param('issuelength');
129     $issuelength = $issuelength eq q{} ? undef : $issuelength;
130     my $lengthunit  = $input->param('lengthunit');
131     my $hardduedate = $input->param('hardduedate') || undef;
132     $hardduedate = eval { dt_from_string( $input->param('hardduedate') ) } if ( $hardduedate );
133     $hardduedate = output_pref( { dt => $hardduedate, dateonly => 1, dateformat => 'iso' } ) if ( $hardduedate );
134     my $hardduedatecompare = $input->param('hardduedatecompare');
135     my $rentaldiscount = $input->param('rentaldiscount');
136     my $opacitemholds = $input->param('opacitemholds') || 0;
137     my $overduefinescap = $input->param('overduefinescap') || undef;
138     $debug and warn "Adding $br, $bor, $itemtype, $fine, $maxissueqty, $maxonsiteissueqty";
139
140     my $schema = Koha::Database->new()->schema();
141     my $rs = $schema->resultset('Issuingrule');
142
143     my $params = {
144         branchcode             => $br,
145         categorycode           => $bor,
146         itemtype               => $itemtype,
147         fine                   => $fine,
148         finedays               => $finedays,
149         maxsuspensiondays      => $maxsuspensiondays,
150         firstremind            => $firstremind,
151         chargeperiod           => $chargeperiod,
152         chargeperiod_charge_at => $chargeperiod_charge_at,
153         maxissueqty            => $maxissueqty,
154         maxonsiteissueqty      => $maxonsiteissueqty,
155         renewalsallowed        => $renewalsallowed,
156         renewalperiod          => $renewalperiod,
157         norenewalbefore        => $norenewalbefore,
158         auto_renew             => $auto_renew,
159         reservesallowed        => $reservesallowed,
160         issuelength            => $issuelength,
161         lengthunit             => $lengthunit,
162         hardduedate            => $hardduedate,
163         hardduedatecompare     => $hardduedatecompare,
164         rentaldiscount         => $rentaldiscount,
165         onshelfholds           => $onshelfholds,
166         opacitemholds          => $opacitemholds,
167         overduefinescap        => $overduefinescap,
168     };
169
170     $rs->update_or_create($params);
171
172 }
173 elsif ($op eq "set-branch-defaults") {
174     my $categorycode  = $input->param('categorycode');
175     my $maxissueqty   = $input->param('maxissueqty');
176     my $maxonsiteissueqty = $input->param('maxonsiteissueqty');
177     my $holdallowed   = $input->param('holdallowed');
178     my $returnbranch  = $input->param('returnbranch');
179     $maxissueqty =~ s/\s//g;
180     $maxissueqty = undef if $maxissueqty !~ /^\d+/;
181     $maxonsiteissueqty =~ s/\s//g;
182     $maxonsiteissueqty = undef if $maxonsiteissueqty !~ /^\d+/;
183     $holdallowed =~ s/\s//g;
184     $holdallowed = undef if $holdallowed !~ /^\d+/;
185
186     if ($branch eq "*") {
187         my $sth_search = $dbh->prepare("SELECT count(*) AS total
188                                         FROM default_circ_rules");
189         my $sth_insert = $dbh->prepare("INSERT INTO default_circ_rules
190                                         (maxissueqty, maxonsiteissueqty, holdallowed, returnbranch)
191                                         VALUES (?, ?, ?, ?)");
192         my $sth_update = $dbh->prepare("UPDATE default_circ_rules
193                                         SET maxissueqty = ?, maxonsiteissueqty = ?, holdallowed = ?, returnbranch = ?");
194
195         $sth_search->execute();
196         my $res = $sth_search->fetchrow_hashref();
197         if ($res->{total}) {
198             $sth_update->execute($maxissueqty, $maxonsiteissueqty, $holdallowed, $returnbranch);
199         } else {
200             $sth_insert->execute($maxissueqty, $maxonsiteissueqty, $holdallowed, $returnbranch);
201         }
202     } else {
203         my $sth_search = $dbh->prepare("SELECT count(*) AS total
204                                         FROM default_branch_circ_rules
205                                         WHERE branchcode = ?");
206         my $sth_insert = $dbh->prepare("INSERT INTO default_branch_circ_rules
207                                         (branchcode, maxissueqty, maxonsiteissueqty, holdallowed, returnbranch)
208                                         VALUES (?, ?, ?, ?, ?)");
209         my $sth_update = $dbh->prepare("UPDATE default_branch_circ_rules
210                                         SET maxissueqty = ?, maxonsiteissueqty = ?, holdallowed = ?, returnbranch = ?
211                                         WHERE branchcode = ?");
212         $sth_search->execute($branch);
213         my $res = $sth_search->fetchrow_hashref();
214         if ($res->{total}) {
215             $sth_update->execute($maxissueqty, $maxonsiteissueqty, $holdallowed, $returnbranch, $branch);
216         } else {
217             $sth_insert->execute($branch, $maxissueqty, $maxonsiteissueqty, $holdallowed, $returnbranch);
218         }
219     }
220 }
221 elsif ($op eq "add-branch-cat") {
222     my $categorycode  = $input->param('categorycode');
223     my $maxissueqty   = $input->param('maxissueqty');
224     my $maxonsiteissueqty = $input->param('maxonsiteissueqty');
225     $maxissueqty =~ s/\s//g;
226     $maxissueqty = undef if $maxissueqty !~ /^\d+/;
227     $maxonsiteissueqty =~ s/\s//g;
228     $maxonsiteissueqty = undef if $maxonsiteissueqty !~ /^\d+/;
229
230     if ($branch eq "*") {
231         if ($categorycode eq "*") {
232             my $sth_search = $dbh->prepare("SELECT count(*) AS total
233                                             FROM default_circ_rules");
234             my $sth_insert = $dbh->prepare(q|
235                 INSERT INTO default_circ_rules
236                     (maxissueqty, maxonsiteissueqty)
237                     VALUES (?, ?)
238             |);
239             my $sth_update = $dbh->prepare(q|
240                 UPDATE default_circ_rules
241                 SET maxissueqty = ?,
242                     maxonsiteissueqty = ?
243             |);
244
245             $sth_search->execute();
246             my $res = $sth_search->fetchrow_hashref();
247             if ($res->{total}) {
248                 $sth_update->execute($maxissueqty, $maxonsiteissueqty);
249             } else {
250                 $sth_insert->execute($maxissueqty, $maxonsiteissueqty);
251             }
252         } else {
253             my $sth_search = $dbh->prepare("SELECT count(*) AS total
254                                             FROM default_borrower_circ_rules
255                                             WHERE categorycode = ?");
256             my $sth_insert = $dbh->prepare(q|
257                 INSERT INTO default_borrower_circ_rules
258                     (categorycode, maxissueqty, maxonsiteissueqty)
259                     VALUES (?, ?, ?)
260             |);
261             my $sth_update = $dbh->prepare(q|
262                 UPDATE default_borrower_circ_rules
263                 SET maxissueqty = ?,
264                     maxonsiteissueqty = ?
265                 WHERE categorycode = ?
266             |);
267             $sth_search->execute($branch);
268             my $res = $sth_search->fetchrow_hashref();
269             if ($res->{total}) {
270                 $sth_update->execute($maxissueqty, $maxonsiteissueqty, $categorycode);
271             } else {
272                 $sth_insert->execute($categorycode, $maxissueqty, $maxonsiteissueqty);
273             }
274         }
275     } elsif ($categorycode eq "*") {
276         my $sth_search = $dbh->prepare("SELECT count(*) AS total
277                                         FROM default_branch_circ_rules
278                                         WHERE branchcode = ?");
279         my $sth_insert = $dbh->prepare(q|
280             INSERT INTO default_branch_circ_rules
281             (branchcode, maxissueqty, maxonsiteissueqty)
282             VALUES (?, ?, ?)
283         |);
284         my $sth_update = $dbh->prepare(q|
285             UPDATE default_branch_circ_rules
286             SET maxissueqty = ?,
287                 maxonsiteissueqty = ?
288             WHERE branchcode = ?
289         |);
290         $sth_search->execute($branch);
291         my $res = $sth_search->fetchrow_hashref();
292         if ($res->{total}) {
293             $sth_update->execute($maxissueqty, $maxonsiteissueqty, $branch);
294         } else {
295             $sth_insert->execute($branch, $maxissueqty, $maxonsiteissueqty);
296         }
297     } else {
298         my $sth_search = $dbh->prepare("SELECT count(*) AS total
299                                         FROM branch_borrower_circ_rules
300                                         WHERE branchcode = ?
301                                         AND   categorycode = ?");
302         my $sth_insert = $dbh->prepare(q|
303             INSERT INTO branch_borrower_circ_rules
304             (branchcode, categorycode, maxissueqty, maxonsiteissueqty)
305             VALUES (?, ?, ?, ?)
306         |);
307         my $sth_update = $dbh->prepare(q|
308             UPDATE branch_borrower_circ_rules
309             SET maxissueqty = ?,
310                 maxonsiteissueqty = ?
311             WHERE branchcode = ?
312             AND categorycode = ?
313         |);
314
315         $sth_search->execute($branch, $categorycode);
316         my $res = $sth_search->fetchrow_hashref();
317         if ($res->{total}) {
318             $sth_update->execute($maxissueqty, $maxonsiteissueqty, $branch, $categorycode);
319         } else {
320             $sth_insert->execute($branch, $categorycode, $maxissueqty, $maxonsiteissueqty);
321         }
322     }
323 }
324 elsif ($op eq "add-branch-item") {
325     my $itemtype  = $input->param('itemtype');
326     my $holdallowed   = $input->param('holdallowed');
327     my $returnbranch  = $input->param('returnbranch');
328     $holdallowed =~ s/\s//g;
329     $holdallowed = undef if $holdallowed !~ /^\d+/;
330
331     if ($branch eq "*") {
332         if ($itemtype eq "*") {
333             my $sth_search = $dbh->prepare("SELECT count(*) AS total
334                                             FROM default_circ_rules");
335             my $sth_insert = $dbh->prepare("INSERT INTO default_circ_rules
336                                             (holdallowed, returnbranch)
337                                             VALUES (?, ?)");
338             my $sth_update = $dbh->prepare("UPDATE default_circ_rules
339                                             SET holdallowed = ?, returnbranch = ?");
340
341             $sth_search->execute();
342             my $res = $sth_search->fetchrow_hashref();
343             if ($res->{total}) {
344                 $sth_update->execute($holdallowed, $returnbranch);
345             } else {
346                 $sth_insert->execute($holdallowed, $returnbranch);
347             }
348         } else {
349             my $sth_search = $dbh->prepare("SELECT count(*) AS total
350                                             FROM default_branch_item_rules
351                                             WHERE itemtype = ?");
352             my $sth_insert = $dbh->prepare("INSERT INTO default_branch_item_rules
353                                             (itemtype, holdallowed, returnbranch)
354                                             VALUES (?, ?, ?)");
355             my $sth_update = $dbh->prepare("UPDATE default_branch_item_rules
356                                             SET holdallowed = ?, returnbranch = ?
357                                             WHERE itemtype = ?");
358             $sth_search->execute($itemtype);
359             my $res = $sth_search->fetchrow_hashref();
360             if ($res->{total}) {
361                 $sth_update->execute($holdallowed, $returnbranch, $itemtype);
362             } else {
363                 $sth_insert->execute($itemtype, $holdallowed, $returnbranch);
364             }
365         }
366     } elsif ($itemtype eq "*") {
367         my $sth_search = $dbh->prepare("SELECT count(*) AS total
368                                         FROM default_branch_circ_rules
369                                         WHERE branchcode = ?");
370         my $sth_insert = $dbh->prepare("INSERT INTO default_branch_circ_rules
371                                         (branchcode, holdallowed, returnbranch)
372                                         VALUES (?, ?, ?)");
373         my $sth_update = $dbh->prepare("UPDATE default_branch_circ_rules
374                                         SET holdallowed = ?, returnbranch = ?
375                                         WHERE branchcode = ?");
376         $sth_search->execute($branch);
377         my $res = $sth_search->fetchrow_hashref();
378         if ($res->{total}) {
379             $sth_update->execute($holdallowed, $returnbranch, $branch);
380         } else {
381             $sth_insert->execute($branch, $holdallowed, $returnbranch);
382         }
383     } else {
384         my $sth_search = $dbh->prepare("SELECT count(*) AS total
385                                         FROM branch_item_rules
386                                         WHERE branchcode = ?
387                                         AND   itemtype = ?");
388         my $sth_insert = $dbh->prepare("INSERT INTO branch_item_rules
389                                         (branchcode, itemtype, holdallowed, returnbranch)
390                                         VALUES (?, ?, ?, ?)");
391         my $sth_update = $dbh->prepare("UPDATE branch_item_rules
392                                         SET holdallowed = ?, returnbranch = ?
393                                         WHERE branchcode = ?
394                                         AND itemtype = ?");
395
396         $sth_search->execute($branch, $itemtype);
397         my $res = $sth_search->fetchrow_hashref();
398         if ($res->{total}) {
399             $sth_update->execute($holdallowed, $returnbranch, $branch, $itemtype);
400         } else {
401             $sth_insert->execute($branch, $itemtype, $holdallowed, $returnbranch);
402         }
403     }
404 }
405
406 my $branches = GetBranches();
407 my @branchloop;
408 for my $thisbranch (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %$branches) {
409     push @branchloop, {
410         value      => $thisbranch,
411         selected   => $thisbranch eq $branch,
412         branchname => $branches->{$thisbranch}->{'branchname'},
413     };
414 }
415
416 my $sth=$dbh->prepare("SELECT description,categorycode FROM categories ORDER BY description");
417 $sth->execute;
418 my @category_loop;
419 while (my $data=$sth->fetchrow_hashref){
420     push @category_loop,$data;
421 }
422
423 $sth->finish;
424 my @row_loop;
425 my @itemtypes = @{ GetItemTypes( style => 'array' ) };
426 @itemtypes = sort { lc $a->{translated_description} cmp lc $b->{translated_description} } @itemtypes;
427
428 my $sth2 = $dbh->prepare("
429     SELECT  issuingrules.*,
430             itemtypes.description AS humanitemtype,
431             categories.description AS humancategorycode,
432             COALESCE( localization.translation, itemtypes.description ) AS translated_description
433     FROM issuingrules
434     LEFT JOIN itemtypes
435         ON (itemtypes.itemtype = issuingrules.itemtype)
436     LEFT JOIN categories
437         ON (categories.categorycode = issuingrules.categorycode)
438     LEFT JOIN localization ON issuingrules.itemtype = localization.code
439         AND localization.entity = 'itemtypes'
440         AND localization.lang = ?
441     WHERE issuingrules.branchcode = ?
442 ");
443 $sth2->execute($language, $branch);
444
445 while (my $row = $sth2->fetchrow_hashref) {
446     $row->{'current_branch'} ||= $row->{'branchcode'};
447     $row->{humanitemtype} ||= $row->{itemtype};
448     $row->{default_translated_description} = 1 if $row->{humanitemtype} eq '*';
449     $row->{'humancategorycode'} ||= $row->{'categorycode'};
450     $row->{'default_humancategorycode'} = 1 if $row->{'humancategorycode'} eq '*';
451     $row->{'fine'} = sprintf('%.2f', $row->{'fine'});
452     if ($row->{'hardduedate'} && $row->{'hardduedate'} ne '0000-00-00') {
453        my $harddue_dt = eval { dt_from_string( $row->{'hardduedate'} ) };
454        $row->{'hardduedate'} = eval { output_pref( { dt => $harddue_dt, dateonly => 1 } ) } if ( $harddue_dt );
455        $row->{'hardduedatebefore'} = 1 if ($row->{'hardduedatecompare'} == -1);
456        $row->{'hardduedateexact'} = 1 if ($row->{'hardduedatecompare'} ==  0);
457        $row->{'hardduedateafter'} = 1 if ($row->{'hardduedatecompare'} ==  1);
458     } else {
459        $row->{'hardduedate'} = 0;
460     }
461     push @row_loop, $row;
462 }
463 $sth->finish;
464
465 my @sorted_row_loop = sort by_category_and_itemtype @row_loop;
466
467 my $sth_branch_cat;
468 if ($branch eq "*") {
469     $sth_branch_cat = $dbh->prepare("
470         SELECT default_borrower_circ_rules.*, categories.description AS humancategorycode
471         FROM default_borrower_circ_rules
472         JOIN categories USING (categorycode)
473
474     ");
475     $sth_branch_cat->execute();
476 } else {
477     $sth_branch_cat = $dbh->prepare("
478         SELECT branch_borrower_circ_rules.*, categories.description AS humancategorycode
479         FROM branch_borrower_circ_rules
480         JOIN categories USING (categorycode)
481         WHERE branch_borrower_circ_rules.branchcode = ?
482     ");
483     $sth_branch_cat->execute($branch);
484 }
485
486 my @branch_cat_rules = ();
487 while (my $row = $sth_branch_cat->fetchrow_hashref) {
488     push @branch_cat_rules, $row;
489 }
490 my @sorted_branch_cat_rules = sort { $a->{'humancategorycode'} cmp $b->{'humancategorycode'} } @branch_cat_rules;
491
492 # note undef maxissueqty so that template can deal with them
493 foreach my $entry (@sorted_branch_cat_rules, @sorted_row_loop) {
494     $entry->{unlimited_maxissueqty} = 1 unless defined($entry->{maxissueqty});
495     $entry->{unlimited_maxonsiteissueqty} = 1 unless defined($entry->{maxonsiteissueqty});
496 }
497
498 @sorted_row_loop = sort by_category_and_itemtype @row_loop;
499
500 my $sth_branch_item;
501 if ($branch eq "*") {
502     $sth_branch_item = $dbh->prepare("
503         SELECT default_branch_item_rules.*,
504             COALESCE( localization.translation, itemtypes.description ) AS translated_description
505         FROM default_branch_item_rules
506         JOIN itemtypes USING (itemtype)
507         LEFT JOIN localization ON itemtypes.itemtype = localization.code
508             AND localization.entity = 'itemtypes'
509             AND localization.lang = ?
510     ");
511     $sth_branch_item->execute($language);
512 } else {
513     $sth_branch_item = $dbh->prepare("
514         SELECT branch_item_rules.*,
515             COALESCE( localization.translation, itemtypes.description ) AS translated_description
516         FROM branch_item_rules
517         JOIN itemtypes USING (itemtype)
518         LEFT JOIN localization ON itemtypes.itemtype = localization.code
519             AND localization.entity = 'itemtypes'
520             AND localization.lang = ?
521         WHERE branch_item_rules.branchcode = ?
522     ");
523     $sth_branch_item->execute($language, $branch);
524 }
525
526 my @branch_item_rules = ();
527 while (my $row = $sth_branch_item->fetchrow_hashref) {
528     push @branch_item_rules, $row;
529 }
530 my @sorted_branch_item_rules = sort { lc $a->{translated_description} cmp lc $b->{translated_description} } @branch_item_rules;
531
532 # note undef holdallowed so that template can deal with them
533 foreach my $entry (@sorted_branch_item_rules) {
534     $entry->{holdallowed_any} = 1 if($entry->{holdallowed} == 2);
535     $entry->{holdallowed_same} = 1 if($entry->{holdallowed} == 1);
536 }
537
538 $template->param(show_branch_cat_rule_form => 1);
539 $template->param(branch_item_rule_loop => \@sorted_branch_item_rules);
540 $template->param(branch_cat_rule_loop => \@sorted_branch_cat_rules);
541
542 my $sth_defaults;
543 if ($branch eq "*") {
544     $sth_defaults = $dbh->prepare("
545         SELECT *
546         FROM default_circ_rules
547     ");
548     $sth_defaults->execute();
549 } else {
550     $sth_defaults = $dbh->prepare("
551         SELECT *
552         FROM default_branch_circ_rules
553         WHERE branchcode = ?
554     ");
555     $sth_defaults->execute($branch);
556 }
557
558 my $defaults = $sth_defaults->fetchrow_hashref;
559
560 if ($defaults) {
561     $template->param(default_holdallowed_none => 1) if($defaults->{holdallowed} == 0);
562     $template->param(default_holdallowed_same => 1) if($defaults->{holdallowed} == 1);
563     $template->param(default_holdallowed_any => 1) if($defaults->{holdallowed} == 2);
564     $template->param(default_maxissueqty => $defaults->{maxissueqty});
565     $template->param(default_maxonsiteissueqty => $defaults->{maxonsiteissueqty});
566     $template->param(default_returnbranch => $defaults->{returnbranch});
567 }
568
569 $template->param(default_rules => ($defaults ? 1 : 0));
570
571 $template->param(categoryloop => \@category_loop,
572                         itemtypeloop => \@itemtypes,
573                         rules => \@sorted_row_loop,
574                         branchloop => \@branchloop,
575                         humanbranch => ($branch ne '*' ? $branches->{$branch}->{branchname} : ''),
576                         current_branch => $branch,
577                         definedbranch => scalar(@sorted_row_loop)>0
578                         );
579 output_html_with_http_headers $input, $cookie, $template->output;
580
581 exit 0;
582
583 # sort by patron category, then item type, putting
584 # default entries at the bottom
585 sub by_category_and_itemtype {
586     unless (by_category($a, $b)) {
587         return by_itemtype($a, $b);
588     }
589 }
590
591 sub by_category {
592     my ($a, $b) = @_;
593     if ($a->{'default_humancategorycode'}) {
594         return ($b->{'default_humancategorycode'} ? 0 : 1);
595     } elsif ($b->{'default_humancategorycode'}) {
596         return -1;
597     } else {
598         return $a->{'humancategorycode'} cmp $b->{'humancategorycode'};
599     }
600 }
601
602 sub by_itemtype {
603     my ($a, $b) = @_;
604     if ($a->{default_translated_description}) {
605         return ($b->{'default_translated_description'} ? 0 : 1);
606     } elsif ($b->{'default_translated_description'}) {
607         return -1;
608     } else {
609         return lc $a->{'translated_description'} cmp lc $b->{'translated_description'};
610     }
611 }