Bug 27673: Fix t/Context.t
[koha-ffzg.git] / C4 / Reserves.pm
index 0a38aa3..a658646 100644 (file)
@@ -69,10 +69,13 @@ This modules provides somes functions to deal with reservations.
   The following columns contains important values :
   - priority >0      : then the reserve is at 1st stage, and not yet affected to any item.
              =0      : then the reserve is being dealed
-  - found : NULL       : means the patron requested the 1st available, and we haven't chosen the item
-            T(ransit)  : the reserve is linked to an item but is in transit to the pickup branch
-            W(aiting)  : the reserve is linked to an item, is at the pickup branch, and is waiting on the hold shelf
-            F(inished) : the reserve has been completed, and is done
+  - found : NULL         : means the patron requested the 1st available, and we haven't chosen the item
+            T(ransit)    : the reserve is linked to an item but is in transit to the pickup branch
+            W(aiting)    : the reserve is linked to an item, is at the pickup branch, and is waiting on the hold shelf
+            F(inished)   : the reserve has been completed, and is done
+            P(rocessing) : reserved item has been returned using self-check machine and reserve needs to be confirmed
+                           by librarian before notice is send and status changed to waiting.
+                           Applicable only if HoldsNeedProcessingSIP system preference is set.
   - itemnumber : empty : the reserve is still unaffected to an item
                  filled: the reserve is attached to an item
   The complete workflow is :
@@ -367,9 +370,7 @@ sub CanItemBeReserved {
 
     my $dbh = C4::Context->dbh;
     my $ruleitemtype;    # itemtype of the matching issuing rule
-    my $allowedreserves  = 0; # Total number of holds allowed across all records
-    my $holds_per_record = 1; # Total number of holds allowed for this one given record
-    my $holds_per_day;        # Default to unlimited
+    my $allowedreserves  = 0; # Total number of holds allowed across all records, default to none
 
     # we retrieve borrowers and items informations #
     # item->{itype} will come for biblioitems if necessery
@@ -422,16 +423,30 @@ sub CanItemBeReserved {
     }
 
     # we retrieve rights
-    if ( my $rights = GetHoldRule( $borrower->{'categorycode'}, $item->effective_itemtype, $branchcode ) ) {
-        $ruleitemtype     = $rights->{itemtype};
-        $allowedreserves  = $rights->{reservesallowed} // $allowedreserves;
-        $holds_per_record = $rights->{holds_per_record} // $holds_per_record;
-        $holds_per_day    = $rights->{holds_per_day};
+    if (
+        my $reservesallowed = Koha::CirculationRules->get_effective_rule({
+                itemtype     => $item->effective_itemtype,
+                categorycode => $borrower->{categorycode},
+                branchcode   => $branchcode,
+                rule_name    => 'reservesallowed',
+        })
+    ) {
+        $ruleitemtype     = $reservesallowed->itemtype;
+        $allowedreserves  = $reservesallowed->rule_value // 0; #undefined is 0, blank is unlimited
     }
     else {
         $ruleitemtype = undef;
     }
 
+    my $rights = Koha::CirculationRules->get_effective_rules({
+        categorycode => $borrower->{'categorycode'},
+        itemtype     => $item->effective_itemtype,
+        branchcode   => $branchcode,
+        rules        => ['holds_per_record','holds_per_day']
+    });
+    my $holds_per_record = $rights->{holds_per_record} // 1;
+    my $holds_per_day    = $rights->{holds_per_day};
+
     my $search_params = {
         borrowernumber => $borrowernumber,
         biblionumber   => $item->biblionumber,
@@ -913,6 +928,7 @@ Cancels all reserves with an expiration date from before today.
 =cut
 
 sub CancelExpiredReserves {
+    my $cancellation_reason = shift;
     my $today = dt_from_string();
     my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays');
     my $expireWaiting = C4::Context->preference('ExpireReservesMaxPickUpDelay');
@@ -930,7 +946,8 @@ sub CancelExpiredReserves {
         next if !$cancel_on_holidays && $calendar->is_holiday( $today );
 
         my $cancel_params = {};
-        if ( $hold->found eq 'W' ) {
+        $cancel_params->{cancellation_reason} = $cancellation_reason if defined($cancellation_reason);
+        if ( defined($hold->found) && $hold->found eq 'W' ) {
             $cancel_params->{charge_cancel_fee} = 1;
         }
         $hold->cancel( $cancel_params );
@@ -1134,7 +1151,7 @@ sub ModReserveStatus {
 
 =head2 ModReserveAffect
 
-  &ModReserveAffect($itemnumber,$borrowernumber,$diffBranchSend,$reserve_id);
+  &ModReserveAffect($itemnumber,$borrowernumber,$diffBranchSend,$reserve_id, $desk_id);
 
 This function affect an item and a status for a given reserve, either fetched directly
 by record_id, or by borrowernumber and itemnumber or biblionumber. If only biblionumber
@@ -1148,7 +1165,7 @@ take care of the waiting status
 =cut
 
 sub ModReserveAffect {
-    my ( $itemnumber, $borrowernumber, $transferToDo, $reserve_id ) = @_;
+    my ( $itemnumber, $borrowernumber, $transferToDo, $reserve_id, $desk_id ) = @_;
     my $dbh = C4::Context->dbh;
 
     # we want to attach $itemnumber to $borrowernumber, find the biblionumber
@@ -1181,7 +1198,7 @@ sub ModReserveAffect {
              && !$already_on_shelf) {
         $hold->set_processing();
     } else {
-        $hold->set_waiting();
+        $hold->set_waiting($desk_id);
         _koha_notify_reserve( $hold->reserve_id ) unless $already_on_shelf;
         my $transfers = Koha::Item::Transfers->search({
             itemnumber => $itemnumber,
@@ -1315,7 +1332,7 @@ sub IsAvailableForItemLevelRequest {
             GetReservesControlBranch( $item->unblessed(), $patron->unblessed() );
         my $branchitemrule =
             C4::Circulation::GetBranchItemRule( $reserves_control_branch, $item->itype );
-        my $home_library = Koka::Libraries->find( {branchcode => $item->homebranch} );
+        my $home_library = Koha::Libraries->find( {branchcode => $item->homebranch} );
         return 0 unless $branchitemrule->{hold_fulfillment_policy} ne 'holdgroup' || $home_library->validate_hold_sibling( {branchcode => $pickup_branchcode} );
     }
 
@@ -1853,7 +1870,8 @@ sub _koha_notify_reserve {
         next if (
                ( $mtt eq 'email' and not $to_address ) # No email address
             or ( $mtt eq 'sms'   and not $patron->smsalertnumber ) # No SMS number
-            or ( $mtt eq 'phone' and C4::Context->preference('TalkingTechItivaPhoneNotification') ) # Notice is handled by TalkingTech_itiva_outbound.pl
+            or ( $mtt eq 'itiva' and C4::Context->preference('TalkingTechItivaPhoneNotification') ) # Notice is handled by TalkingTech_itiva_outbound.pl
+            or ( $mtt eq 'phone' and not $patron->phone ) # No phone number to call
         );
 
         &$send_notification($mtt, $letter_code);
@@ -1990,13 +2008,13 @@ sub MergeHolds {
         # don't reorder those already waiting
 
         $sth = $dbh->prepare(
-"SELECT * FROM reserves WHERE biblionumber = ? AND (found <> ? AND found <> ? OR found is NULL) ORDER BY reservedate ASC"
+"SELECT * FROM reserves WHERE biblionumber = ? AND (found NOT IN ('W', 'T', 'P') OR found is NULL) ORDER BY reservedate ASC"
         );
         my $upd_sth = $dbh->prepare(
 "UPDATE reserves SET priority = ? WHERE biblionumber = ? AND borrowernumber = ?
         AND reservedate = ? AND (itemnumber = ? or itemnumber is NULL) "
         );
-        $sth->execute( $to_biblio, 'W', 'T', 'P' );
+        $sth->execute( $to_biblio );
         my $priority = 1;
         while ( my $reserve = $sth->fetchrow_hashref() ) {
             $upd_sth->execute(
@@ -2237,61 +2255,17 @@ sub GetMaxPatronHoldsForRecord {
 
         $branchcode = $item->homebranch if ( $controlbranch eq "ItemHomeLibrary" );
 
-        my $rule = GetHoldRule( $categorycode, $itemtype, $branchcode );
-        my $holds_per_record = $rule ? $rule->{holds_per_record} : 0;
-        $max = $holds_per_record if $holds_per_record > $max;
-    }
-
-    return $max;
-}
-
-=head2 GetHoldRule
-
-my $rule = GetHoldRule( $categorycode, $itemtype, $branchcode );
-
-Returns the matching hold related issuingrule fields for a given
-patron category, itemtype, and library.
-
-=cut
-
-sub GetHoldRule {
-    my ( $categorycode, $itemtype, $branchcode ) = @_;
-
-    my $reservesallowed = Koha::CirculationRules->get_effective_rule(
-        {
-            itemtype     => $itemtype,
+        my $rule = Koha::CirculationRules->get_effective_rule({
             categorycode => $categorycode,
-            branchcode   => $branchcode,
-            rule_name    => 'reservesallowed',
-            order_by     => {
-                -desc => [ 'categorycode', 'itemtype', 'branchcode' ]
-            }
-        }
-    );
-
-    my $rules;
-    if ( $reservesallowed ) {
-        $rules->{reservesallowed} = $reservesallowed->rule_value;
-        $rules->{itemtype}        = $reservesallowed->itemtype;
-        $rules->{categorycode}    = $reservesallowed->categorycode;
-        $rules->{branchcode}      = $reservesallowed->branchcode;
-    }
-
-    my $holds_per_x_rules = Koha::CirculationRules->get_effective_rules(
-        {
             itemtype     => $itemtype,
-            categorycode => $categorycode,
             branchcode   => $branchcode,
-            rules        => ['holds_per_record', 'holds_per_day'],
-            order_by     => {
-                -desc => [ 'categorycode', 'itemtype', 'branchcode' ]
-            }
-        }
-    );
-    $rules->{holds_per_record} = $holds_per_x_rules->{holds_per_record};
-    $rules->{holds_per_day} = $holds_per_x_rules->{holds_per_day};
+            rule_name    => 'holds_per_record'
+        });
+        my $holds_per_record = $rule ? $rule->rule_value : 0;
+        $max = $holds_per_record if $holds_per_record > $max;
+    }
 
-    return $rules;
+    return $max;
 }
 
 =head1 AUTHOR