Bug 12721: (followup) Replace mysqlism by DBIx::Class
[koha.git] / C4 / HoldsQueue.pm
index 13cb295..4fda2c6 100755 (executable)
@@ -29,14 +29,14 @@ use C4::Branch;
 use C4::Circulation;
 use C4::Members;
 use C4::Biblio;
+use Koha::DateUtils;
 
 use List::Util qw(shuffle);
 use List::MoreUtils qw(any);
 use Data::Dumper;
 
-use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
 BEGIN {
-    $VERSION = 3.03;
     require Exporter;
     @ISA = qw(Exporter);
     @EXPORT_OK = qw(
@@ -63,13 +63,25 @@ sub TransportCostMatrix {
     my $dbh   = C4::Context->dbh;
     my $transport_costs = $dbh->selectall_arrayref("SELECT * FROM transport_cost",{ Slice => {} });
 
+    my $today = dt_from_string();
+    my $calendars;
     my %transport_cost_matrix;
     foreach (@$transport_costs) {
-        my $from = $_->{frombranch};
-        my $to = $_->{tobranch};
-        my $cost = $_->{cost};
+        my $from     = $_->{frombranch};
+        my $to       = $_->{tobranch};
+        my $cost     = $_->{cost};
         my $disabled = $_->{disable_transfer};
-        $transport_cost_matrix{$to}{$from} = { cost => $cost, disable_transfer => $disabled };
+        $transport_cost_matrix{$to}{$from} = {
+            cost             => $cost,
+            disable_transfer => $disabled
+        };
+
+        if ( C4::Context->preference("HoldsQueueSkipClosed") ) {
+            $calendars->{$from} ||= Koha::Calendar->new( branchcode => $from );
+            $transport_cost_matrix{$to}{$from}{disable_transfer} ||=
+              $calendars->{$from}->is_holiday( $today );
+        }
+
     }
     return \%transport_cost_matrix;
 }
@@ -446,7 +458,7 @@ sub MapItemsToHoldRequests {
                 }
             }
             else {
-                warn "No transport costs for $pickup_branch";
+                next;
             }
         }
 
@@ -457,6 +469,8 @@ sub MapItemsToHoldRequests {
             } else {
                 $pull_branches = [keys %items_by_branch];
             }
+
+            # Try picking items where the home and pickup branch match first
             PULL_BRANCHES:
             foreach my $branch (@$pull_branches) {
                 my $holding_branch_items = $items_by_branch{$branch}
@@ -473,6 +487,7 @@ sub MapItemsToHoldRequests {
                 }
             }
 
+            # Now try items from the least cost branch based on the transport cost matrix or StaticHoldsQueueWeight
             unless ( $itemnumber ) {
                 foreach my $current_item ( @{ $items_by_branch{$holdingbranch} } ) {
                     if ( $holdingbranch && ( $current_item->{holdallowed} == 2 || $request->{borrowerbranch} eq $current_item->{homebranch} ) ) {
@@ -481,6 +496,23 @@ sub MapItemsToHoldRequests {
                     }
                 }
             }
+
+            # Now try for items for any item that can fill this hold
+            unless ( $itemnumber ) {
+                PULL_BRANCHES2:
+                foreach my $branch (@$pull_branches) {
+                    my $holding_branch_items = $items_by_branch{$branch}
+                      or next;
+
+                    foreach my $item (@$holding_branch_items) {
+                        next if ( $item->{holdallowed} == 1 && $item->{homebranch} ne $request->{borrowerbranch} );
+
+                        $itemnumber = $item->{itemnumber};
+                        $holdingbranch = $branch;
+                        last PULL_BRANCHES2;
+                    }
+                }
+            }
         }
 
         if ($itemnumber) {
@@ -581,12 +613,27 @@ sub _trim {
 }
 
 sub load_branches_to_pull_from {
-    my $static_branch_list = C4::Context->preference("StaticHoldsQueueWeight")
-      or return;
-
-    my @branches_to_use = map _trim($_), split /,/, $static_branch_list;
-
-    @branches_to_use = shuffle(@branches_to_use) if  C4::Context->preference("RandomizeHoldsQueueWeight");
+    my @branches_to_use;
+
+    my $static_branch_list = C4::Context->preference("StaticHoldsQueueWeight");
+    @branches_to_use = map { _trim($_) } split( /,/, $static_branch_list )
+      if $static_branch_list;
+
+    @branches_to_use =
+      Koha::Database->new()->schema()->resultset('Branch')
+      ->get_column('branchcode')->all()
+      unless (@branches_to_use);
+
+    @branches_to_use = shuffle(@branches_to_use)
+      if C4::Context->preference("RandomizeHoldsQueueWeight");
+
+    my $today = dt_from_string();
+    if ( C4::Context->preference('HoldsQueueSkipClosed') ) {
+        @branches_to_use = grep {
+            !Koha::Calendar->new( branchcode => $_ )
+              ->is_holiday( $today )
+        } @branches_to_use;
+    }
 
     return \@branches_to_use;
 }
@@ -598,7 +645,7 @@ sub least_cost_branch {
 
     # Nothing really spectacular: supply to branch, a list of potential from branches
     # and find the minimum from - to value from the transport_cost_matrix
-    return $from->[0] if @$from == 1;
+    return $from->[0] if ( @$from == 1 && $transport_cost_matrix->{$to}{$from->[0]}->{disable_transfer} != 1 );
 
     # If the pickup library is in the list of libraries to pull from,
     # return that library right away, it is obviously the least costly