|
Lines 38-49
use Koha::Calendar;
Link Here
|
| 38 |
use Koha::CirculationRules; |
38 |
use Koha::CirculationRules; |
| 39 |
use Koha::Database; |
39 |
use Koha::Database; |
| 40 |
use Koha::DateUtils; |
40 |
use Koha::DateUtils; |
| 41 |
use Koha::Hold; |
|
|
| 42 |
use Koha::Holds; |
41 |
use Koha::Holds; |
| 43 |
use Koha::ItemTypes; |
42 |
use Koha::ItemTypes; |
| 44 |
use Koha::Items; |
43 |
use Koha::Items; |
| 45 |
use Koha::Libraries; |
44 |
use Koha::Libraries; |
| 46 |
use Koha::Old::Hold; |
|
|
| 47 |
use Koha::Patrons; |
45 |
use Koha::Patrons; |
| 48 |
use Koha::Plugins; |
46 |
use Koha::Plugins; |
| 49 |
|
47 |
|
|
Lines 186-192
sub AddReserve {
Link Here
|
| 186 |
my $notes = $params->{notes}; |
184 |
my $notes = $params->{notes}; |
| 187 |
my $title = $params->{title}; |
185 |
my $title = $params->{title}; |
| 188 |
my $checkitem = $params->{itemnumber}; |
186 |
my $checkitem = $params->{itemnumber}; |
| 189 |
my $found = $params->{found}; |
187 |
my $found = $params->{found} // 'placed'; |
| 190 |
my $itemtype = $params->{itemtype}; |
188 |
my $itemtype = $params->{itemtype}; |
| 191 |
my $non_priority = $params->{non_priority}; |
189 |
my $non_priority = $params->{non_priority}; |
| 192 |
|
190 |
|
|
Lines 217-223
sub AddReserve {
Link Here
|
| 217 |
&& !$item->current_holds->count ) |
215 |
&& !$item->current_holds->count ) |
| 218 |
{ |
216 |
{ |
| 219 |
$priority = 0; |
217 |
$priority = 0; |
| 220 |
$found = 'W'; |
218 |
$found = 'waiting'; |
| 221 |
} |
219 |
} |
| 222 |
} |
220 |
} |
| 223 |
|
221 |
|
|
Lines 230-236
sub AddReserve {
Link Here
|
| 230 |
my $waitingdate; |
228 |
my $waitingdate; |
| 231 |
|
229 |
|
| 232 |
# If the reserv had the waiting status, we had the value of the resdate |
230 |
# If the reserv had the waiting status, we had the value of the resdate |
| 233 |
if ( $found && $found eq 'W' ) { |
231 |
if ( $found and $found eq 'waiting' ) { |
| 234 |
$waitingdate = $resdate; |
232 |
$waitingdate = $resdate; |
| 235 |
} |
233 |
} |
| 236 |
|
234 |
|
|
Lines 240-261
sub AddReserve {
Link Here
|
| 240 |
# updates take place here |
238 |
# updates take place here |
| 241 |
my $hold = Koha::Hold->new( |
239 |
my $hold = Koha::Hold->new( |
| 242 |
{ |
240 |
{ |
| 243 |
borrowernumber => $borrowernumber, |
241 |
patron_id => $borrowernumber, |
| 244 |
biblionumber => $biblionumber, |
242 |
biblio_id => $biblionumber, |
| 245 |
reservedate => $resdate, |
243 |
created_date => $resdate, |
| 246 |
branchcode => $branch, |
244 |
pickup_library_id => $branch, |
| 247 |
priority => $priority, |
245 |
priority => $priority, |
| 248 |
reservenotes => $notes, |
246 |
notes => $notes, |
| 249 |
itemnumber => $checkitem, |
247 |
item_id => $checkitem, |
| 250 |
found => $found, |
248 |
waiting_date => $waitingdate, |
| 251 |
waitingdate => $waitingdate, |
249 |
expiration_date => $expdate, |
| 252 |
expirationdate => $expdate, |
250 |
item_type => $itemtype, |
| 253 |
itemtype => $itemtype, |
251 |
item_level => $checkitem ? 1 : 0, |
| 254 |
item_level_hold => $checkitem ? 1 : 0, |
|
|
| 255 |
non_priority => $non_priority ? 1 : 0, |
252 |
non_priority => $non_priority ? 1 : 0, |
| 256 |
} |
253 |
} |
| 257 |
)->store(); |
254 |
)->store(); |
| 258 |
$hold->set_waiting() if $found && $found eq 'W'; |
255 |
$hold->set_waiting() if $found eq 'waiting'; |
| 259 |
|
256 |
|
| 260 |
logaction( 'HOLDS', 'CREATE', $hold->id, Dumper($hold->unblessed) ) |
257 |
logaction( 'HOLDS', 'CREATE', $hold->id, Dumper($hold->unblessed) ) |
| 261 |
if C4::Context->preference('HoldsLog'); |
258 |
if C4::Context->preference('HoldsLog'); |
|
Lines 391-397
sub CanItemBeReserved {
Link Here
|
| 391 |
|
388 |
|
| 392 |
# Check that the patron doesn't have an item level hold on this item already |
389 |
# Check that the patron doesn't have an item level hold on this item already |
| 393 |
return { status =>'itemAlreadyOnHold' } |
390 |
return { status =>'itemAlreadyOnHold' } |
| 394 |
if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count(); |
391 |
if Koha::Holds->search( { patron_id => $borrowernumber, item_id => $itemnumber, completed => 0 } )->count(); |
| 395 |
|
392 |
|
| 396 |
# Check that patron have not checked out this biblio (if AllowHoldsOnPatronsPossessions set) |
393 |
# Check that patron have not checked out this biblio (if AllowHoldsOnPatronsPossessions set) |
| 397 |
if ( !C4::Context->preference('AllowHoldsOnPatronsPossessions') |
394 |
if ( !C4::Context->preference('AllowHoldsOnPatronsPossessions') |
|
Lines 403-417
sub CanItemBeReserved {
Link Here
|
| 403 |
|
400 |
|
| 404 |
my $querycount = q{ |
401 |
my $querycount = q{ |
| 405 |
SELECT count(*) AS count |
402 |
SELECT count(*) AS count |
| 406 |
FROM reserves |
403 |
FROM holds |
| 407 |
LEFT JOIN items USING (itemnumber) |
404 |
LEFT JOIN items ON (holds.item_id=items.itemnumber) |
| 408 |
LEFT JOIN biblioitems ON (reserves.biblionumber=biblioitems.biblionumber) |
405 |
LEFT JOIN biblioitems ON (holds.biblio_id=biblioitems.biblionumber) |
| 409 |
LEFT JOIN borrowers USING (borrowernumber) |
406 |
LEFT JOIN borrowers ON (holds.patron_id=borrowers.borrowernumber) |
| 410 |
WHERE borrowernumber = ? |
407 |
WHERE completed = 0 and borrowernumber = ? |
| 411 |
}; |
408 |
}; |
| 412 |
|
409 |
|
| 413 |
my $branchcode = ""; |
410 |
my $branchcode = ""; |
| 414 |
my $branchfield = "reserves.branchcode"; |
411 |
my $branchfield = "holds.pickup_library_id"; |
| 415 |
|
412 |
|
| 416 |
if ( $controlbranch eq "ItemHomeLibrary" ) { |
413 |
if ( $controlbranch eq "ItemHomeLibrary" ) { |
| 417 |
$branchfield = "items.homebranch"; |
414 |
$branchfield = "items.homebranch"; |
|
Lines 448-457
sub CanItemBeReserved {
Link Here
|
| 448 |
my $holds_per_day = $rights->{holds_per_day}; |
445 |
my $holds_per_day = $rights->{holds_per_day}; |
| 449 |
|
446 |
|
| 450 |
my $search_params = { |
447 |
my $search_params = { |
| 451 |
borrowernumber => $borrowernumber, |
448 |
patron_id => $borrowernumber, |
| 452 |
biblionumber => $item->biblionumber, |
449 |
biblio_id => $item->biblionumber, |
|
|
450 |
completed => 0, |
| 453 |
}; |
451 |
}; |
| 454 |
$search_params->{found} = undef if $params->{ignore_found_holds}; |
452 |
$search_params->{status} = 'placed' if $params->{ignore_found_holds}; |
| 455 |
|
453 |
|
| 456 |
my $holds = Koha::Holds->search($search_params); |
454 |
my $holds = Koha::Holds->search($search_params); |
| 457 |
if ( defined $holds_per_record && $holds_per_record ne '' |
455 |
if ( defined $holds_per_record && $holds_per_record ne '' |
|
Lines 460-467
sub CanItemBeReserved {
Link Here
|
| 460 |
} |
458 |
} |
| 461 |
|
459 |
|
| 462 |
my $today_holds = Koha::Holds->search({ |
460 |
my $today_holds = Koha::Holds->search({ |
| 463 |
borrowernumber => $borrowernumber, |
461 |
patron_id => $borrowernumber, |
| 464 |
reservedate => dt_from_string->date |
462 |
created_date => dt_from_string->date, |
|
|
463 |
completed => 0 |
| 465 |
}); |
464 |
}); |
| 466 |
|
465 |
|
| 467 |
if ( defined $holds_per_day && $holds_per_day ne '' |
466 |
if ( defined $holds_per_day && $holds_per_day ne '' |
|
Lines 513-519
sub CanItemBeReserved {
Link Here
|
| 513 |
if ( $rule && defined( $rule->rule_value ) && $rule->rule_value ne '' ) { |
512 |
if ( $rule && defined( $rule->rule_value ) && $rule->rule_value ne '' ) { |
| 514 |
my $total_holds_count = Koha::Holds->search( |
513 |
my $total_holds_count = Koha::Holds->search( |
| 515 |
{ |
514 |
{ |
| 516 |
borrowernumber => $borrower->{borrowernumber} |
515 |
patron_id => $borrower->{borrowernumber}, |
|
|
516 |
completed => 0 |
| 517 |
} |
517 |
} |
| 518 |
)->count(); |
518 |
)->count(); |
| 519 |
|
519 |
|
|
Lines 591-600
sub CanReserveBeCanceledFromOpac {
Link Here
|
| 591 |
my ($reserve_id, $borrowernumber) = @_; |
591 |
my ($reserve_id, $borrowernumber) = @_; |
| 592 |
|
592 |
|
| 593 |
return unless $reserve_id and $borrowernumber; |
593 |
return unless $reserve_id and $borrowernumber; |
| 594 |
my $reserve = Koha::Holds->find($reserve_id); |
594 |
my $hold = Koha::Holds->find($reserve_id); |
| 595 |
|
595 |
|
| 596 |
return 0 unless $reserve->borrowernumber == $borrowernumber; |
596 |
return 0 unless $hold->patron_id == $borrowernumber; |
| 597 |
return $reserve->is_cancelable_from_opac; |
597 |
return $hold->is_cancelable_from_opac; |
| 598 |
} |
598 |
} |
| 599 |
|
599 |
|
| 600 |
=head2 GetOtherReserves |
600 |
=head2 GetOtherReserves |
|
Lines 612-630
sub GetOtherReserves {
Link Here
|
| 612 |
my ( undef, $checkreserves, undef ) = CheckReserves($itemnumber); |
612 |
my ( undef, $checkreserves, undef ) = CheckReserves($itemnumber); |
| 613 |
if ($checkreserves) { |
613 |
if ($checkreserves) { |
| 614 |
my $item = Koha::Items->find($itemnumber); |
614 |
my $item = Koha::Items->find($itemnumber); |
| 615 |
if ( $item->holdingbranch ne $checkreserves->{'branchcode'} ) { |
615 |
if ( $item->holdingbranch ne $checkreserves->{pickup_library_id} ) { |
| 616 |
$messages->{'transfert'} = $checkreserves->{'branchcode'}; |
616 |
$messages->{'transfert'} = $checkreserves->{pickup_library_id}; |
| 617 |
#minus priorities of others reservs |
617 |
#minus priorities of others reservs |
| 618 |
ModReserveMinusPriority( |
618 |
ModReserveMinusPriority( |
| 619 |
$itemnumber, |
619 |
$itemnumber, |
| 620 |
$checkreserves->{'reserve_id'}, |
620 |
$checkreserves->{id}, |
| 621 |
); |
621 |
); |
| 622 |
|
622 |
|
| 623 |
#launch the subroutine dotransfer |
623 |
#launch the subroutine dotransfer |
| 624 |
C4::Items::ModItemTransfer( |
624 |
C4::Items::ModItemTransfer( |
| 625 |
$itemnumber, |
625 |
$itemnumber, |
| 626 |
$item->holdingbranch, |
626 |
$item->holdingbranch, |
| 627 |
$checkreserves->{'branchcode'}, |
627 |
$checkreserves->{pickup_library_id}, |
| 628 |
'Reserve' |
628 |
'Reserve' |
| 629 |
), |
629 |
), |
| 630 |
; |
630 |
; |
|
Lines 635-643
sub GetOtherReserves {
Link Here
|
| 635 |
$messages->{'waiting'} = 1; |
635 |
$messages->{'waiting'} = 1; |
| 636 |
ModReserveMinusPriority( |
636 |
ModReserveMinusPriority( |
| 637 |
$itemnumber, |
637 |
$itemnumber, |
| 638 |
$checkreserves->{'reserve_id'}, |
638 |
$checkreserves->{id}, |
| 639 |
); |
639 |
); |
| 640 |
ModReserveStatus($itemnumber,'W'); |
640 |
ModReserveStatus($itemnumber,'waiting'); |
| 641 |
} |
641 |
} |
| 642 |
|
642 |
|
| 643 |
$nextreservinfo = $checkreserves; |
643 |
$nextreservinfo = $checkreserves; |
|
Lines 728-752
If several reserves exist, the reserve with the lower priority is given.
Link Here
|
| 728 |
## multiple reserves for that bib can have the itemnumber set |
728 |
## multiple reserves for that bib can have the itemnumber set |
| 729 |
## the sub is only used once in the codebase. |
729 |
## the sub is only used once in the codebase. |
| 730 |
sub GetReserveStatus { |
730 |
sub GetReserveStatus { |
| 731 |
my ($itemnumber) = @_; |
731 |
my ($item_id) = @_; |
| 732 |
|
732 |
|
| 733 |
my $dbh = C4::Context->dbh; |
733 |
my $holds_rs = Koha::Holds->search({ item_id => $item_id, completed => 0 }, { order_by => 'priority' }); |
| 734 |
|
734 |
|
| 735 |
my ($sth, $found, $priority); |
735 |
if ( $holds_rs->count > 0 ) { |
| 736 |
if ( $itemnumber ) { |
736 |
# They are sorted by priority, pick the first one |
| 737 |
$sth = $dbh->prepare("SELECT found, priority FROM reserves WHERE itemnumber = ? order by priority LIMIT 1"); |
737 |
my $hold = $holds_rs->next; |
| 738 |
$sth->execute($itemnumber); |
|
|
| 739 |
($found, $priority) = $sth->fetchrow_array; |
| 740 |
} |
| 741 |
|
738 |
|
| 742 |
if(defined $found) { |
739 |
return 'Waiting' if $hold->is_waiting and $hold->priority == 0; |
| 743 |
return 'Waiting' if $found eq 'W' and $priority == 0; |
740 |
return 'Processing' if $hold->is_in_processing; |
| 744 |
return 'Processing' if $found eq 'P'; |
741 |
return 'Finished' if $hold->status eq 'fulfilled'; |
| 745 |
return 'Finished' if $found eq 'F'; |
742 |
return 'Reserved' if $hold->priority > 0; |
| 746 |
} |
743 |
} |
| 747 |
|
744 |
|
| 748 |
return 'Reserved' if defined $priority && $priority > 0; |
|
|
| 749 |
|
| 750 |
return ''; # empty string here will remove need for checking undef, or less log lines |
745 |
return ''; # empty string here will remove need for checking undef, or less log lines |
| 751 |
} |
746 |
} |
| 752 |
|
747 |
|
|
Lines 785-791
sub CheckReserves {
Link Here
|
| 785 |
my $sth; |
780 |
my $sth; |
| 786 |
my $select; |
781 |
my $select; |
| 787 |
if (C4::Context->preference('item-level_itypes')){ |
782 |
if (C4::Context->preference('item-level_itypes')){ |
| 788 |
$select = " |
783 |
$select = " |
| 789 |
SELECT items.biblionumber, |
784 |
SELECT items.biblionumber, |
| 790 |
items.biblioitemnumber, |
785 |
items.biblioitemnumber, |
| 791 |
itemtypes.notforloan, |
786 |
itemtypes.notforloan, |
|
Lines 800-806
sub CheckReserves {
Link Here
|
| 800 |
"; |
795 |
"; |
| 801 |
} |
796 |
} |
| 802 |
else { |
797 |
else { |
| 803 |
$select = " |
798 |
$select = " |
| 804 |
SELECT items.biblionumber, |
799 |
SELECT items.biblionumber, |
| 805 |
items.biblioitemnumber, |
800 |
items.biblioitemnumber, |
| 806 |
itemtypes.notforloan, |
801 |
itemtypes.notforloan, |
|
Lines 853-862
sub CheckReserves {
Link Here
|
| 853 |
|
848 |
|
| 854 |
my $priority = 10000000; |
849 |
my $priority = 10000000; |
| 855 |
foreach my $res (@reserves) { |
850 |
foreach my $res (@reserves) { |
| 856 |
if ( $res->{'itemnumber'} && $res->{'itemnumber'} == $itemnumber && $res->{'priority'} == 0) { |
851 |
if ( $res->{item_id} && $res->{item_id} == $itemnumber && $res->{priority} == 0) { |
| 857 |
if ($res->{'found'} eq 'W') { |
852 |
if ($res->{status} eq 'waiting') { |
| 858 |
return ( "Waiting", $res, \@reserves ); # Found it, it is waiting |
853 |
return ( "Waiting", $res, \@reserves ); # Found it, it is waiting |
| 859 |
} elsif ($res->{'found'} eq 'P') { |
854 |
} elsif ($res->{'status'} eq 'processing') { |
| 860 |
return ( "Processing", $res, \@reserves ); # Found determinated hold, e. g. the transferred one |
855 |
return ( "Processing", $res, \@reserves ); # Found determinated hold, e. g. the transferred one |
| 861 |
} else { |
856 |
} else { |
| 862 |
return ( "Reserved", $res, \@reserves ); # Found determinated hold, e. g. the transferred one |
857 |
return ( "Reserved", $res, \@reserves ); # Found determinated hold, e. g. the transferred one |
|
Lines 867-873
sub CheckReserves {
Link Here
|
| 867 |
my $local_hold_match; |
862 |
my $local_hold_match; |
| 868 |
|
863 |
|
| 869 |
if ($LocalHoldsPriority) { |
864 |
if ($LocalHoldsPriority) { |
| 870 |
$patron = Koha::Patrons->find( $res->{borrowernumber} ); |
865 |
$patron = Koha::Patrons->find( $res->{patron_id} ); |
| 871 |
$item = Koha::Items->find($itemnumber); |
866 |
$item = Koha::Items->find($itemnumber); |
| 872 |
|
867 |
|
| 873 |
unless ($item->exclude_from_local_holds_priority || $patron->category->exclude_from_local_holds_priority) { |
868 |
unless ($item->exclude_from_local_holds_priority || $patron->category->exclude_from_local_holds_priority) { |
|
Lines 875-881
sub CheckReserves {
Link Here
|
| 875 |
$item->$LocalHoldsPriorityItemControl; |
870 |
$item->$LocalHoldsPriorityItemControl; |
| 876 |
my $local_holds_priority_patron_branchcode = |
871 |
my $local_holds_priority_patron_branchcode = |
| 877 |
( $LocalHoldsPriorityPatronControl eq 'PickupLibrary' ) |
872 |
( $LocalHoldsPriorityPatronControl eq 'PickupLibrary' ) |
| 878 |
? $res->{branchcode} |
873 |
? $res->{pickup_library_id} |
| 879 |
: ( $LocalHoldsPriorityPatronControl eq 'HomeLibrary' ) |
874 |
: ( $LocalHoldsPriorityPatronControl eq 'HomeLibrary' ) |
| 880 |
? $patron->branchcode |
875 |
? $patron->branchcode |
| 881 |
: undef; |
876 |
: undef; |
|
Lines 886-895
sub CheckReserves {
Link Here
|
| 886 |
} |
881 |
} |
| 887 |
|
882 |
|
| 888 |
# See if this item is more important than what we've got so far |
883 |
# See if this item is more important than what we've got so far |
| 889 |
if ( ( $res->{'priority'} && $res->{'priority'} < $priority ) || $local_hold_match ) { |
884 |
if ( ( $res->{priority} && $res->{priority} < $priority ) || $local_hold_match ) { |
| 890 |
$item ||= Koha::Items->find($itemnumber); |
885 |
$item ||= Koha::Items->find($itemnumber); |
| 891 |
next if $res->{itemtype} && $res->{itemtype} ne $item->effective_itemtype; |
886 |
next if $res->{item_type} && $res->{item_type} ne $item->effective_itemtype; |
| 892 |
$patron ||= Koha::Patrons->find( $res->{borrowernumber} ); |
887 |
$patron ||= Koha::Patrons->find( $res->{patron_id} ); |
| 893 |
my $branch = GetReservesControlBranch( $item->unblessed, $patron->unblessed ); |
888 |
my $branch = GetReservesControlBranch( $item->unblessed, $patron->unblessed ); |
| 894 |
my $branchitemrule = C4::Circulation::GetBranchItemRule($branch,$item->effective_itemtype); |
889 |
my $branchitemrule = C4::Circulation::GetBranchItemRule($branch,$item->effective_itemtype); |
| 895 |
next if ($branchitemrule->{'holdallowed'} == 0); |
890 |
next if ($branchitemrule->{'holdallowed'} == 0); |
|
Lines 897-906
sub CheckReserves {
Link Here
|
| 897 |
my $library = Koha::Libraries->find({branchcode=>$item->homebranch}); |
892 |
my $library = Koha::Libraries->find({branchcode=>$item->homebranch}); |
| 898 |
next if (($branchitemrule->{'holdallowed'} == 3) && (!$library->validate_hold_sibling({branchcode => $patron->branchcode}) )); |
893 |
next if (($branchitemrule->{'holdallowed'} == 3) && (!$library->validate_hold_sibling({branchcode => $patron->branchcode}) )); |
| 899 |
my $hold_fulfillment_policy = $branchitemrule->{hold_fulfillment_policy}; |
894 |
my $hold_fulfillment_policy = $branchitemrule->{hold_fulfillment_policy}; |
| 900 |
next if ( ($hold_fulfillment_policy eq 'holdgroup') && (!$library->validate_hold_sibling({branchcode => $res->{branchcode}})) ); |
895 |
next if ( ($hold_fulfillment_policy eq 'holdgroup') && (!$library->validate_hold_sibling({branchcode => $res->{pickup_library_id}})) ); |
| 901 |
next if ( ($hold_fulfillment_policy eq 'homebranch') && ($res->{branchcode} ne $item->$hold_fulfillment_policy) ); |
896 |
next if ( ($hold_fulfillment_policy eq 'homebranch') && ($res->{pickup_library_id} ne $item->$hold_fulfillment_policy) ); |
| 902 |
next if ( ($hold_fulfillment_policy eq 'holdingbranch') && ($res->{branchcode} ne $item->$hold_fulfillment_policy) ); |
897 |
next if ( ($hold_fulfillment_policy eq 'holdingbranch') && ($res->{pickup_library_id} ne $item->$hold_fulfillment_policy) ); |
| 903 |
next unless $item->can_be_transferred( { to => Koha::Libraries->find( $res->{branchcode} ) } ); |
898 |
next unless $item->can_be_transferred( { to => Koha::Libraries->find( $res->{pickup_library_id} ) } ); |
| 904 |
$priority = $res->{'priority'}; |
899 |
$priority = $res->{'priority'}; |
| 905 |
$highest = $res; |
900 |
$highest = $res; |
| 906 |
last if $local_hold_match; |
901 |
last if $local_hold_match; |
|
Lines 934-953
sub CancelExpiredReserves {
Link Here
|
| 934 |
my $expireWaiting = C4::Context->preference('ExpireReservesMaxPickUpDelay'); |
929 |
my $expireWaiting = C4::Context->preference('ExpireReservesMaxPickUpDelay'); |
| 935 |
|
930 |
|
| 936 |
my $dtf = Koha::Database->new->schema->storage->datetime_parser; |
931 |
my $dtf = Koha::Database->new->schema->storage->datetime_parser; |
| 937 |
my $params = { expirationdate => { '<', $dtf->format_date($today) } }; |
932 |
my $params = { expiration_date => { '<', $dtf->format_date($today) } }; |
| 938 |
$params->{found} = [ { '!=', 'W' }, undef ] unless $expireWaiting; |
933 |
$params->{status} = [ { '!=', 'waiting' }, undef ] unless $expireWaiting; |
| 939 |
|
934 |
|
| 940 |
# FIXME To move to Koha::Holds->search_expired (?) |
935 |
# FIXME To move to Koha::Holds->search_expired (?) |
| 941 |
my $holds = Koha::Holds->search( $params ); |
936 |
my $holds = Koha::Holds->search( $params ); |
| 942 |
|
937 |
|
| 943 |
while ( my $hold = $holds->next ) { |
938 |
while ( my $hold = $holds->next ) { |
| 944 |
my $calendar = Koha::Calendar->new( branchcode => $hold->branchcode ); |
939 |
my $calendar = Koha::Calendar->new( branchcode => $hold->pickup_library_id ); |
| 945 |
|
940 |
|
| 946 |
next if !$cancel_on_holidays && $calendar->is_holiday( $today ); |
941 |
next if !$cancel_on_holidays && $calendar->is_holiday( $today ); |
| 947 |
|
942 |
|
| 948 |
my $cancel_params = {}; |
943 |
my $cancel_params = {}; |
| 949 |
$cancel_params->{cancellation_reason} = $cancellation_reason if defined($cancellation_reason); |
944 |
$cancel_params->{cancellation_reason} = $cancellation_reason if defined($cancellation_reason); |
| 950 |
if ( defined($hold->found) && $hold->found eq 'W' ) { |
945 |
if ( $hold->is_waiting ) { |
| 951 |
$cancel_params->{charge_cancel_fee} = 1; |
946 |
$cancel_params->{charge_cancel_fee} = 1; |
| 952 |
} |
947 |
} |
| 953 |
$hold->cancel( $cancel_params ); |
948 |
$hold->cancel( $cancel_params ); |
|
Lines 958-971
sub CancelExpiredReserves {
Link Here
|
| 958 |
|
953 |
|
| 959 |
AutoUnsuspendReserves(); |
954 |
AutoUnsuspendReserves(); |
| 960 |
|
955 |
|
| 961 |
Unsuspends all suspended reserves with a suspend_until date from before today. |
956 |
Unsuspends all suspended reserves with a suspended_until date from before today. |
| 962 |
|
957 |
|
| 963 |
=cut |
958 |
=cut |
| 964 |
|
959 |
|
| 965 |
sub AutoUnsuspendReserves { |
960 |
sub AutoUnsuspendReserves { |
| 966 |
my $today = dt_from_string(); |
961 |
my $today = dt_from_string(); |
| 967 |
|
962 |
|
| 968 |
my @holds = Koha::Holds->search( { suspend_until => { '<=' => $today->ymd() } } ); |
963 |
my @holds = Koha::Holds->search( { suspended_until_date => { '<=' => $today->ymd() } } ); |
| 969 |
|
964 |
|
| 970 |
map { $_->resume() } @holds; |
965 |
map { $_->resume() } @holds; |
| 971 |
} |
966 |
} |
|
Lines 1025-1034
sub ModReserve {
Link Here
|
| 1025 |
|
1020 |
|
| 1026 |
my $hold; |
1021 |
my $hold; |
| 1027 |
unless ( $reserve_id ) { |
1022 |
unless ( $reserve_id ) { |
| 1028 |
my $holds = Koha::Holds->search({ biblionumber => $biblionumber, borrowernumber => $borrowernumber, itemnumber => $itemnumber }); |
1023 |
my $holds = Koha::Holds->search({ biblio_id => $biblionumber, patron_id => $borrowernumber, item_id => $itemnumber }); |
| 1029 |
return unless $holds->count; # FIXME Should raise an exception |
1024 |
return unless $holds->count; # FIXME Should raise an exception |
| 1030 |
$hold = $holds->next; |
1025 |
$hold = $holds->next; |
| 1031 |
$reserve_id = $hold->reserve_id; |
1026 |
$reserve_id = $hold->id; |
| 1032 |
} |
1027 |
} |
| 1033 |
|
1028 |
|
| 1034 |
$hold ||= Koha::Holds->find($reserve_id); |
1029 |
$hold ||= Koha::Holds->find($reserve_id); |
|
Lines 1037-1057
sub ModReserve {
Link Here
|
| 1037 |
$hold->cancel({ cancellation_reason => $cancellation_reason }); |
1032 |
$hold->cancel({ cancellation_reason => $cancellation_reason }); |
| 1038 |
} |
1033 |
} |
| 1039 |
elsif ($rank =~ /^\d+/ and $rank > 0) { |
1034 |
elsif ($rank =~ /^\d+/ and $rank > 0) { |
| 1040 |
logaction( 'HOLDS', 'MODIFY', $hold->reserve_id, Dumper($hold->unblessed) ) |
1035 |
logaction( 'HOLDS', 'MODIFY', $hold->id, Dumper($hold->unblessed) ) |
| 1041 |
if C4::Context->preference('HoldsLog'); |
1036 |
if C4::Context->preference('HoldsLog'); |
| 1042 |
|
1037 |
|
| 1043 |
my $properties = { |
1038 |
my $properties = { |
| 1044 |
priority => $rank, |
1039 |
priority => $rank, |
| 1045 |
branchcode => $branchcode, |
1040 |
pickup_library_id => $branchcode, |
| 1046 |
itemnumber => $itemnumber, |
1041 |
item_id => $itemnumber, |
| 1047 |
found => undef, |
1042 |
status => 'placed', |
| 1048 |
waitingdate => undef |
1043 |
waiting_date => undef |
| 1049 |
}; |
1044 |
}; |
| 1050 |
if (exists $params->{reservedate}) { |
1045 |
if (exists $params->{reservedate}) { |
| 1051 |
$properties->{reservedate} = $params->{reservedate} || undef; |
1046 |
$properties->{created_date} = $params->{reservedate} || undef; |
| 1052 |
} |
1047 |
} |
| 1053 |
if (exists $params->{expirationdate}) { |
1048 |
if (exists $params->{expirationdate}) { |
| 1054 |
$properties->{expirationdate} = $params->{expirationdate} || undef; |
1049 |
$properties->{expiration_date} = $params->{expirationdate} || undef; |
| 1055 |
} |
1050 |
} |
| 1056 |
|
1051 |
|
| 1057 |
$hold->set($properties)->store(); |
1052 |
$hold->set($properties)->store(); |
|
Lines 1063-1069
sub ModReserve {
Link Here
|
| 1063 |
} else { |
1058 |
} else { |
| 1064 |
# If the hold is suspended leave the hold suspended, but convert it to an indefinite hold. |
1059 |
# If the hold is suspended leave the hold suspended, but convert it to an indefinite hold. |
| 1065 |
# If the hold is not suspended, this does nothing. |
1060 |
# If the hold is not suspended, this does nothing. |
| 1066 |
$hold->set( { suspend_until => undef } )->store(); |
1061 |
$hold->set( { suspended_until_date => undef } )->store(); |
| 1067 |
} |
1062 |
} |
| 1068 |
} |
1063 |
} |
| 1069 |
|
1064 |
|
|
Lines 1085-1121
whose keys are fields from the reserves table in the Koha database.
Link Here
|
| 1085 |
|
1080 |
|
| 1086 |
sub ModReserveFill { |
1081 |
sub ModReserveFill { |
| 1087 |
my ($res) = @_; |
1082 |
my ($res) = @_; |
| 1088 |
my $reserve_id = $res->{'reserve_id'}; |
1083 |
my $reserve_id = $res->{'id'}; |
| 1089 |
|
1084 |
|
| 1090 |
my $hold = Koha::Holds->find($reserve_id); |
1085 |
my $hold = Koha::Holds->find($reserve_id); |
| 1091 |
# get the priority on this record.... |
1086 |
# get the priority on this record.... |
| 1092 |
my $priority = $hold->priority; |
1087 |
my $priority = $hold->priority; |
| 1093 |
|
1088 |
|
| 1094 |
# update the hold statuses, no need to store it though, we will be deleting it anyway |
1089 |
# update the hold statuses, no need to store it though, we will be deleting it anyway |
|
|
1090 |
# FIXME: Add Koha::Hold->set_filled and add the correct log |
| 1095 |
$hold->set( |
1091 |
$hold->set( |
| 1096 |
{ |
1092 |
{ |
| 1097 |
found => 'F', |
1093 |
status => 'fulfilled', |
| 1098 |
priority => 0, |
1094 |
priority => 0, |
|
|
1095 |
completed => 1, |
| 1096 |
completed_date => \'NOW()' |
| 1099 |
} |
1097 |
} |
| 1100 |
); |
1098 |
); |
| 1101 |
|
1099 |
|
| 1102 |
logaction( 'HOLDS', 'MODIFY', $hold->reserve_id, Dumper($hold->unblessed) ) |
1100 |
logaction( 'HOLDS', 'MODIFY', $hold->id, Dumper($hold->unblessed) ) |
| 1103 |
if C4::Context->preference('HoldsLog'); |
1101 |
if C4::Context->preference('HoldsLog'); |
| 1104 |
|
1102 |
|
| 1105 |
# FIXME Must call Koha::Hold->cancel ? => No, should call ->filled and add the correct log |
1103 |
$hold->store(); |
| 1106 |
Koha::Old::Hold->new( $hold->unblessed() )->store(); |
|
|
| 1107 |
|
| 1108 |
$hold->delete(); |
| 1109 |
|
1104 |
|
| 1110 |
if ( C4::Context->preference('HoldFeeMode') eq 'any_time_is_collected' ) { |
1105 |
if ( C4::Context->preference('HoldFeeMode') eq 'any_time_is_collected' ) { |
| 1111 |
my $reserve_fee = GetReserveFee( $hold->borrowernumber, $hold->biblionumber ); |
1106 |
my $reserve_fee = GetReserveFee( $hold->patron_id, $hold->biblio_id ); |
| 1112 |
ChargeReserveFee( $hold->borrowernumber, $reserve_fee, $hold->biblio->title ); |
1107 |
ChargeReserveFee( $hold->patron_id, $reserve_fee, $hold->biblio->title ); |
| 1113 |
} |
1108 |
} |
| 1114 |
|
1109 |
|
| 1115 |
# now fix the priority on the others (if the priority wasn't |
1110 |
# now fix the priority on the others (if the priority wasn't |
| 1116 |
# already sorted!).... |
1111 |
# already sorted!).... |
| 1117 |
unless ( $priority == 0 ) { |
1112 |
unless ( $priority == 0 ) { |
| 1118 |
_FixPriority( { reserve_id => $reserve_id, biblionumber => $hold->biblionumber } ); |
1113 |
_FixPriority( { reserve_id => $reserve_id, biblionumber => $hold->biblio_id } ); |
| 1119 |
} |
1114 |
} |
| 1120 |
} |
1115 |
} |
| 1121 |
|
1116 |
|
|
Lines 1137-1143
sub ModReserveStatus {
Link Here
|
| 1137 |
my ($itemnumber, $newstatus) = @_; |
1132 |
my ($itemnumber, $newstatus) = @_; |
| 1138 |
my $dbh = C4::Context->dbh; |
1133 |
my $dbh = C4::Context->dbh; |
| 1139 |
|
1134 |
|
| 1140 |
my $query = "UPDATE reserves SET found = ?, waitingdate = NOW() WHERE itemnumber = ? AND found IS NULL AND priority = 0"; |
1135 |
my $query = "UPDATE holds SET status = ?, waiting_date = NOW() WHERE item_id = ? AND status='placed' AND priority = 0"; |
| 1141 |
my $sth_set = $dbh->prepare($query); |
1136 |
my $sth_set = $dbh->prepare($query); |
| 1142 |
$sth_set->execute( $newstatus, $itemnumber ); |
1137 |
$sth_set->execute( $newstatus, $itemnumber ); |
| 1143 |
|
1138 |
|
|
Lines 1181-1195
sub ModReserveAffect {
Link Here
|
| 1181 |
# Find hold by id if we have it |
1176 |
# Find hold by id if we have it |
| 1182 |
$hold = Koha::Holds->find( $reserve_id ) if $reserve_id; |
1177 |
$hold = Koha::Holds->find( $reserve_id ) if $reserve_id; |
| 1183 |
# Find item level hold for this item if there is one |
1178 |
# Find item level hold for this item if there is one |
| 1184 |
$hold ||= Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->next(); |
1179 |
$hold ||= Koha::Holds->search( { patron_id => $borrowernumber, item_id => $itemnumber } )->next(); |
| 1185 |
# Find record level hold if there is no item level hold |
1180 |
# Find record level hold if there is no item level hold |
| 1186 |
$hold ||= Koha::Holds->search( { borrowernumber => $borrowernumber, biblionumber => $biblionumber } )->next(); |
1181 |
$hold ||= Koha::Holds->search( { patron_id => $borrowernumber, biblio_id => $biblionumber } )->next(); |
| 1187 |
|
1182 |
|
| 1188 |
return unless $hold; |
1183 |
return unless $hold; |
| 1189 |
|
1184 |
|
| 1190 |
my $already_on_shelf = $hold->found && $hold->found eq 'W'; |
1185 |
my $already_on_shelf = $hold->status eq 'waiting'; |
| 1191 |
|
1186 |
|
| 1192 |
$hold->itemnumber($itemnumber); |
1187 |
$hold->item_id($itemnumber); |
| 1193 |
|
1188 |
|
| 1194 |
if ($transferToDo) { |
1189 |
if ($transferToDo) { |
| 1195 |
$hold->set_transfer(); |
1190 |
$hold->set_transfer(); |
|
Lines 1199-1205
sub ModReserveAffect {
Link Here
|
| 1199 |
$hold->set_processing(); |
1194 |
$hold->set_processing(); |
| 1200 |
} else { |
1195 |
} else { |
| 1201 |
$hold->set_waiting($desk_id); |
1196 |
$hold->set_waiting($desk_id); |
| 1202 |
_koha_notify_reserve( $hold->reserve_id ) unless $already_on_shelf; |
1197 |
_koha_notify_reserve( $hold->id ) unless $already_on_shelf; |
| 1203 |
# Complete transfer if one exists |
1198 |
# Complete transfer if one exists |
| 1204 |
my $transfer = $hold->item->get_transfer; |
1199 |
my $transfer = $hold->item->get_transfer; |
| 1205 |
$transfer->receive if $transfer; |
1200 |
$transfer->receive if $transfer; |
|
Lines 1212-1218
sub ModReserveAffect {
Link Here
|
| 1212 |
CartToShelf( $itemnumber ); |
1207 |
CartToShelf( $itemnumber ); |
| 1213 |
} |
1208 |
} |
| 1214 |
|
1209 |
|
| 1215 |
logaction( 'HOLDS', 'MODIFY', $hold->reserve_id, Dumper($hold->unblessed) ) |
1210 |
logaction( 'HOLDS', 'MODIFY', $hold->id, Dumper($hold->unblessed) ) |
| 1216 |
if C4::Context->preference('HoldsLog'); |
1211 |
if C4::Context->preference('HoldsLog'); |
| 1217 |
|
1212 |
|
| 1218 |
return; |
1213 |
return; |
|
Lines 1229-1243
function to cancel reserv,check other reserves, and transfer document if it's ne
Link Here
|
| 1229 |
sub ModReserveCancelAll { |
1224 |
sub ModReserveCancelAll { |
| 1230 |
my $messages; |
1225 |
my $messages; |
| 1231 |
my $nextreservinfo; |
1226 |
my $nextreservinfo; |
| 1232 |
my ( $itemnumber, $borrowernumber, $cancellation_reason ) = @_; |
1227 |
my ( $item_id, $patron_id, $cancellation_reason ) = @_; |
| 1233 |
|
1228 |
|
| 1234 |
#step 1 : cancel the reservation |
1229 |
#step 1 : cancel the reservation |
| 1235 |
my $holds = Koha::Holds->search({ itemnumber => $itemnumber, borrowernumber => $borrowernumber }); |
1230 |
my $holds = Koha::Holds->search({ item_id => $item_id, patron_id => $patron_id }); |
| 1236 |
return unless $holds->count; |
1231 |
return unless $holds->count; |
| 1237 |
$holds->next->cancel({ cancellation_reason => $cancellation_reason }); |
1232 |
$holds->next->cancel({ cancellation_reason => $cancellation_reason }); |
| 1238 |
|
1233 |
|
| 1239 |
#step 2 launch the subroutine of the others reserves |
1234 |
#step 2 launch the subroutine of the others reserves |
| 1240 |
( $messages, $nextreservinfo ) = GetOtherReserves($itemnumber); |
1235 |
( $messages, $nextreservinfo ) = GetOtherReserves($item_id); |
| 1241 |
|
1236 |
|
| 1242 |
return ( $messages, $nextreservinfo->{borrowernumber} ); |
1237 |
return ( $messages, $nextreservinfo->{borrowernumber} ); |
| 1243 |
} |
1238 |
} |
|
Lines 1251-1267
Reduce the values of queued list
Link Here
|
| 1251 |
=cut |
1246 |
=cut |
| 1252 |
|
1247 |
|
| 1253 |
sub ModReserveMinusPriority { |
1248 |
sub ModReserveMinusPriority { |
| 1254 |
my ( $itemnumber, $reserve_id ) = @_; |
1249 |
my ( $item_id, $reserve_id ) = @_; |
| 1255 |
|
1250 |
|
| 1256 |
#first step update the value of the first person on reserv |
1251 |
#first step update the value of the first person on reserv |
| 1257 |
my $dbh = C4::Context->dbh; |
1252 |
my $dbh = C4::Context->dbh; |
| 1258 |
my $query = " |
1253 |
my $query = " |
| 1259 |
UPDATE reserves |
1254 |
UPDATE holds |
| 1260 |
SET priority = 0 , itemnumber = ? |
1255 |
SET priority = 0 , item_id = ? |
| 1261 |
WHERE reserve_id = ? |
1256 |
WHERE id = ? |
| 1262 |
"; |
1257 |
"; |
| 1263 |
my $sth_upd = $dbh->prepare($query); |
1258 |
my $sth_upd = $dbh->prepare($query); |
| 1264 |
$sth_upd->execute( $itemnumber, $reserve_id ); |
1259 |
$sth_upd->execute( $item_id, $reserve_id ); |
| 1265 |
# second step update all others reserves |
1260 |
# second step update all others reserves |
| 1266 |
_FixPriority({ reserve_id => $reserve_id, rank => '0' }); |
1261 |
_FixPriority({ reserve_id => $reserve_id, rank => '0' }); |
| 1267 |
} |
1262 |
} |
|
Lines 1405-1412
sub AlterPriority {
Link Here
|
| 1405 |
my $hold = Koha::Holds->find( $reserve_id ); |
1400 |
my $hold = Koha::Holds->find( $reserve_id ); |
| 1406 |
return unless $hold; |
1401 |
return unless $hold; |
| 1407 |
|
1402 |
|
| 1408 |
if ( $hold->cancellationdate ) { |
1403 |
if ( $hold->completed_date and $hold->status eq 'cancelled' ) { |
| 1409 |
warn "I cannot alter the priority for reserve_id $reserve_id, the reserve has been cancelled (" . $hold->cancellationdate . ')'; |
1404 |
warn "I cannot alter the priority for reserve_id $reserve_id, the reserve has been cancelled (" . $hold->completed_date . ')'; |
| 1410 |
return; |
1405 |
return; |
| 1411 |
} |
1406 |
} |
| 1412 |
|
1407 |
|
|
Lines 1438-1444
sub ToggleLowestPriority {
Link Here
|
| 1438 |
|
1433 |
|
| 1439 |
my $dbh = C4::Context->dbh; |
1434 |
my $dbh = C4::Context->dbh; |
| 1440 |
|
1435 |
|
| 1441 |
my $sth = $dbh->prepare( "UPDATE reserves SET lowestPriority = NOT lowestPriority WHERE reserve_id = ?"); |
1436 |
my $sth = $dbh->prepare( "UPDATE holds SET lowest_priority = NOT lowest_priority WHERE id = ?"); |
| 1442 |
$sth->execute( $reserve_id ); |
1437 |
$sth->execute( $reserve_id ); |
| 1443 |
|
1438 |
|
| 1444 |
_FixPriority({ reserve_id => $reserve_id, rank => '999999' }); |
1439 |
_FixPriority({ reserve_id => $reserve_id, rank => '999999' }); |
|
Lines 1498-1506
sub SuspendAll {
Link Here
|
| 1498 |
return unless ( $borrowernumber || $biblionumber ); |
1493 |
return unless ( $borrowernumber || $biblionumber ); |
| 1499 |
|
1494 |
|
| 1500 |
my $params; |
1495 |
my $params; |
| 1501 |
$params->{found} = undef; |
1496 |
$params->{status} = 'placed'; |
| 1502 |
$params->{borrowernumber} = $borrowernumber if $borrowernumber; |
1497 |
$params->{patron_id} = $borrowernumber if $borrowernumber; |
| 1503 |
$params->{biblionumber} = $biblionumber if $biblionumber; |
1498 |
$params->{biblio_id} = $biblionumber if $biblionumber; |
| 1504 |
|
1499 |
|
| 1505 |
my @holds = Koha::Holds->search($params); |
1500 |
my @holds = Koha::Holds->search($params); |
| 1506 |
|
1501 |
|
|
Lines 1560-1574
sub _FixPriority {
Link Here
|
| 1560 |
my $hold; |
1555 |
my $hold; |
| 1561 |
if ( $reserve_id ) { |
1556 |
if ( $reserve_id ) { |
| 1562 |
$hold = Koha::Holds->find( $reserve_id ); |
1557 |
$hold = Koha::Holds->find( $reserve_id ); |
| 1563 |
if (!defined $hold){ |
|
|
| 1564 |
# may have already been checked out and hold fulfilled |
| 1565 |
$hold = Koha::Old::Holds->find( $reserve_id ); |
| 1566 |
} |
| 1567 |
return unless $hold; |
1558 |
return unless $hold; |
| 1568 |
} |
1559 |
} |
| 1569 |
|
1560 |
|
| 1570 |
unless ( $biblionumber ) { # FIXME This is a very weird API |
1561 |
unless ( $biblionumber ) { # FIXME This is a very weird API |
| 1571 |
$biblionumber = $hold->biblionumber; |
1562 |
$biblionumber = $hold->biblio_id; |
| 1572 |
} |
1563 |
} |
| 1573 |
|
1564 |
|
| 1574 |
if ( $rank eq "del" ) { # FIXME will crash if called without $hold |
1565 |
if ( $rank eq "del" ) { # FIXME will crash if called without $hold |
|
Lines 1578-1587
sub _FixPriority {
Link Here
|
| 1578 |
|
1569 |
|
| 1579 |
# make sure priority for waiting or in-transit items is 0 |
1570 |
# make sure priority for waiting or in-transit items is 0 |
| 1580 |
my $query = " |
1571 |
my $query = " |
| 1581 |
UPDATE reserves |
1572 |
UPDATE holds |
| 1582 |
SET priority = 0 |
1573 |
SET priority = 0 |
| 1583 |
WHERE reserve_id = ? |
1574 |
WHERE id = ? |
| 1584 |
AND found IN ('W', 'T', 'P') |
1575 |
AND status IN ('waiting', 'in_transit', 'processing') |
| 1585 |
"; |
1576 |
"; |
| 1586 |
my $sth = $dbh->prepare($query); |
1577 |
my $sth = $dbh->prepare($query); |
| 1587 |
$sth->execute( $reserve_id ); |
1578 |
$sth->execute( $reserve_id ); |
|
Lines 1590-1599
sub _FixPriority {
Link Here
|
| 1590 |
|
1581 |
|
| 1591 |
# get whats left |
1582 |
# get whats left |
| 1592 |
my $query = " |
1583 |
my $query = " |
| 1593 |
SELECT reserve_id, borrowernumber, reservedate |
1584 |
SELECT id |
| 1594 |
FROM reserves |
1585 |
FROM holds |
| 1595 |
WHERE biblionumber = ? |
1586 |
WHERE biblio_id = ? |
| 1596 |
AND ((found <> 'W' AND found <> 'T' AND found <> 'P') OR found IS NULL) |
1587 |
AND completed = 0 |
|
|
1588 |
AND status = 'placed' |
| 1597 |
ORDER BY priority ASC |
1589 |
ORDER BY priority ASC |
| 1598 |
"; |
1590 |
"; |
| 1599 |
my $sth = $dbh->prepare($query); |
1591 |
my $sth = $dbh->prepare($query); |
|
Lines 1607-1613
sub _FixPriority {
Link Here
|
| 1607 |
my $i; |
1599 |
my $i; |
| 1608 |
my $key = -1; # to allow for 0 to be a valid result |
1600 |
my $key = -1; # to allow for 0 to be a valid result |
| 1609 |
for ( $i = 0 ; $i < @priority ; $i++ ) { |
1601 |
for ( $i = 0 ; $i < @priority ; $i++ ) { |
| 1610 |
if ( $reserve_id && $reserve_id == $priority[$i]->{'reserve_id'} ) { |
1602 |
if ( $reserve_id && $reserve_id == $priority[$i]->{'id'} ) { |
| 1611 |
$key = $i; # save the index |
1603 |
$key = $i; # save the index |
| 1612 |
last; |
1604 |
last; |
| 1613 |
} |
1605 |
} |
|
Lines 1623-1647
sub _FixPriority {
Link Here
|
| 1623 |
|
1615 |
|
| 1624 |
# now fix the priority on those that are left.... |
1616 |
# now fix the priority on those that are left.... |
| 1625 |
$query = " |
1617 |
$query = " |
| 1626 |
UPDATE reserves |
1618 |
UPDATE holds |
| 1627 |
SET priority = ? |
1619 |
SET priority = ? |
| 1628 |
WHERE reserve_id = ? |
1620 |
WHERE id = ? |
| 1629 |
"; |
1621 |
"; |
| 1630 |
$sth = $dbh->prepare($query); |
1622 |
$sth = $dbh->prepare($query); |
| 1631 |
for ( my $j = 0 ; $j < @priority ; $j++ ) { |
1623 |
for ( my $j = 0 ; $j < @priority ; $j++ ) { |
| 1632 |
$sth->execute( |
1624 |
$sth->execute( |
| 1633 |
$j + 1, |
1625 |
$j + 1, |
| 1634 |
$priority[$j]->{'reserve_id'} |
1626 |
$priority[$j]->{'id'} |
| 1635 |
); |
1627 |
); |
| 1636 |
} |
1628 |
} |
| 1637 |
|
1629 |
|
| 1638 |
$sth = $dbh->prepare( "SELECT reserve_id FROM reserves WHERE lowestPriority = 1 ORDER BY priority" ); |
1630 |
$sth = $dbh->prepare( "SELECT id FROM holds WHERE lowest_priority = 1 ORDER BY priority" ); |
| 1639 |
$sth->execute(); |
1631 |
$sth->execute(); |
| 1640 |
|
1632 |
|
| 1641 |
unless ( $ignoreSetLowestRank ) { |
1633 |
unless ( $ignoreSetLowestRank ) { |
| 1642 |
while ( my $res = $sth->fetchrow_hashref() ) { |
1634 |
while ( my $res = $sth->fetchrow_hashref() ) { |
| 1643 |
_FixPriority({ |
1635 |
_FixPriority({ |
| 1644 |
reserve_id => $res->{'reserve_id'}, |
1636 |
reserve_id => $res->{'id'}, |
| 1645 |
rank => '999999', |
1637 |
rank => '999999', |
| 1646 |
ignoreSetLowestRank => 1 |
1638 |
ignoreSetLowestRank => 1 |
| 1647 |
}); |
1639 |
}); |
|
Lines 1678-1706
sub _Findgroupreserve {
Link Here
|
| 1678 |
# TODO: consolidate at least the SELECT portion of the first 2 queries to a common $select var. |
1670 |
# TODO: consolidate at least the SELECT portion of the first 2 queries to a common $select var. |
| 1679 |
# check for exact targeted match |
1671 |
# check for exact targeted match |
| 1680 |
my $item_level_target_query = qq{ |
1672 |
my $item_level_target_query = qq{ |
| 1681 |
SELECT reserves.biblionumber AS biblionumber, |
1673 |
SELECT holds.biblio_id AS biblio_id, |
| 1682 |
reserves.borrowernumber AS borrowernumber, |
1674 |
holds.patron_id AS patron_id, |
| 1683 |
reserves.reservedate AS reservedate, |
1675 |
holds.created_date AS created_date, |
| 1684 |
reserves.branchcode AS branchcode, |
1676 |
holds.pickup_library_id AS pickup_library_id, |
| 1685 |
reserves.cancellationdate AS cancellationdate, |
1677 |
holds.completed_date AS completed_date, |
| 1686 |
reserves.found AS found, |
1678 |
holds.status AS status, |
| 1687 |
reserves.reservenotes AS reservenotes, |
1679 |
holds.notes AS notes, |
| 1688 |
reserves.priority AS priority, |
1680 |
holds.priority AS priority, |
| 1689 |
reserves.timestamp AS timestamp, |
1681 |
holds.timestamp AS timestamp, |
| 1690 |
biblioitems.biblioitemnumber AS biblioitemnumber, |
1682 |
biblioitems.biblioitemnumber AS biblioitemnumber, |
| 1691 |
reserves.itemnumber AS itemnumber, |
1683 |
holds.item_id AS item_id, |
| 1692 |
reserves.reserve_id AS reserve_id, |
1684 |
holds.id AS id, |
| 1693 |
reserves.itemtype AS itemtype, |
1685 |
holds.item_type AS item_type, |
| 1694 |
reserves.non_priority AS non_priority |
1686 |
holds.non_priority AS non_priority |
| 1695 |
FROM reserves |
1687 |
FROM holds |
| 1696 |
JOIN biblioitems USING (biblionumber) |
1688 |
JOIN biblioitems ON (holds.biblio_id=biblioitems.biblionumber) |
| 1697 |
JOIN hold_fill_targets USING (reserve_id) |
1689 |
JOIN hold_fill_targets ON ( |
| 1698 |
WHERE found IS NULL |
1690 |
holds.biblio_id=hold_fill_targets.biblionumber |
|
|
1691 |
AND holds.patron_id=hold_fill_targets.borrowernumber |
| 1692 |
AND holds.item_id=hold_fill_targets.itemnumber) |
| 1693 |
WHERE status='placed' |
| 1699 |
AND priority > 0 |
1694 |
AND priority > 0 |
| 1700 |
AND item_level_request = 1 |
1695 |
AND completed = 0 |
| 1701 |
AND hold_fill_targets.itemnumber = ? |
1696 |
AND item_level = 1 |
| 1702 |
AND reservedate <= DATE_ADD(NOW(),INTERVAL ? DAY) |
1697 |
AND item_id = ? |
| 1703 |
AND suspend = 0 |
1698 |
AND created_date <= DATE_ADD(NOW(),INTERVAL ? DAY) |
|
|
1699 |
AND suspended = 0 |
| 1704 |
ORDER BY priority |
1700 |
ORDER BY priority |
| 1705 |
}; |
1701 |
}; |
| 1706 |
my $sth = $dbh->prepare($item_level_target_query); |
1702 |
my $sth = $dbh->prepare($item_level_target_query); |
|
Lines 1708-1742
sub _Findgroupreserve {
Link Here
|
| 1708 |
my @results; |
1704 |
my @results; |
| 1709 |
if ( my $data = $sth->fetchrow_hashref ) { |
1705 |
if ( my $data = $sth->fetchrow_hashref ) { |
| 1710 |
push( @results, $data ) |
1706 |
push( @results, $data ) |
| 1711 |
unless any{ $data->{borrowernumber} eq $_ } @$ignore_borrowers ; |
1707 |
unless any{ $data->{patron_id} eq $_ } @$ignore_borrowers ; |
| 1712 |
} |
1708 |
} |
| 1713 |
return @results if @results; |
1709 |
return @results if @results; |
| 1714 |
|
1710 |
|
| 1715 |
# check for title-level targeted match |
1711 |
# check for title-level targeted match |
| 1716 |
my $title_level_target_query = qq{ |
1712 |
my $title_level_target_query = qq{ |
| 1717 |
SELECT reserves.biblionumber AS biblionumber, |
1713 |
SELECT holds.biblio_id AS biblio_id, |
| 1718 |
reserves.borrowernumber AS borrowernumber, |
1714 |
holds.patron_id AS patron_id, |
| 1719 |
reserves.reservedate AS reservedate, |
1715 |
holds.created_date AS created_date, |
| 1720 |
reserves.branchcode AS branchcode, |
1716 |
holds.pickup_library_id AS pickup_library_id, |
| 1721 |
reserves.cancellationdate AS cancellationdate, |
1717 |
holds.completed_date AS completed_date, |
| 1722 |
reserves.found AS found, |
1718 |
holds.status AS status, |
| 1723 |
reserves.reservenotes AS reservenotes, |
1719 |
holds.notes AS notes, |
| 1724 |
reserves.priority AS priority, |
1720 |
holds.priority AS priority, |
| 1725 |
reserves.timestamp AS timestamp, |
1721 |
holds.timestamp AS timestamp, |
| 1726 |
biblioitems.biblioitemnumber AS biblioitemnumber, |
1722 |
biblioitems.biblioitemnumber AS biblioitemnumber, |
| 1727 |
reserves.itemnumber AS itemnumber, |
1723 |
holds.item_id AS item_id, |
| 1728 |
reserves.reserve_id AS reserve_id, |
1724 |
holds.id AS id, |
| 1729 |
reserves.itemtype AS itemtype, |
1725 |
holds.item_type AS item_type, |
| 1730 |
reserves.non_priority AS non_priority |
1726 |
holds.non_priority AS non_priority |
| 1731 |
FROM reserves |
1727 |
FROM holds |
| 1732 |
JOIN biblioitems USING (biblionumber) |
1728 |
JOIN biblioitems ON (holds.biblio_id=biblioitems.biblionumber) |
| 1733 |
JOIN hold_fill_targets USING (reserve_id) |
1729 |
JOIN hold_fill_targets ON ( |
| 1734 |
WHERE found IS NULL |
1730 |
holds.biblio_id=hold_fill_targets.biblionumber |
|
|
1731 |
AND holds.patron_id=hold_fill_targets.borrowernumber) |
| 1732 |
WHERE status='placed' |
| 1735 |
AND priority > 0 |
1733 |
AND priority > 0 |
| 1736 |
AND item_level_request = 0 |
1734 |
AND completed = 0 |
|
|
1735 |
AND item_level = 0 |
| 1737 |
AND hold_fill_targets.itemnumber = ? |
1736 |
AND hold_fill_targets.itemnumber = ? |
| 1738 |
AND reservedate <= DATE_ADD(NOW(),INTERVAL ? DAY) |
1737 |
AND created_date <= DATE_ADD(NOW(),INTERVAL ? DAY) |
| 1739 |
AND suspend = 0 |
1738 |
AND suspended = 0 |
| 1740 |
ORDER BY priority |
1739 |
ORDER BY priority |
| 1741 |
}; |
1740 |
}; |
| 1742 |
$sth = $dbh->prepare($title_level_target_query); |
1741 |
$sth = $dbh->prepare($title_level_target_query); |
|
Lines 1744-1773
sub _Findgroupreserve {
Link Here
|
| 1744 |
@results = (); |
1743 |
@results = (); |
| 1745 |
if ( my $data = $sth->fetchrow_hashref ) { |
1744 |
if ( my $data = $sth->fetchrow_hashref ) { |
| 1746 |
push( @results, $data ) |
1745 |
push( @results, $data ) |
| 1747 |
unless any{ $data->{borrowernumber} eq $_ } @$ignore_borrowers ; |
1746 |
unless any{ $data->{patron_id} eq $_ } @$ignore_borrowers ; |
| 1748 |
} |
1747 |
} |
| 1749 |
return @results if @results; |
1748 |
return @results if @results; |
| 1750 |
|
1749 |
|
| 1751 |
my $query = qq{ |
1750 |
my $query = qq{ |
| 1752 |
SELECT reserves.biblionumber AS biblionumber, |
1751 |
SELECT holds.biblio_id AS biblio_id, |
| 1753 |
reserves.borrowernumber AS borrowernumber, |
1752 |
holds.patron_id AS patron_id, |
| 1754 |
reserves.reservedate AS reservedate, |
1753 |
holds.created_date AS created_date, |
| 1755 |
reserves.waitingdate AS waitingdate, |
1754 |
holds.waiting_date AS waiting_date, |
| 1756 |
reserves.branchcode AS branchcode, |
1755 |
holds.pickup_library_id AS pickup_library_id, |
| 1757 |
reserves.cancellationdate AS cancellationdate, |
1756 |
holds.completed_date AS completed_date, |
| 1758 |
reserves.found AS found, |
1757 |
holds.status AS status, |
| 1759 |
reserves.reservenotes AS reservenotes, |
1758 |
holds.notes AS notes, |
| 1760 |
reserves.priority AS priority, |
1759 |
holds.priority AS priority, |
| 1761 |
reserves.timestamp AS timestamp, |
1760 |
holds.timestamp AS timestamp, |
| 1762 |
reserves.itemnumber AS itemnumber, |
1761 |
holds.item_id AS item_id, |
| 1763 |
reserves.reserve_id AS reserve_id, |
1762 |
holds.id AS id, |
| 1764 |
reserves.itemtype AS itemtype, |
1763 |
holds.item_type AS item_type, |
| 1765 |
reserves.non_priority AS non_priority |
1764 |
holds.non_priority AS non_priority |
| 1766 |
FROM reserves |
1765 |
FROM holds |
| 1767 |
WHERE reserves.biblionumber = ? |
1766 |
WHERE holds.biblio_id = ? |
| 1768 |
AND (reserves.itemnumber IS NULL OR reserves.itemnumber = ?) |
1767 |
AND (holds.item_id IS NULL OR holds.item_id = ?) |
| 1769 |
AND reserves.reservedate <= DATE_ADD(NOW(),INTERVAL ? DAY) |
1768 |
AND holds.created_date <= DATE_ADD(NOW(),INTERVAL ? DAY) |
| 1770 |
AND suspend = 0 |
1769 |
AND suspended = 0 |
|
|
1770 |
AND completed = 0 |
| 1771 |
ORDER BY priority |
1771 |
ORDER BY priority |
| 1772 |
}; |
1772 |
}; |
| 1773 |
$sth = $dbh->prepare($query); |
1773 |
$sth = $dbh->prepare($query); |
|
Lines 1775-1781
sub _Findgroupreserve {
Link Here
|
| 1775 |
@results = (); |
1775 |
@results = (); |
| 1776 |
while ( my $data = $sth->fetchrow_hashref ) { |
1776 |
while ( my $data = $sth->fetchrow_hashref ) { |
| 1777 |
push( @results, $data ) |
1777 |
push( @results, $data ) |
| 1778 |
unless any{ $data->{borrowernumber} eq $_ } @$ignore_borrowers ; |
1778 |
unless any{ $data->{patron_id} eq $_ } @$ignore_borrowers ; |
| 1779 |
} |
1779 |
} |
| 1780 |
return @results; |
1780 |
return @results; |
| 1781 |
} |
1781 |
} |
|
Lines 1811-1817
The following tables are availalbe witin the notice:
Link Here
|
| 1811 |
sub _koha_notify_reserve { |
1811 |
sub _koha_notify_reserve { |
| 1812 |
my $reserve_id = shift; |
1812 |
my $reserve_id = shift; |
| 1813 |
my $hold = Koha::Holds->find($reserve_id); |
1813 |
my $hold = Koha::Holds->find($reserve_id); |
| 1814 |
my $borrowernumber = $hold->borrowernumber; |
1814 |
my $borrowernumber = $hold->patron_id; |
| 1815 |
|
1815 |
|
| 1816 |
my $patron = Koha::Patrons->find( $borrowernumber ); |
1816 |
my $patron = Koha::Patrons->find( $borrowernumber ); |
| 1817 |
|
1817 |
|
|
Lines 1823-1843
sub _koha_notify_reserve {
Link Here
|
| 1823 |
message_name => 'Hold_Filled' |
1823 |
message_name => 'Hold_Filled' |
| 1824 |
} ); |
1824 |
} ); |
| 1825 |
|
1825 |
|
| 1826 |
my $library = Koha::Libraries->find( $hold->branchcode )->unblessed; |
1826 |
my $library = Koha::Libraries->find( $hold->pickup_library_id )->unblessed; |
| 1827 |
|
1827 |
|
| 1828 |
my $admin_email_address = $library->{branchemail} || C4::Context->preference('KohaAdminEmailAddress'); |
1828 |
my $admin_email_address = $library->{branchemail} || C4::Context->preference('KohaAdminEmailAddress'); |
| 1829 |
|
1829 |
|
| 1830 |
my %letter_params = ( |
1830 |
my %letter_params = ( |
| 1831 |
module => 'reserves', |
1831 |
module => 'reserves', |
| 1832 |
branchcode => $hold->branchcode, |
1832 |
branchcode => $hold->pickup_library_id, |
| 1833 |
lang => $patron->lang, |
1833 |
lang => $patron->lang, |
| 1834 |
tables => { |
1834 |
tables => { |
| 1835 |
'branches' => $library, |
1835 |
'branches' => $library, |
| 1836 |
'borrowers' => $patron->unblessed, |
1836 |
'borrowers' => $patron->unblessed, |
| 1837 |
'biblio' => $hold->biblionumber, |
1837 |
'biblio' => $hold->biblio_id, |
| 1838 |
'biblioitems' => $hold->biblionumber, |
1838 |
'biblioitems' => $hold->biblio_id, |
| 1839 |
'reserves' => $hold->unblessed, |
1839 |
'reserves' => $hold->unblessed, |
| 1840 |
'items' => $hold->itemnumber, |
1840 |
'items' => $hold->item_id, |
| 1841 |
}, |
1841 |
}, |
| 1842 |
); |
1842 |
); |
| 1843 |
|
1843 |
|
|
Lines 1901-1907
sub _ShiftPriorityByDateAndPriority {
Link Here
|
| 1901 |
my ( $biblio, $resdate, $new_priority ) = @_; |
1901 |
my ( $biblio, $resdate, $new_priority ) = @_; |
| 1902 |
|
1902 |
|
| 1903 |
my $dbh = C4::Context->dbh; |
1903 |
my $dbh = C4::Context->dbh; |
| 1904 |
my $query = "SELECT priority FROM reserves WHERE biblionumber = ? AND ( reservedate > ? OR priority > ? ) ORDER BY priority ASC LIMIT 1"; |
1904 |
my $query = "SELECT priority FROM holds WHERE biblio_id = ? AND ( created_date > ? OR priority > ? ) AND completed = 0 ORDER BY priority ASC LIMIT 1"; |
| 1905 |
my $sth = $dbh->prepare( $query ); |
1905 |
my $sth = $dbh->prepare( $query ); |
| 1906 |
$sth->execute( $biblio, $resdate, $new_priority ); |
1906 |
$sth->execute( $biblio, $resdate, $new_priority ); |
| 1907 |
my $min_priority = $sth->fetchrow; |
1907 |
my $min_priority = $sth->fetchrow; |
|
Lines 1909-1928
sub _ShiftPriorityByDateAndPriority {
Link Here
|
| 1909 |
$new_priority = $min_priority if ( $min_priority ); |
1909 |
$new_priority = $min_priority if ( $min_priority ); |
| 1910 |
|
1910 |
|
| 1911 |
# Shift the priority up by one; works in conjunction with the next SQL statement |
1911 |
# Shift the priority up by one; works in conjunction with the next SQL statement |
| 1912 |
$query = "UPDATE reserves |
1912 |
$query = "UPDATE holds |
| 1913 |
SET priority = priority+1 |
1913 |
SET priority = priority+1 |
| 1914 |
WHERE biblionumber = ? |
1914 |
WHERE biblio_id = ? |
| 1915 |
AND borrowernumber = ? |
1915 |
AND patron_id = ? |
| 1916 |
AND reservedate = ? |
1916 |
AND created_date = ? |
| 1917 |
AND found IS NULL"; |
1917 |
AND status = 'placed'"; |
| 1918 |
my $sth_update = $dbh->prepare( $query ); |
1918 |
my $sth_update = $dbh->prepare( $query ); |
| 1919 |
|
1919 |
|
| 1920 |
# Select all reserves for the biblio with priority greater than $new_priority, and order greatest to least |
1920 |
# Select all reserves for the biblio with priority greater than $new_priority, and order greatest to least |
| 1921 |
$query = "SELECT borrowernumber, reservedate FROM reserves WHERE priority >= ? AND biblionumber = ? ORDER BY priority DESC"; |
1921 |
$query = "SELECT patron_id, created_date FROM holds WHERE priority >= ? AND biblio_id = ? ORDER BY priority DESC"; |
| 1922 |
$sth = $dbh->prepare( $query ); |
1922 |
$sth = $dbh->prepare( $query ); |
| 1923 |
$sth->execute( $new_priority, $biblio ); |
1923 |
$sth->execute( $new_priority, $biblio ); |
| 1924 |
while ( my $row = $sth->fetchrow_hashref ) { |
1924 |
while ( my $row = $sth->fetchrow_hashref ) { |
| 1925 |
$sth_update->execute( $biblio, $row->{borrowernumber}, $row->{reservedate} ); |
1925 |
$sth_update->execute( $biblio, $row->{patron_id}, $row->{created_date} ); |
| 1926 |
} |
1926 |
} |
| 1927 |
|
1927 |
|
| 1928 |
return $new_priority; # so the caller knows what priority they wind up receiving |
1928 |
return $new_priority; # so the caller knows what priority they wind up receiving |
|
Lines 1946-1954
sub MoveReserve {
Link Here
|
| 1946 |
my ( $restype, $res, undef ) = CheckReserves( $itemnumber, undef, $lookahead ); |
1946 |
my ( $restype, $res, undef ) = CheckReserves( $itemnumber, undef, $lookahead ); |
| 1947 |
return unless $res; |
1947 |
return unless $res; |
| 1948 |
|
1948 |
|
| 1949 |
my $biblionumber = $res->{biblionumber}; |
1949 |
my $biblionumber = $res->{biblio_id}; |
| 1950 |
|
1950 |
|
| 1951 |
if ($res->{borrowernumber} == $borrowernumber) { |
1951 |
if ($res->{patron_id} == $borrowernumber) { |
| 1952 |
ModReserveFill($res); |
1952 |
ModReserveFill($res); |
| 1953 |
} |
1953 |
} |
| 1954 |
else { |
1954 |
else { |
|
Lines 1957-1964
sub MoveReserve {
Link Here
|
| 1957 |
# Find this item in the reserves |
1957 |
# Find this item in the reserves |
| 1958 |
|
1958 |
|
| 1959 |
my $borr_res = Koha::Holds->search({ |
1959 |
my $borr_res = Koha::Holds->search({ |
| 1960 |
borrowernumber => $borrowernumber, |
1960 |
patron_id => $borrowernumber, |
| 1961 |
biblionumber => $biblionumber, |
1961 |
biblio_id => $biblionumber, |
| 1962 |
},{ |
1962 |
},{ |
| 1963 |
order_by => 'priority' |
1963 |
order_by => 'priority' |
| 1964 |
})->next(); |
1964 |
})->next(); |
|
Lines 1972-1978
sub MoveReserve {
Link Here
|
| 1972 |
RevertWaitingStatus({ itemnumber => $itemnumber }); |
1972 |
RevertWaitingStatus({ itemnumber => $itemnumber }); |
| 1973 |
} |
1973 |
} |
| 1974 |
elsif ( $cancelreserve eq 'cancel' || $cancelreserve ) { # cancel reserves on this item |
1974 |
elsif ( $cancelreserve eq 'cancel' || $cancelreserve ) { # cancel reserves on this item |
| 1975 |
my $hold = Koha::Holds->find( $res->{reserve_id} ); |
1975 |
my $hold = Koha::Holds->find( $res->{id} ); |
| 1976 |
$hold->cancel; |
1976 |
$hold->cancel; |
| 1977 |
} |
1977 |
} |
| 1978 |
} |
1978 |
} |
|
Lines 1989-2021
This shifts the holds from C<$from_biblio> to C<$to_biblio> and reorders them by
Link Here
|
| 1989 |
sub MergeHolds { |
1989 |
sub MergeHolds { |
| 1990 |
my ( $dbh, $to_biblio, $from_biblio ) = @_; |
1990 |
my ( $dbh, $to_biblio, $from_biblio ) = @_; |
| 1991 |
my $sth = $dbh->prepare( |
1991 |
my $sth = $dbh->prepare( |
| 1992 |
"SELECT count(*) as reserve_count FROM reserves WHERE biblionumber = ?" |
1992 |
"SELECT count(*) as reserve_count FROM holds WHERE biblio_id = ? AND completed = 0" |
| 1993 |
); |
1993 |
); |
| 1994 |
$sth->execute($from_biblio); |
1994 |
$sth->execute($from_biblio); |
| 1995 |
if ( my $data = $sth->fetchrow_hashref() ) { |
1995 |
if ( my $data = $sth->fetchrow_hashref() ) { |
| 1996 |
|
1996 |
|
| 1997 |
# holds exist on old record, if not we don't need to do anything |
1997 |
# holds exist on old record, if not we don't need to do anything |
| 1998 |
$sth = $dbh->prepare( |
1998 |
$sth = $dbh->prepare( |
| 1999 |
"UPDATE reserves SET biblionumber = ? WHERE biblionumber = ?"); |
1999 |
"UPDATE holds SET biblio_id = ? WHERE biblio_id = ?"); |
| 2000 |
$sth->execute( $to_biblio, $from_biblio ); |
2000 |
$sth->execute( $to_biblio, $from_biblio ); |
| 2001 |
|
2001 |
|
| 2002 |
# Reorder by date |
2002 |
# Reorder by date |
| 2003 |
# don't reorder those already waiting |
2003 |
# don't reorder those already waiting |
| 2004 |
|
2004 |
|
| 2005 |
$sth = $dbh->prepare( |
2005 |
$sth = $dbh->prepare( |
| 2006 |
"SELECT * FROM reserves WHERE biblionumber = ? AND (found NOT IN ('W', 'T', 'P') OR found is NULL) ORDER BY reservedate ASC" |
2006 |
"SELECT id FROM holds WHERE biblio_id = ? AND status = 'placed' AND completed = 0 ORDER BY created_date ASC" |
| 2007 |
); |
2007 |
); |
| 2008 |
my $upd_sth = $dbh->prepare( |
2008 |
my $upd_sth = $dbh->prepare( |
| 2009 |
"UPDATE reserves SET priority = ? WHERE biblionumber = ? AND borrowernumber = ? |
2009 |
"UPDATE holds SET priority = ? WHERE id = ? " |
| 2010 |
AND reservedate = ? AND (itemnumber = ? or itemnumber is NULL) " |
|
|
| 2011 |
); |
2010 |
); |
| 2012 |
$sth->execute( $to_biblio ); |
2011 |
$sth->execute( $to_biblio ); |
| 2013 |
my $priority = 1; |
2012 |
my $priority = 1; |
| 2014 |
while ( my $reserve = $sth->fetchrow_hashref() ) { |
2013 |
while ( my $reserve = $sth->fetchrow_hashref() ) { |
| 2015 |
$upd_sth->execute( |
2014 |
$upd_sth->execute( |
| 2016 |
$priority, $to_biblio, |
2015 |
$priority, |
| 2017 |
$reserve->{'borrowernumber'}, $reserve->{'reservedate'}, |
2016 |
$reserve->{'id'} |
| 2018 |
$reserve->{'itemnumber'} |
|
|
| 2019 |
); |
2017 |
); |
| 2020 |
$priority++; |
2018 |
$priority++; |
| 2021 |
} |
2019 |
} |
|
Lines 2038-2073
sub MergeHolds {
Link Here
|
| 2038 |
|
2036 |
|
| 2039 |
sub RevertWaitingStatus { |
2037 |
sub RevertWaitingStatus { |
| 2040 |
my ( $params ) = @_; |
2038 |
my ( $params ) = @_; |
| 2041 |
my $itemnumber = $params->{'itemnumber'}; |
2039 |
my $item_id = $params->{'itemnumber'}; |
| 2042 |
|
2040 |
|
| 2043 |
return unless ( $itemnumber ); |
2041 |
return unless ( $item_id ); |
| 2044 |
|
|
|
| 2045 |
my $dbh = C4::Context->dbh; |
| 2046 |
|
2042 |
|
| 2047 |
## Get the waiting reserve we want to revert |
2043 |
## Get the waiting reserve we want to revert |
| 2048 |
my $hold = Koha::Holds->search( |
2044 |
my $hold = Koha::Holds->search( |
| 2049 |
{ |
2045 |
{ |
| 2050 |
itemnumber => $itemnumber, |
2046 |
item_id => $item_id, |
| 2051 |
found => { not => undef }, |
2047 |
status => 'waiting', |
| 2052 |
} |
2048 |
} |
| 2053 |
)->next; |
2049 |
)->next; |
| 2054 |
|
2050 |
|
| 2055 |
## Increment the priority of all other non-waiting |
2051 |
## Increment the priority of all other non-waiting |
| 2056 |
## reserves for this bib record |
2052 |
## reserves for this bib record |
| 2057 |
my $holds = Koha::Holds->search({ biblionumber => $hold->biblionumber, priority => { '>' => 0 } }) |
2053 |
my $holds = Koha::Holds->search({ biblio_id => $hold->biblio_id, priority => { '>' => 0 } }) |
| 2058 |
->update({ priority => \'priority + 1' }, { no_triggers => 1 }); |
2054 |
->update({ priority => \'priority + 1' }, { no_triggers => 1 }); |
| 2059 |
|
2055 |
|
| 2060 |
## Fix up the currently waiting reserve |
2056 |
## Fix up the currently waiting reserve |
| 2061 |
$hold->set( |
2057 |
$hold->set( |
| 2062 |
{ |
2058 |
{ |
| 2063 |
priority => 1, |
2059 |
priority => 1, |
| 2064 |
found => undef, |
2060 |
status => 'placed', |
| 2065 |
waitingdate => undef, |
2061 |
waiting_date => undef, |
| 2066 |
itemnumber => $hold->item_level_hold ? $hold->itemnumber : undef, |
2062 |
item_id => $hold->item_level ? $hold->item_id : undef, |
| 2067 |
} |
2063 |
} |
| 2068 |
)->store(); |
2064 |
)->store(); |
| 2069 |
|
2065 |
|
| 2070 |
_FixPriority( { biblionumber => $hold->biblionumber } ); |
2066 |
_FixPriority( { biblionumber => $hold->biblio_id } ); |
| 2071 |
|
2067 |
|
| 2072 |
return $hold; |
2068 |
return $hold; |
| 2073 |
} |
2069 |
} |
|
Lines 2100-2112
available within the slip:
Link Here
|
| 2100 |
|
2096 |
|
| 2101 |
sub ReserveSlip { |
2097 |
sub ReserveSlip { |
| 2102 |
my ($args) = @_; |
2098 |
my ($args) = @_; |
| 2103 |
my $branchcode = $args->{branchcode}; |
2099 |
my $branchcode = $args->{branchcode}; |
| 2104 |
my $reserve_id = $args->{reserve_id}; |
2100 |
my $reserve_id = $args->{reserve_id}; |
| 2105 |
|
2101 |
|
| 2106 |
my $hold = Koha::Holds->find($reserve_id); |
2102 |
my $hold = Koha::Holds->find($reserve_id); |
| 2107 |
return unless $hold; |
2103 |
return unless $hold; |
| 2108 |
|
2104 |
|
| 2109 |
my $patron = $hold->borrower; |
2105 |
my $patron = $hold->patron; |
| 2110 |
my $reserve = $hold->unblessed; |
2106 |
my $reserve = $hold->unblessed; |
| 2111 |
|
2107 |
|
| 2112 |
return C4::Letters::GetPreparedLetter ( |
2108 |
return C4::Letters::GetPreparedLetter ( |
|
Lines 2116-2126
sub ReserveSlip {
Link Here
|
| 2116 |
lang => $patron->lang, |
2112 |
lang => $patron->lang, |
| 2117 |
tables => { |
2113 |
tables => { |
| 2118 |
'reserves' => $reserve, |
2114 |
'reserves' => $reserve, |
| 2119 |
'branches' => $reserve->{branchcode}, |
2115 |
'branches' => $reserve->{pickup_library_id}, |
| 2120 |
'borrowers' => $reserve->{borrowernumber}, |
2116 |
'borrowers' => $reserve->{patron_id}, |
| 2121 |
'biblio' => $reserve->{biblionumber}, |
2117 |
'biblio' => $reserve->{biblio_id}, |
| 2122 |
'biblioitems' => $reserve->{biblionumber}, |
2118 |
'biblioitems' => $reserve->{biblio_id}, |
| 2123 |
'items' => $reserve->{itemnumber}, |
2119 |
'items' => $reserve->{item_id}, |
| 2124 |
}, |
2120 |
}, |
| 2125 |
); |
2121 |
); |
| 2126 |
} |
2122 |
} |
|
Lines 2174-2190
sub CalculatePriority {
Link Here
|
| 2174 |
my ( $biblionumber, $resdate ) = @_; |
2170 |
my ( $biblionumber, $resdate ) = @_; |
| 2175 |
|
2171 |
|
| 2176 |
my $sql = q{ |
2172 |
my $sql = q{ |
| 2177 |
SELECT COUNT(*) FROM reserves |
2173 |
SELECT COUNT(*) FROM holds |
| 2178 |
WHERE biblionumber = ? |
2174 |
WHERE biblio_id = ? |
| 2179 |
AND priority > 0 |
2175 |
AND priority > 0 |
| 2180 |
AND (found IS NULL OR found = '') |
2176 |
AND status='placed' |
| 2181 |
}; |
2177 |
}; |
| 2182 |
#skip found==W or found==T or found==P (waiting, transit or processing holds) |
2178 |
#skip status==waiting or status==in_transit or status==processing |
| 2183 |
if( $resdate ) { |
2179 |
if( $resdate ) { |
| 2184 |
$sql.= ' AND ( reservedate <= ? )'; |
2180 |
$sql.= ' AND ( created_date <= ? )'; |
| 2185 |
} |
2181 |
} |
| 2186 |
else { |
2182 |
else { |
| 2187 |
$sql.= ' AND ( reservedate < NOW() )'; |
2183 |
$sql.= ' AND ( created_date < NOW() )'; |
| 2188 |
} |
2184 |
} |
| 2189 |
my $dbh = C4::Context->dbh(); |
2185 |
my $dbh = C4::Context->dbh(); |
| 2190 |
my @row = $dbh->selectrow_array( |
2186 |
my @row = $dbh->selectrow_array( |
|
Lines 2198-2223
sub CalculatePriority {
Link Here
|
| 2198 |
|
2194 |
|
| 2199 |
=head2 IsItemOnHoldAndFound |
2195 |
=head2 IsItemOnHoldAndFound |
| 2200 |
|
2196 |
|
| 2201 |
my $bool = IsItemFoundHold( $itemnumber ); |
2197 |
my $bool = IsItemFoundHold( $item_id ); |
| 2202 |
|
2198 |
|
| 2203 |
Returns true if the item is currently on hold |
2199 |
Returns true if the item is currently on hold |
| 2204 |
and that hold has a non-null found status ( W, T, etc. ) |
2200 |
and that hold has a status of in_transit, processing |
|
|
2201 |
or waiting. |
| 2205 |
|
2202 |
|
| 2206 |
=cut |
2203 |
=cut |
| 2207 |
|
2204 |
|
| 2208 |
sub IsItemOnHoldAndFound { |
2205 |
sub IsItemOnHoldAndFound { |
| 2209 |
my ($itemnumber) = @_; |
2206 |
my ($item_id) = @_; |
| 2210 |
|
|
|
| 2211 |
my $rs = Koha::Database->new()->schema()->resultset('Reserve'); |
| 2212 |
|
2207 |
|
| 2213 |
my $found = $rs->count( |
2208 |
return Koha::Holds->search( |
| 2214 |
{ |
2209 |
{ |
| 2215 |
itemnumber => $itemnumber, |
2210 |
item_id => $item_id, |
| 2216 |
found => { '!=' => undef } |
2211 |
status => [ 'in_transit', 'processing', 'waiting' ], |
|
|
2212 |
completed => 0 |
| 2217 |
} |
2213 |
} |
| 2218 |
); |
2214 |
)->count; |
| 2219 |
|
|
|
| 2220 |
return $found; |
| 2221 |
} |
2215 |
} |
| 2222 |
|
2216 |
|
| 2223 |
=head2 GetMaxPatronHoldsForRecord |
2217 |
=head2 GetMaxPatronHoldsForRecord |