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 :
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
}
# 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,
=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');
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 );
=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
=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
&& !$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,
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} );
}
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);
# 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(
$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