[Koha-patches] [PATCH 14/55] Circulation : Global Quota management

Henri-Damien LAURENT henridamien.laurent at biblibre.com
Wed Mar 10 22:25:56 CET 2010


Quota for a Library network is supposed to be stored in the default Library
issuing rules definition
This patch checks and enforces the issuing rules at network level
---
 C4/Circulation.pm                                  |  258 +++++++++-----------
 .../prog/en/modules/circ/circulation.tmpl          |    4 +
 2 files changed, 116 insertions(+), 146 deletions(-)

diff --git a/C4/Circulation.pm b/C4/Circulation.pm
index 84814a6..cfe8f28 100644
--- a/C4/Circulation.pm
+++ b/C4/Circulation.pm
@@ -338,118 +338,128 @@ sub TooMany {
 	my $item		= shift;
     my $cat_borrower    = $borrower->{'categorycode'};
     my $dbh             = C4::Context->dbh;
-	my $branch;
+	my $exactbranch;
 	# Get which branchcode we need
-	$branch = _GetCircControlBranch($item,$borrower);
+	$exactbranch = _GetCircControlBranch($item,$borrower);
 	my $type = (C4::Context->preference('item-level_itypes')) 
   			? $item->{'itype'}         # item-level
 			: $item->{'itemtype'};     # biblio-level
  
     # given branch, patron category, and item type, determine
     # applicable issuing rule
-    my $issuing_rule = GetIssuingRule($cat_borrower, $type, $branch);
-
-    # if a rule is found and has a loan limit set, count
-    # how many loans the patron already has that meet that
-    # rule
-    if (defined($issuing_rule) and defined($issuing_rule->{'maxissueqty'})) {
-        my @bind_params;
-        my $count_query = "SELECT COUNT(*) FROM issues
-                           JOIN items USING (itemnumber) ";
-
-        my $rule_itemtype = $issuing_rule->{itemtype};
-        if ($rule_itemtype eq "*") {
-            # matching rule has the default item type, so count only
-            # those existing loans that don't fall under a more
-            # specific rule
-            if (C4::Context->preference('item-level_itypes')) {
-                $count_query .= " WHERE items.itype NOT IN (
-                                    SELECT itemtype FROM issuingrules
-                                    WHERE branchcode = ?
-                                    AND   (categorycode = ? OR categorycode = ?)
-                                    AND   itemtype <> '*'
-                                  ) ";
-            } else { 
-                $count_query .= " JOIN  biblioitems USING (biblionumber) 
-                                  WHERE biblioitems.itemtype NOT IN (
-                                    SELECT itemtype FROM issuingrules
-                                    WHERE branchcode = ?
-                                    AND   (categorycode = ? OR categorycode = ?)
-                                    AND   itemtype <> '*'
-                                  ) ";
+    my $branchfield = C4::Context->Preference('HomeOrHoldingBranch') || "homebranch";
+    #By default, Patron is supposed not to be able to borrow
+    my $toomany = 1;
+
+    foreach my $branch ( $exactbranch, '*' ) {
+        my $issuing_rule = GetIssuingRule( $cat_borrower, $type, $branch );
+
+        # if a rule is found and has a loan limit set, count
+        # how many loans the patron already has that meet that
+        # rule
+        if ( defined($issuing_rule) and defined( $issuing_rule->{'maxissueqty'} ) ) {
+            my @bind_params;
+            my $count_query = "SELECT COUNT(*) FROM issues
+							   JOIN items USING (itemnumber) ";
+
+			my $rule_itemtype = $issuing_rule->{itemtype};
+			if ($rule_itemtype eq "*") {
+				# matching rule has the default item type, so count only
+				# those existing loans that don't fall under a more
+				# specific rule
+				if (C4::Context->preference('item-level_itypes')) {
+					$count_query .= " WHERE items.itype NOT IN (
+										SELECT itemtype FROM issuingrules
+										WHERE branchcode = ?
+										AND   (categorycode = ? OR categorycode = ?)
+										AND   itemtype <> '*'
+									  ) ";
+				} else { 
+					$count_query .= " JOIN  biblioitems USING (biblionumber) 
+									  WHERE biblioitems.itemtype NOT IN (
+										SELECT itemtype FROM issuingrules
+										WHERE branchcode = ?
+										AND   (categorycode = ? OR categorycode = ?)
+										AND   itemtype <> '*'
+									  ) ";
+				}
+				push @bind_params, $issuing_rule->{branchcode};
+				push @bind_params, $issuing_rule->{categorycode};
+				push @bind_params, $cat_borrower;
+			} else {
+				# rule has specific item type, so count loans of that
+				# specific item type
+				if (C4::Context->preference('item-level_itypes')) {
+					$count_query .= " WHERE items.itype = ? ";
+				} else { 
+					$count_query .= " JOIN  biblioitems USING (biblionumber) 
+								  WHERE biblioitems.itemtype= ? ";
+                }
+                push @bind_params, $type;
             }
-            push @bind_params, $issuing_rule->{branchcode};
-            push @bind_params, $issuing_rule->{categorycode};
-            push @bind_params, $cat_borrower;
-        } else {
-            # rule has specific item type, so count loans of that
-            # specific item type
-            if (C4::Context->preference('item-level_itypes')) {
-                $count_query .= " WHERE items.itype = ? ";
-            } else { 
-                $count_query .= " JOIN  biblioitems USING (biblionumber) 
-                                  WHERE biblioitems.itemtype= ? ";
+
+            $count_query .= " AND borrowernumber = ? ";
+            push @bind_params, $borrower->{'borrowernumber'};
+            my $rule_branch = $issuing_rule->{branchcode};
+            if ( $rule_branch ne "*" ) {
+                if ( C4::Context->preference('CircControl') eq 'PickupLibrary' ) {
+                    $count_query .= " AND issues.branchcode = ? ";
+                    push @bind_params, $branch;
+                } elsif ( C4::Context->preference('CircControl') eq 'PatronLibrary' ) {
+                    ;    # if branch is the patron's home branch, then count all loans by patron
+                } else {
+                    $count_query .= " AND items.$branchfield = ? ";
+                    push @bind_params, $branch;
+                }
+            }
+
+            my $count_sth = $dbh->prepare($count_query);
+            $count_sth->execute(@bind_params);
+            my ($current_loan_count) = $count_sth->fetchrow_array;
+
+            my $max_loans_allowed = $issuing_rule->{'maxissueqty'};
+            if ( $current_loan_count >= $max_loans_allowed ) {
+                return 1,$current_loan_count,$max_loans_allowed;
+            }
+            else {
+                $toomany=0;
             }
-            push @bind_params, $type;
         }
 
-        $count_query .= " AND borrowernumber = ? ";
-        push @bind_params, $borrower->{'borrowernumber'};
-        my $rule_branch = $issuing_rule->{branchcode};
-        if ($rule_branch ne "*") {
+        # Now count total loans against the limit for the branch
+        my $branch_borrower_circ_rule = GetBranchBorrowerCircRule($branch, $cat_borrower);
+        if (defined($branch_borrower_circ_rule->{maxissueqty})) {
+            my @bind_params = ();
+            my $branch_count_query = "SELECT COUNT(*) FROM issues 
+                                      JOIN items USING (itemnumber)
+                                      WHERE borrowernumber = ? ";
+            push @bind_params, $borrower->{borrowernumber};
+
             if (C4::Context->preference('CircControl') eq 'PickupLibrary') {
-                $count_query .= " AND issues.branchcode = ? ";
+                $branch_count_query .= " AND issues.branchcode = ? ";
                 push @bind_params, $branch;
             } elsif (C4::Context->preference('CircControl') eq 'PatronLibrary') {
                 ; # if branch is the patron's home branch, then count all loans by patron
             } else {
-				my $branchfield=C4::Context->Preference('HomeOrHoldingBranch')||"homebranch";
-                $count_query .= " AND items.$branchfield = ? ";
+                my $branchfield=C4::Context->Preference('HomeOrHoldingBranch')||"homebranch";
+                $branch_count_query .= " AND items.$branchfield = ? ";
                 push @bind_params, $branch;
             }
-        }
+            my $branch_count_sth = $dbh->prepare($branch_count_query);
+            $branch_count_sth->execute(@bind_params);
+            my ($current_loan_count) = $branch_count_sth->fetchrow_array;
 
-        my $count_sth = $dbh->prepare($count_query);
-        $count_sth->execute(@bind_params);
-        my ($current_loan_count) = $count_sth->fetchrow_array;
-
-        my $max_loans_allowed = $issuing_rule->{'maxissueqty'};
-        if ($current_loan_count >= $max_loans_allowed) {
-            return "$current_loan_count / $max_loans_allowed";
-        }
-    }
-
-    # Now count total loans against the limit for the branch
-    my $branch_borrower_circ_rule = GetBranchBorrowerCircRule($branch, $cat_borrower);
-    if (defined($branch_borrower_circ_rule->{maxissueqty})) {
-        my @bind_params = ();
-        my $branch_count_query = "SELECT COUNT(*) FROM issues 
-                                  JOIN items USING (itemnumber)
-                                  WHERE borrowernumber = ? ";
-        push @bind_params, $borrower->{borrowernumber};
-
-        if (C4::Context->preference('CircControl') eq 'PickupLibrary') {
-            $branch_count_query .= " AND issues.branchcode = ? ";
-            push @bind_params, $branch;
-        } elsif (C4::Context->preference('CircControl') eq 'PatronLibrary') {
-            ; # if branch is the patron's home branch, then count all loans by patron
-        } else {
-			my $branchfield=C4::Context->Preference('HomeOrHoldingBranch')||"homebranch";
-            $branch_count_query .= " AND items.$branchfield = ? ";
-            push @bind_params, $branch;
-        }
-        my $branch_count_sth = $dbh->prepare($branch_count_query);
-        $branch_count_sth->execute(@bind_params);
-        my ($current_loan_count) = $branch_count_sth->fetchrow_array;
-
-        my $max_loans_allowed = $branch_borrower_circ_rule->{maxissueqty};
-        if ($current_loan_count >= $max_loans_allowed) {
-            return "$current_loan_count / $max_loans_allowed";
+            my $max_loans_allowed = $branch_borrower_circ_rule->{maxissueqty};
+            if ( $current_loan_count >= $max_loans_allowed ) {
+                return 1,$current_loan_count,$max_loans_allowed;
+            }
+            else {
+                $toomany=0;
+            }
         }
     }
-
     # OK, the patron can issue !!!
-    return;
+    return $toomany;
 }
 
 =head2 itemissues
@@ -675,7 +685,10 @@ sub CanBookBeIssued {
         my $branch = _GetCircControlBranch($item,$borrower);
         my $itype = ( C4::Context->preference('item-level_itypes') ) ? $item->{'itype'} : $biblioitem->{'itemtype'};
         my $loanlength = GetLoanLength( $borrower->{'categorycode'}, $itype, $branch );
-        $duedate = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $loanlength, $branch, $borrower );
+        unless ( $loanlength ) {
+             $issuingimpossible{LOAN_LENGTH_UNDEFINED} = "$borrower->{'categorycode'}, $itype, $branch";
+        }
+        $duedate = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $loanlength, $branch, $borrower ) ;
 
         # Offline circ calls AddIssue directly, doesn't run through here
         #  So issuingimpossible should be ok.
@@ -742,14 +755,15 @@ sub CanBookBeIssued {
 #
     # JB34 CHECKS IF BORROWERS DONT HAVE ISSUE TOO MANY BOOKS
     #
-	my $toomany = TooMany( $borrower, $item->{biblionumber}, $item );
-    # if TooMany return / 0, then the user has no permission to check out this book
-    if ($toomany =~ /\/ 0/) {
+    my @toomany = TooMany( $borrower, $item->{biblionumber}, $item );
+
+    if ( $toomany[0] == 1 && scalar(@toomany)<3) {
         $needsconfirmation{PATRON_CANT} = 1;
-    } else {
-        $needsconfirmation{TOO_MANY} = $toomany if $toomany;
+    } elsif (scalar(@toomany)==3) {
+        $needsconfirmation{TOO_MANY} = "$toomany[1] / $toomany[2]";
     }
 
+
     #
     # ITEM CHECKING
     #
@@ -1075,56 +1089,8 @@ my $loanlength = &GetLoanLength($borrowertype,$itemtype,branchcode)
 
 sub GetLoanLength {
     my ( $borrowertype, $itemtype, $branchcode ) = @_;
-    my $dbh = C4::Context->dbh;
-    my $sth =
-      $dbh->prepare(
-"select issuelength from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null"
-      );
-# warn "in get loan lenght $borrowertype $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->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
-
-    $sth->execute( $borrowertype, "*", $branchcode );
-    $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
-
-    $sth->execute( "*", $itemtype, $branchcode );
-    $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
-
-    $sth->execute( "*", "*", $branchcode );
-    $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
-
-    $sth->execute( $borrowertype, $itemtype, "*" );
-    $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
-
-    $sth->execute( $borrowertype, "*", "*" );
-    $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
-
-    $sth->execute( "*", $itemtype, "*" );
-    $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
-
-    $sth->execute( "*", "*", "*" );
-    $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
-
-    # if no rule is set => 21 days (hardcoded)
-    return 21;
+    my $loanlength=GetIssuingRule($borrowertype,$itemtype,$branchcode);
+    return $loanlength->{issuelength};
 }
 
 =head2 GetIssuingRule
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tmpl
index 5b958ba..cfd8011 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tmpl
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tmpl
@@ -302,6 +302,10 @@ function refocus(calendar) {
             <li>The barcode was not found</li>
         <!-- /TMPL_IF -->
 
+        <!-- TMPL_IF NAME="LOAN_LENGTH_UNDEFINED" -->
+            <li>No circulation rule defined for <!-- TMPL_VAR Name="LOAN_LENGTH_UNDEFINED"--> </li>
+        <!-- /TMPL_IF -->
+
         <!-- TMPL_IF NAME="NOT_FOR_LOAN" -->
             <li>Item not for loan</li>
         <!-- /TMPL_IF -->
-- 
1.6.3.3




More information about the Koha-patches mailing list