Bug 18887: (follow-up) Fix behavior for default branch/category
[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 Modern::Perl;
21 use CGI qw ( -utf8 );
22 use C4::Context;
23 use C4::Output;
24 use C4::Auth;
25 use C4::Koha;
26 use C4::Debug;
27 use Koha::DateUtils;
28 use Koha::Database;
29 use Koha::IssuingRule;
30 use Koha::IssuingRules;
31 use Koha::Logger;
32 use Koha::RefundLostItemFeeRule;
33 use Koha::RefundLostItemFeeRules;
34 use Koha::Libraries;
35 use Koha::CirculationRules;
36 use Koha::Patron::Categories;
37 use Koha::Caches;
38
39 my $input = CGI->new;
40 my $dbh = C4::Context->dbh;
41
42 # my $flagsrequired;
43 # $flagsrequired->{circulation}=1;
44 my ($template, $loggedinuser, $cookie)
45     = get_template_and_user({template_name => "admin/smart-rules.tt",
46                             query => $input,
47                             type => "intranet",
48                             authnotrequired => 0,
49                             flagsrequired => {parameters => 'manage_circ_rules'},
50                             debug => 1,
51                             });
52
53 my $type=$input->param('type');
54
55 my $branch = $input->param('branch');
56 unless ( $branch ) {
57     if ( C4::Context->preference('DefaultToLoggedInLibraryCircRules') ) {
58         $branch = Koha::Libraries->search->count() == 1 ? undef : C4::Context::mybranch();
59     }
60     else {
61         $branch = C4::Context::only_my_library() ? ( C4::Context::mybranch() || '*' ) : '*';
62     }
63 }
64 $branch = '*' if $branch eq 'NO_LIBRARY_SET';
65
66 my $op = $input->param('op') || q{};
67 my $language = C4::Languages::getlanguage();
68
69 my $cache = Koha::Caches->get_instance;
70 $cache->clear_from_cache( Koha::IssuingRules::GUESSED_ITEMTYPES_KEY );
71
72 if ($op eq 'delete') {
73     my $itemtype     = $input->param('itemtype');
74     my $categorycode = $input->param('categorycode');
75     $debug and warn "deleting $1 $2 $branch";
76
77     my $sth_Idelete = $dbh->prepare("delete from issuingrules where branchcode=? and categorycode=? and itemtype=?");
78     $sth_Idelete->execute($branch, $categorycode, $itemtype);
79 }
80 elsif ($op eq 'delete-branch-cat') {
81     my $categorycode  = $input->param('categorycode');
82     if ($branch eq "*") {
83         if ($categorycode eq "*") {
84             my $sth_delete = $dbh->prepare("DELETE FROM default_circ_rules");
85             $sth_delete->execute();
86         } else {
87             my $sth_delete = $dbh->prepare("DELETE FROM default_borrower_circ_rules
88                                             WHERE categorycode = ?");
89             $sth_delete->execute($categorycode);
90         }
91     } elsif ($categorycode eq "*") {
92         my $sth_delete = $dbh->prepare("DELETE FROM default_branch_circ_rules
93                                         WHERE branchcode = ?");
94         $sth_delete->execute($branch);
95     } else {
96         my $sth_delete = $dbh->prepare("DELETE FROM branch_borrower_circ_rules
97                                         WHERE branchcode = ?
98                                         AND categorycode = ?");
99         $sth_delete->execute($branch, $categorycode);
100     }
101     Koha::CirculationRules->set_rule(
102         {
103             branchcode   => $branch,
104             categorycode => $categorycode,
105             itemtype     => undef,
106             rule_name    => 'max_holds',
107             rule_value   => undef,
108         }
109     );
110 }
111 elsif ($op eq 'delete-branch-item') {
112     my $itemtype  = $input->param('itemtype');
113     if ($branch eq "*") {
114         if ($itemtype eq "*") {
115             my $sth_delete = $dbh->prepare("DELETE FROM default_circ_rules");
116             $sth_delete->execute();
117         } else {
118             my $sth_delete = $dbh->prepare("DELETE FROM default_branch_item_rules
119                                             WHERE itemtype = ?");
120             $sth_delete->execute($itemtype);
121         }
122     } elsif ($itemtype eq "*") {
123         my $sth_delete = $dbh->prepare("DELETE FROM default_branch_circ_rules
124                                         WHERE branchcode = ?");
125         $sth_delete->execute($branch);
126     } else {
127         my $sth_delete = $dbh->prepare("DELETE FROM branch_item_rules
128                                         WHERE branchcode = ?
129                                         AND itemtype = ?");
130         $sth_delete->execute($branch, $itemtype);
131     }
132 }
133 # save the values entered
134 elsif ($op eq 'add') {
135     my $br = $branch; # branch
136     my $bor  = $input->param('categorycode'); # borrower category
137     my $itemtype  = $input->param('itemtype');     # item type
138     my $fine = $input->param('fine');
139     my $finedays     = $input->param('finedays');
140     my $maxsuspensiondays = $input->param('maxsuspensiondays');
141     $maxsuspensiondays = undef if $maxsuspensiondays eq q||;
142     my $suspension_chargeperiod = $input->param('suspension_chargeperiod') || 1;
143     my $firstremind  = $input->param('firstremind');
144     my $chargeperiod = $input->param('chargeperiod');
145     my $chargeperiod_charge_at = $input->param('chargeperiod_charge_at');
146     my $maxissueqty  = $input->param('maxissueqty');
147     my $maxonsiteissueqty  = $input->param('maxonsiteissueqty');
148     my $renewalsallowed  = $input->param('renewalsallowed');
149     my $renewalperiod    = $input->param('renewalperiod');
150     my $norenewalbefore  = $input->param('norenewalbefore');
151     $norenewalbefore = undef if $norenewalbefore =~ /^\s*$/;
152     my $auto_renew = $input->param('auto_renew') eq 'yes' ? 1 : 0;
153     my $no_auto_renewal_after = $input->param('no_auto_renewal_after');
154     $no_auto_renewal_after = undef if $no_auto_renewal_after =~ /^\s*$/;
155     my $no_auto_renewal_after_hard_limit = $input->param('no_auto_renewal_after_hard_limit') || undef;
156     $no_auto_renewal_after_hard_limit = eval { dt_from_string( $input->param('no_auto_renewal_after_hard_limit') ) } if ( $no_auto_renewal_after_hard_limit );
157     $no_auto_renewal_after_hard_limit = output_pref( { dt => $no_auto_renewal_after_hard_limit, dateonly => 1, dateformat => 'iso' } ) if ( $no_auto_renewal_after_hard_limit );
158     my $reservesallowed  = $input->param('reservesallowed');
159     my $holds_per_record  = $input->param('holds_per_record');
160     my $onshelfholds     = $input->param('onshelfholds') || 0;
161     $maxissueqty =~ s/\s//g;
162     $maxissueqty = undef if $maxissueqty !~ /^\d+/;
163     $maxonsiteissueqty =~ s/\s//g;
164     $maxonsiteissueqty = undef if $maxonsiteissueqty !~ /^\d+/;
165     my $issuelength  = $input->param('issuelength');
166     $issuelength = $issuelength eq q{} ? undef : $issuelength;
167     my $lengthunit  = $input->param('lengthunit');
168     my $hardduedate = $input->param('hardduedate') || undef;
169     $hardduedate = eval { dt_from_string( $input->param('hardduedate') ) } if ( $hardduedate );
170     $hardduedate = output_pref( { dt => $hardduedate, dateonly => 1, dateformat => 'iso' } ) if ( $hardduedate );
171     my $hardduedatecompare = $input->param('hardduedatecompare');
172     my $rentaldiscount = $input->param('rentaldiscount');
173     my $opacitemholds = $input->param('opacitemholds') || 0;
174     my $article_requests = $input->param('article_requests') || 'no';
175     my $overduefinescap = $input->param('overduefinescap') || undef;
176     my $cap_fine_to_replacement_price = $input->param('cap_fine_to_replacement_price') eq 'on';
177     $debug and warn "Adding $br, $bor, $itemtype, $fine, $maxissueqty, $maxonsiteissueqty, $cap_fine_to_replacement_price";
178
179     my $params = {
180         branchcode                    => $br,
181         categorycode                  => $bor,
182         itemtype                      => $itemtype,
183         fine                          => $fine,
184         finedays                      => $finedays,
185         maxsuspensiondays             => $maxsuspensiondays,
186         suspension_chargeperiod       => $suspension_chargeperiod,
187         firstremind                   => $firstremind,
188         chargeperiod                  => $chargeperiod,
189         chargeperiod_charge_at        => $chargeperiod_charge_at,
190         maxissueqty                   => $maxissueqty,
191         maxonsiteissueqty             => $maxonsiteissueqty,
192         renewalsallowed               => $renewalsallowed,
193         renewalperiod                 => $renewalperiod,
194         norenewalbefore               => $norenewalbefore,
195         auto_renew                    => $auto_renew,
196         no_auto_renewal_after         => $no_auto_renewal_after,
197         no_auto_renewal_after_hard_limit => $no_auto_renewal_after_hard_limit,
198         reservesallowed               => $reservesallowed,
199         holds_per_record              => $holds_per_record,
200         issuelength                   => $issuelength,
201         lengthunit                    => $lengthunit,
202         hardduedate                   => $hardduedate,
203         hardduedatecompare            => $hardduedatecompare,
204         rentaldiscount                => $rentaldiscount,
205         onshelfholds                  => $onshelfholds,
206         opacitemholds                 => $opacitemholds,
207         overduefinescap               => $overduefinescap,
208         cap_fine_to_replacement_price => $cap_fine_to_replacement_price,
209         article_requests              => $article_requests,
210     };
211
212     my $issuingrule = Koha::IssuingRules->find({categorycode => $bor, itemtype => $itemtype, branchcode => $br});
213     if ($issuingrule) {
214         $issuingrule->set($params)->store();
215     } else {
216         Koha::IssuingRule->new()->set($params)->store();
217     }
218
219 }
220 elsif ($op eq "set-branch-defaults") {
221     my $categorycode  = $input->param('categorycode');
222     my $maxissueqty   = $input->param('maxissueqty');
223     my $maxonsiteissueqty = $input->param('maxonsiteissueqty');
224     my $holdallowed   = $input->param('holdallowed');
225     my $hold_fulfillment_policy = $input->param('hold_fulfillment_policy');
226     my $returnbranch  = $input->param('returnbranch');
227     my $max_holds = $input->param('max_holds');
228     $maxissueqty =~ s/\s//g;
229     $maxissueqty = undef if $maxissueqty !~ /^\d+/;
230     $maxonsiteissueqty =~ s/\s//g;
231     $maxonsiteissueqty = undef if $maxonsiteissueqty !~ /^\d+/;
232     $holdallowed =~ s/\s//g;
233     $holdallowed = undef if $holdallowed !~ /^\d+/;
234     $max_holds =~ s/\s//g;
235     $max_holds = undef if $max_holds !~ /^\d+/;
236
237     if ($branch eq "*") {
238         my $sth_search = $dbh->prepare("SELECT count(*) AS total
239                                         FROM default_circ_rules");
240         my $sth_insert = $dbh->prepare("INSERT INTO default_circ_rules
241                                         (maxissueqty, maxonsiteissueqty, holdallowed, hold_fulfillment_policy, returnbranch)
242                                         VALUES (?, ?, ?, ?, ?)");
243         my $sth_update = $dbh->prepare("UPDATE default_circ_rules
244                                         SET maxissueqty = ?, maxonsiteissueqty = ?, holdallowed = ?, hold_fulfillment_policy = ?, returnbranch = ?");
245
246         $sth_search->execute();
247         my $res = $sth_search->fetchrow_hashref();
248         if ($res->{total}) {
249             $sth_update->execute($maxissueqty, $maxonsiteissueqty, $holdallowed, $hold_fulfillment_policy, $returnbranch);
250         } else {
251             $sth_insert->execute($maxissueqty, $maxonsiteissueqty, $holdallowed, $hold_fulfillment_policy, $returnbranch);
252         }
253     } else {
254         my $sth_search = $dbh->prepare("SELECT count(*) AS total
255                                         FROM default_branch_circ_rules
256                                         WHERE branchcode = ?");
257         my $sth_insert = $dbh->prepare("INSERT INTO default_branch_circ_rules
258                                         (branchcode, maxissueqty, maxonsiteissueqty, holdallowed, hold_fulfillment_policy, returnbranch)
259                                         VALUES (?, ?, ?, ?, ?, ?)");
260         my $sth_update = $dbh->prepare("UPDATE default_branch_circ_rules
261                                         SET maxissueqty = ?, maxonsiteissueqty = ?, holdallowed = ?, hold_fulfillment_policy = ?, returnbranch = ?
262                                         WHERE branchcode = ?");
263         $sth_search->execute($branch);
264         my $res = $sth_search->fetchrow_hashref();
265         if ($res->{total}) {
266             $sth_update->execute($maxissueqty, $maxonsiteissueqty, $holdallowed, $hold_fulfillment_policy, $returnbranch, $branch);
267         } else {
268             $sth_insert->execute($branch, $maxissueqty, $maxonsiteissueqty, $holdallowed, $hold_fulfillment_policy, $returnbranch);
269         }
270     }
271     Koha::CirculationRules->set_rule(
272         {
273             branchcode   => $branch,
274             categorycode => '*',
275             itemtype     => undef,
276             rule_name    => 'max_holds',
277             rule_value   => $max_holds,
278         }
279     );
280 }
281 elsif ($op eq "add-branch-cat") {
282     my $categorycode  = $input->param('categorycode');
283     my $maxissueqty   = $input->param('maxissueqty');
284     my $maxonsiteissueqty = $input->param('maxonsiteissueqty');
285     my $max_holds = $input->param('max_holds');
286     $maxissueqty =~ s/\s//g;
287     $maxissueqty = undef if $maxissueqty !~ /^\d+/;
288     $maxonsiteissueqty =~ s/\s//g;
289     $maxonsiteissueqty = undef if $maxonsiteissueqty !~ /^\d+/;
290     $max_holds =~ s/\s//g;
291     $max_holds = undef if $max_holds !~ /^\d+/;
292
293     if ($branch eq "*") {
294         if ($categorycode eq "*") {
295             my $sth_search = $dbh->prepare("SELECT count(*) AS total
296                                             FROM default_circ_rules");
297             my $sth_insert = $dbh->prepare(q|
298                 INSERT INTO default_circ_rules
299                     (maxissueqty, maxonsiteissueqty, max_holds)
300                     VALUES (?, ?, ?)
301             |);
302             my $sth_update = $dbh->prepare(q|
303                 UPDATE default_circ_rules
304                 SET maxissueqty = ?,
305                     maxonsiteissueqty = ?,
306                     max_holds = ?
307             |);
308
309             $sth_search->execute();
310             my $res = $sth_search->fetchrow_hashref();
311             if ($res->{total}) {
312                 $sth_update->execute( $maxissueqty, $maxonsiteissueqty );
313             } else {
314                 $sth_insert->execute( $maxissueqty, $maxonsiteissueqty );
315             }
316
317             Koha::CirculationRules->set_rule(
318                 {
319                     branchcode   => undef,
320                     categorycode => undef,
321                     itemtype     => undef,
322                     rule_name    => 'max_holds',
323                     rule_value   => $max_holds,
324                 }
325             );
326         } else {
327             my $sth_search = $dbh->prepare("SELECT count(*) AS total
328                                             FROM default_borrower_circ_rules
329                                             WHERE categorycode = ?");
330             my $sth_insert = $dbh->prepare(q|
331                 INSERT INTO default_borrower_circ_rules
332                     (categorycode, maxissueqty, maxonsiteissueqty, max_holds)
333                     VALUES (?, ?, ?, ?)
334             |);
335             my $sth_update = $dbh->prepare(q|
336                 UPDATE default_borrower_circ_rules
337                 SET maxissueqty = ?,
338                     maxonsiteissueqty = ?,
339                     max_holds = ?
340                 WHERE categorycode = ?
341             |);
342             $sth_search->execute($categorycode);
343             my $res = $sth_search->fetchrow_hashref();
344             if ($res->{total}) {
345                 $sth_update->execute( $maxissueqty, $maxonsiteissueqty, $categorycode );
346             } else {
347                 $sth_insert->execute( $categorycode, $maxissueqty, $maxonsiteissueqty );
348             }
349
350             Koha::CirculationRules->set_rule(
351                 {
352                     branchcode   => '*',
353                     categorycode => $categorycode,
354                     itemtype     => undef,
355                     rule_name    => 'max_holds',
356                     rule_value   => $max_holds,
357                 }
358             );
359         }
360     } elsif ($categorycode eq "*") {
361         my $sth_search = $dbh->prepare("SELECT count(*) AS total
362                                         FROM default_branch_circ_rules
363                                         WHERE branchcode = ?");
364         my $sth_insert = $dbh->prepare(q|
365             INSERT INTO default_branch_circ_rules
366             (branchcode, maxissueqty, maxonsiteissueqty)
367             VALUES (?, ?, ?)
368         |);
369         my $sth_update = $dbh->prepare(q|
370             UPDATE default_branch_circ_rules
371             SET maxissueqty = ?,
372                 maxonsiteissueqty = ?
373             WHERE branchcode = ?
374         |);
375         $sth_search->execute($branch);
376         my $res = $sth_search->fetchrow_hashref();
377         if ($res->{total}) {
378             $sth_update->execute($maxissueqty, $maxonsiteissueqty, $branch);
379         } else {
380             $sth_insert->execute($branch, $maxissueqty, $maxonsiteissueqty);
381         }
382     } else {
383         my $sth_search = $dbh->prepare("SELECT count(*) AS total
384                                         FROM branch_borrower_circ_rules
385                                         WHERE branchcode = ?
386                                         AND   categorycode = ?");
387         my $sth_insert = $dbh->prepare(q|
388             INSERT INTO branch_borrower_circ_rules
389             (branchcode, categorycode, maxissueqty, maxonsiteissueqty, max_holds)
390             VALUES (?, ?, ?, ?, ?)
391         |);
392         my $sth_update = $dbh->prepare(q|
393             UPDATE branch_borrower_circ_rules
394             SET maxissueqty = ?,
395                 maxonsiteissueqty = ?
396                 max_holds = ?
397             WHERE branchcode = ?
398             AND categorycode = ?
399         |);
400
401         $sth_search->execute($branch, $categorycode);
402         my $res = $sth_search->fetchrow_hashref();
403         if ($res->{total}) {
404             $sth_update->execute($maxissueqty, $maxonsiteissueqty, $max_holds, $branch, $categorycode);
405         } else {
406             $sth_insert->execute($branch, $categorycode, $maxissueqty, $maxonsiteissueqty, $max_holds);
407         }
408
409         Koha::CirculationRules->set_rule(
410             {
411                 branchcode   => $branch,
412                 categorycode => $categorycode,
413                 itemtype     => undef,
414                 rule_name    => 'max_holds',
415                 rule_value   => $max_holds,
416             }
417         );
418     }
419 }
420 elsif ($op eq "add-branch-item") {
421     my $itemtype                = $input->param('itemtype');
422     my $holdallowed             = $input->param('holdallowed');
423     my $hold_fulfillment_policy = $input->param('hold_fulfillment_policy');
424     my $returnbranch            = $input->param('returnbranch');
425
426     $holdallowed =~ s/\s//g;
427     $holdallowed = undef if $holdallowed !~ /^\d+/;
428
429     if ($branch eq "*") {
430         if ($itemtype eq "*") {
431             my $sth_search = $dbh->prepare("SELECT count(*) AS total
432                                             FROM default_circ_rules");
433             my $sth_insert = $dbh->prepare("INSERT INTO default_circ_rules
434                                             (holdallowed, hold_fulfillment_policy, returnbranch)
435                                             VALUES (?, ?, ?)");
436             my $sth_update = $dbh->prepare("UPDATE default_circ_rules
437                                             SET holdallowed = ?, hold_fulfillment_policy = ?, returnbranch = ?");
438
439             $sth_search->execute();
440             my $res = $sth_search->fetchrow_hashref();
441             if ($res->{total}) {
442                 $sth_update->execute($holdallowed, $hold_fulfillment_policy, $returnbranch);
443             } else {
444                 $sth_insert->execute($holdallowed, $hold_fulfillment_policy, $returnbranch);
445             }
446         } else {
447             my $sth_search = $dbh->prepare("SELECT count(*) AS total
448                                             FROM default_branch_item_rules
449                                             WHERE itemtype = ?");
450             my $sth_insert = $dbh->prepare("INSERT INTO default_branch_item_rules
451                                             (itemtype, holdallowed, hold_fulfillment_policy, returnbranch)
452                                             VALUES (?, ?, ?, ?)");
453             my $sth_update = $dbh->prepare("UPDATE default_branch_item_rules
454                                             SET holdallowed = ?, hold_fulfillment_policy = ?, returnbranch = ?
455                                             WHERE itemtype = ?");
456             $sth_search->execute($itemtype);
457             my $res = $sth_search->fetchrow_hashref();
458             if ($res->{total}) {
459                 $sth_update->execute($holdallowed, $hold_fulfillment_policy, $returnbranch, $itemtype);
460             } else {
461                 $sth_insert->execute($itemtype, $holdallowed, $hold_fulfillment_policy, $returnbranch);
462             }
463         }
464     } elsif ($itemtype eq "*") {
465         my $sth_search = $dbh->prepare("SELECT count(*) AS total
466                                         FROM default_branch_circ_rules
467                                         WHERE branchcode = ?");
468         my $sth_insert = $dbh->prepare("INSERT INTO default_branch_circ_rules
469                                         (branchcode, holdallowed, hold_fulfillment_policy, returnbranch)
470                                         VALUES (?, ?, ?, ?)");
471         my $sth_update = $dbh->prepare("UPDATE default_branch_circ_rules
472                                         SET holdallowed = ?, hold_fulfillment_policy = ?, returnbranch = ?
473                                         WHERE branchcode = ?");
474         $sth_search->execute($branch);
475         my $res = $sth_search->fetchrow_hashref();
476         if ($res->{total}) {
477             $sth_update->execute($holdallowed, $hold_fulfillment_policy, $returnbranch, $branch);
478         } else {
479             $sth_insert->execute($branch, $holdallowed, $hold_fulfillment_policy, $returnbranch);
480         }
481     } else {
482         my $sth_search = $dbh->prepare("SELECT count(*) AS total
483                                         FROM branch_item_rules
484                                         WHERE branchcode = ?
485                                         AND   itemtype = ?");
486         my $sth_insert = $dbh->prepare("INSERT INTO branch_item_rules
487                                         (branchcode, itemtype, holdallowed, hold_fulfillment_policy, returnbranch)
488                                         VALUES (?, ?, ?, ?, ?)");
489         my $sth_update = $dbh->prepare("UPDATE branch_item_rules
490                                         SET holdallowed = ?, hold_fulfillment_policy = ?, returnbranch = ?
491                                         WHERE branchcode = ?
492                                         AND itemtype = ?");
493
494         $sth_search->execute($branch, $itemtype);
495         my $res = $sth_search->fetchrow_hashref();
496         if ($res->{total}) {
497             $sth_update->execute($holdallowed, $hold_fulfillment_policy, $returnbranch, $branch, $itemtype);
498         } else {
499             $sth_insert->execute($branch, $itemtype, $holdallowed, $hold_fulfillment_policy, $returnbranch);
500         }
501     }
502 }
503 elsif ( $op eq 'mod-refund-lost-item-fee-rule' ) {
504
505     my $refund = $input->param('refund');
506
507     if ( $refund eq '*' ) {
508         if ( $branch ne '*' ) {
509             # only do something for $refund eq '*' if branch-specific
510             eval {
511                 # Delete it so it picks the default
512                 Koha::RefundLostItemFeeRules->find({
513                     branchcode => $branch
514                 })->delete;
515             };
516         }
517     } else {
518         my $refundRule =
519                 Koha::RefundLostItemFeeRules->find({
520                     branchcode => $branch
521                 }) // Koha::RefundLostItemFeeRule->new;
522         $refundRule->set({
523             branchcode => $branch,
524                 refund => $refund
525         })->store;
526     }
527 }
528
529 my $refundLostItemFeeRule = Koha::RefundLostItemFeeRules->find({ branchcode => $branch });
530 $template->param(
531     refundLostItemFeeRule => $refundLostItemFeeRule,
532     defaultRefundRule     => Koha::RefundLostItemFeeRules->_default_rule
533 );
534
535 my $patron_categories = Koha::Patron::Categories->search({}, { order_by => ['description'] });
536
537 my @row_loop;
538 my $itemtypes = Koha::ItemTypes->search_with_localization;
539
540 my $sth2 = $dbh->prepare("
541     SELECT  issuingrules.*,
542             itemtypes.description AS humanitemtype,
543             categories.description AS humancategorycode,
544             COALESCE( localization.translation, itemtypes.description ) AS translated_description
545     FROM issuingrules
546     LEFT JOIN itemtypes
547         ON (itemtypes.itemtype = issuingrules.itemtype)
548     LEFT JOIN categories
549         ON (categories.categorycode = issuingrules.categorycode)
550     LEFT JOIN localization ON issuingrules.itemtype = localization.code
551         AND localization.entity = 'itemtypes'
552         AND localization.lang = ?
553     WHERE issuingrules.branchcode = ?
554 ");
555 $sth2->execute($language, $branch);
556
557 while (my $row = $sth2->fetchrow_hashref) {
558     $row->{'current_branch'} ||= $row->{'branchcode'};
559     $row->{humanitemtype} ||= $row->{itemtype};
560     $row->{default_translated_description} = 1 if $row->{humanitemtype} eq '*';
561     $row->{'humancategorycode'} ||= $row->{'categorycode'};
562     $row->{'default_humancategorycode'} = 1 if $row->{'humancategorycode'} eq '*';
563     $row->{'fine'} = sprintf('%.2f', $row->{'fine'});
564     if ($row->{'hardduedate'} && $row->{'hardduedate'} ne '0000-00-00') {
565        my $harddue_dt = eval { dt_from_string( $row->{'hardduedate'} ) };
566        $row->{'hardduedate'} = eval { output_pref( { dt => $harddue_dt, dateonly => 1 } ) } if ( $harddue_dt );
567        $row->{'hardduedatebefore'} = 1 if ($row->{'hardduedatecompare'} == -1);
568        $row->{'hardduedateexact'} = 1 if ($row->{'hardduedatecompare'} ==  0);
569        $row->{'hardduedateafter'} = 1 if ($row->{'hardduedatecompare'} ==  1);
570     } else {
571        $row->{'hardduedate'} = 0;
572     }
573     if ($row->{no_auto_renewal_after_hard_limit}) {
574        my $dt = eval { dt_from_string( $row->{no_auto_renewal_after_hard_limit} ) };
575        $row->{no_auto_renewal_after_hard_limit} = eval { output_pref( { dt => $dt, dateonly => 1 } ) } if $dt;
576     }
577
578     push @row_loop, $row;
579 }
580
581 my @sorted_row_loop = sort by_category_and_itemtype @row_loop;
582
583 my $sth_branch_cat;
584 if ($branch eq "*") {
585     $sth_branch_cat = $dbh->prepare("
586         SELECT default_borrower_circ_rules.*, categories.description AS humancategorycode
587         FROM default_borrower_circ_rules
588         JOIN categories USING (categorycode)
589
590     ");
591     $sth_branch_cat->execute();
592 } else {
593     $sth_branch_cat = $dbh->prepare("
594         SELECT branch_borrower_circ_rules.*, categories.description AS humancategorycode
595         FROM branch_borrower_circ_rules
596         JOIN categories USING (categorycode)
597         WHERE branch_borrower_circ_rules.branchcode = ?
598     ");
599     $sth_branch_cat->execute($branch);
600 }
601
602 my @branch_cat_rules = ();
603 while (my $row = $sth_branch_cat->fetchrow_hashref) {
604     push @branch_cat_rules, $row;
605 }
606 my @sorted_branch_cat_rules = sort { $a->{'humancategorycode'} cmp $b->{'humancategorycode'} } @branch_cat_rules;
607
608 # note undef maxissueqty so that template can deal with them
609 foreach my $entry (@sorted_branch_cat_rules, @sorted_row_loop) {
610     $entry->{unlimited_maxissueqty} = 1 unless defined($entry->{maxissueqty});
611     $entry->{unlimited_maxonsiteissueqty} = 1 unless defined($entry->{maxonsiteissueqty});
612     $entry->{unlimited_max_holds} = 1 unless defined($entry->{max_holds});
613 }
614
615 @sorted_row_loop = sort by_category_and_itemtype @row_loop;
616
617 my $sth_branch_item;
618 if ($branch eq "*") {
619     $sth_branch_item = $dbh->prepare("
620         SELECT default_branch_item_rules.*,
621             COALESCE( localization.translation, itemtypes.description ) AS translated_description
622         FROM default_branch_item_rules
623         JOIN itemtypes USING (itemtype)
624         LEFT JOIN localization ON itemtypes.itemtype = localization.code
625             AND localization.entity = 'itemtypes'
626             AND localization.lang = ?
627     ");
628     $sth_branch_item->execute($language);
629 } else {
630     $sth_branch_item = $dbh->prepare("
631         SELECT branch_item_rules.*,
632             COALESCE( localization.translation, itemtypes.description ) AS translated_description
633         FROM branch_item_rules
634         JOIN itemtypes USING (itemtype)
635         LEFT JOIN localization ON itemtypes.itemtype = localization.code
636             AND localization.entity = 'itemtypes'
637             AND localization.lang = ?
638         WHERE branch_item_rules.branchcode = ?
639     ");
640     $sth_branch_item->execute($language, $branch);
641 }
642
643 my @branch_item_rules = ();
644 while (my $row = $sth_branch_item->fetchrow_hashref) {
645     push @branch_item_rules, $row;
646 }
647 my @sorted_branch_item_rules = sort { lc $a->{translated_description} cmp lc $b->{translated_description} } @branch_item_rules;
648
649 # note undef holdallowed so that template can deal with them
650 foreach my $entry (@sorted_branch_item_rules) {
651     $entry->{holdallowed_any}  = 1 if ( $entry->{holdallowed} == 2 );
652     $entry->{holdallowed_same} = 1 if ( $entry->{holdallowed} == 1 );
653 }
654
655 $template->param(show_branch_cat_rule_form => 1);
656 $template->param(branch_item_rule_loop => \@sorted_branch_item_rules);
657 $template->param(branch_cat_rule_loop => \@sorted_branch_cat_rules);
658
659 my $sth_defaults;
660 if ($branch eq "*") {
661     $sth_defaults = $dbh->prepare("
662         SELECT *
663         FROM default_circ_rules
664     ");
665     $sth_defaults->execute();
666 } else {
667     $sth_defaults = $dbh->prepare("
668         SELECT *
669         FROM default_branch_circ_rules
670         WHERE branchcode = ?
671     ");
672     $sth_defaults->execute($branch);
673 }
674
675 my $defaults = $sth_defaults->fetchrow_hashref;
676
677 if ($defaults) {
678     $template->param( default_holdallowed_none => 1 ) if ( $defaults->{holdallowed} == 0 );
679     $template->param( default_holdallowed_same => 1 ) if ( $defaults->{holdallowed} == 1 );
680     $template->param( default_holdallowed_any  => 1 ) if ( $defaults->{holdallowed} == 2 );
681     $template->param( default_hold_fulfillment_policy => $defaults->{hold_fulfillment_policy} );
682     $template->param( default_maxissueqty      => $defaults->{maxissueqty} );
683     $template->param( default_maxonsiteissueqty => $defaults->{maxonsiteissueqty} );
684     $template->param( default_returnbranch      => $defaults->{returnbranch} );
685 }
686
687 $template->param(default_rules => ($defaults ? 1 : 0));
688
689 $template->param(
690     patron_categories => $patron_categories,
691                         itemtypeloop => $itemtypes,
692                         rules => \@sorted_row_loop,
693                         humanbranch => ($branch ne '*' ? $branch : ''),
694                         current_branch => $branch,
695                         definedbranch => scalar(@sorted_row_loop)>0
696                         );
697 output_html_with_http_headers $input, $cookie, $template->output;
698
699 exit 0;
700
701 # sort by patron category, then item type, putting
702 # default entries at the bottom
703 sub by_category_and_itemtype {
704     unless (by_category($a, $b)) {
705         return by_itemtype($a, $b);
706     }
707 }
708
709 sub by_category {
710     my ($a, $b) = @_;
711     if ($a->{'default_humancategorycode'}) {
712         return ($b->{'default_humancategorycode'} ? 0 : 1);
713     } elsif ($b->{'default_humancategorycode'}) {
714         return -1;
715     } else {
716         return $a->{'humancategorycode'} cmp $b->{'humancategorycode'};
717     }
718 }
719
720 sub by_itemtype {
721     my ($a, $b) = @_;
722     if ($a->{default_translated_description}) {
723         return ($b->{'default_translated_description'} ? 0 : 1);
724     } elsif ($b->{'default_translated_description'}) {
725         return -1;
726     } else {
727         return lc $a->{'translated_description'} cmp lc $b->{'translated_description'};
728     }
729 }