Bug 7888 - Permission for "change password" button in circ toolbar should be "borrowe...
[koha.git] / C4 / Circulation.pm
index d2aa9b6..9c43f36 100644 (file)
@@ -1385,13 +1385,17 @@ sub GetBranchBorrowerCircRule {
 Retrieves circulation rule attributes that apply to the given
 branch and item type, regardless of patron category.
 
-The return value is a hashref containing the following key:
+The return value is a hashref containing the following keys:
 
 holdallowed => Hold policy for this branch and itemtype. Possible values:
   0: No holds allowed.
   1: Holds allowed only by patrons that have the same homebranch as the item.
   2: Holds allowed from any patron.
 
+returnbranch => branch to which to return item.  Possible values:
+  noreturn: do not return, let item remain where checked in (floating collections)
+  homebranch: return to item's home branch
+
 This searches branchitemrules in the following order:
 
   * Same branchcode and itemtype
@@ -1399,7 +1403,7 @@ This searches branchitemrules in the following order:
   * branchcode '*', same itemtype
   * branchcode and itemtype '*'
 
-Neither C<$branchcode> nor C<$categorycode> should be '*'.
+Neither C<$branchcode> nor C<$itemtype> should be '*'.
 
 =cut
 
@@ -1409,33 +1413,36 @@ sub GetBranchItemRule {
     my $result = {};
 
     my @attempts = (
-        ['SELECT holdallowed
+        ['SELECT holdallowed, returnbranch
             FROM branch_item_rules
             WHERE branchcode = ?
               AND itemtype = ?', $branchcode, $itemtype],
-        ['SELECT holdallowed
+        ['SELECT holdallowed, returnbranch
             FROM default_branch_circ_rules
             WHERE branchcode = ?', $branchcode],
-        ['SELECT holdallowed
+        ['SELECT holdallowed, returnbranch
             FROM default_branch_item_rules
             WHERE itemtype = ?', $itemtype],
-        ['SELECT holdallowed
+        ['SELECT holdallowed, returnbranch
             FROM default_circ_rules'],
     );
 
     foreach my $attempt (@attempts) {
         my ($query, @bind_params) = @{$attempt};
+        my $search_result = $dbh->selectrow_hashref ( $query , {}, @bind_params );
 
         # Since branch/category and branch/itemtype use the same per-branch
         # defaults tables, we have to check that the key we want is set, not
         # just that a row was returned
-        return $result if ( defined( $result->{'holdallowed'} = $dbh->selectrow_array( $query, {}, @bind_params ) ) );
+        $result->{'holdallowed'}  = $search_result->{'holdallowed'}  unless ( defined $result->{'holdallowed'} );
+        $result->{'returnbranch'} = $search_result->{'returnbranch'} unless ( defined $result->{'returnbranch'} );
     }
     
     # built-in default circulation rule
-    return {
-        holdallowed => 2,
-    };
+    $result->{'holdallowed'} = 2 unless ( defined $result->{'holdallowed'} );
+    $result->{'returnbranch'} = 'homebranch' unless ( defined $result->{'returnbranch'} );
+
+    return $result;
 }
 
 =head2 AddReturn
@@ -1552,9 +1559,10 @@ sub AddReturn {
     my $item = GetItem($itemnumber) or die "GetItem($itemnumber) failed";
         # full item data, but no borrowernumber or checkout info (no issue)
         # we know GetItem should work because GetItemnumberFromBarcode worked
-    my $hbr      = C4::Context->preference("HomeOrHoldingBranchReturn") || "homebranch";
-    $hbr = $item->{$hbr} || '';
-        # item must be from items table -- issues table has branchcode and issuingbranch, not homebranch nor holdingbranch
+    my $hbr      = GetBranchItemRule($item->{'homebranch'}, $item->{'itype'})->{'returnbranch'} || "homebranch";
+        # get the proper branch to which to return the item
+    $hbr = $item->{$hbr} || $branch ;
+        # if $hbr was "noreturn" or any other non-item table value, then it should 'float' (i.e. stay at this branch)
 
     my $borrowernumber = $borrower->{'borrowernumber'} || undef;    # we don't know if we had a borrower or not
 
@@ -1785,18 +1793,16 @@ Internal function, called only by AddReturn that calculate and update the user f
 
 sub _FixFineDaysOnReturn {
     my ( $borrower, $item, $datedue ) = @_;
-
-    if ($datedue) {
-        $datedue = C4::Dates->new( $datedue, "iso" );
-    } else {
-        return;
-    }
+    return unless ($datedue);
+    
+    my $dt_due =  dt_from_string( $datedue );
+    my $dt_today = DateTime->now( time_zone => C4::Context->tz() );
 
     my $branchcode = _GetCircControlBranch( $item, $borrower );
     my $calendar = Koha::Calendar->new( branchcode => $branchcode );
-    my $today = C4::Dates->new();
 
-    my $deltadays = $calendar->daysBetween( $datedue, C4::Dates->new() );
+    # $deltadays is a DateTime::Duration object
+    my $deltadays = $calendar->days_between( $dt_due, $dt_today );
 
     my $circcontrol = C4::Context::preference('CircControl');
     my $issuingrule = GetIssuingRule( $borrower->{categorycode}, $item->{itype}, $branchcode );
@@ -1804,22 +1810,22 @@ sub _FixFineDaysOnReturn {
 
     # exit if no finedays defined
     return unless $finedays;
-    my $grace = $issuingrule->{firstremind};
-
-    if ( $deltadays - $grace > 0 ) {
-        my @newdate = Add_Delta_Days( Today(), $deltadays * $finedays );
-        my $isonewdate = join( '-', @newdate );
-        my ( $deby, $debm, $debd ) = split( /-/, $borrower->{debarred} );
-        if ( check_date( $deby, $debm, $debd ) ) {
-            my @olddate = split( /-/, $borrower->{debarred} );
-
-            if ( Delta_Days( @olddate, @newdate ) > 0 ) {
-                C4::Members::DebarMember( $borrower->{borrowernumber}, $isonewdate );
-                return $isonewdate;
+    my $grace = DateTime::Duration->new( days => $issuingrule->{firstremind} );
+
+    if ( ( $deltadays - $grace )->is_positive ) { # you can't compare DateTime::Durations with logical operators
+        my $new_debar_dt = $dt_today->clone()->add_duration( $deltadays * $finedays );
+        my $borrower_debar_dt = dt_from_string( $borrower->{debarred} );
+        # check to see if the current debar date is a valid date
+        if ( $borrower->{debarred} && $borrower_debar_dt ) {
+        # if so, is it before the new date?  update only if true
+            if ( DateTime->compare( $borrower_debar_dt, $new_debar_dt ) == -1 ) {
+                C4::Members::DebarMember( $borrower->{borrowernumber}, $new_debar_dt->ymd() );
+                return $new_debar_dt->ymd();
             }
+        # if the borrower's debar date is not set or valid, debar them
         } else {
-            C4::Members::DebarMember( $borrower->{borrowernumber}, $isonewdate );
-            return $isonewdate;
+            C4::Members::DebarMember( $borrower->{borrowernumber}, $new_debar_dt->ymd() );
+            return $new_debar_dt->ymd();
         }
     }
 }