Lines 120-126
BEGIN {
Link Here
|
120 |
&CanItemBeReserved |
120 |
&CanItemBeReserved |
121 |
&CanReserveBeCanceledFromOpac |
121 |
&CanReserveBeCanceledFromOpac |
122 |
&CancelExpiredReserves |
122 |
&CancelExpiredReserves |
123 |
|
|
|
124 |
&AutoUnsuspendReserves |
123 |
&AutoUnsuspendReserves |
125 |
|
124 |
|
126 |
&IsAvailableForItemLevelRequest |
125 |
&IsAvailableForItemLevelRequest |
Lines 185-201
sub AddReserve {
Link Here
|
185 |
# Make room in reserves for this before those of a later reserve date |
184 |
# Make room in reserves for this before those of a later reserve date |
186 |
$priority = _ShiftPriorityByDateAndPriority( $biblionumber, $resdate, $priority ); |
185 |
$priority = _ShiftPriorityByDateAndPriority( $biblionumber, $resdate, $priority ); |
187 |
} |
186 |
} |
|
|
187 |
my ($waitingdate, $lastpickupdate); |
188 |
|
188 |
|
189 |
my $waitingdate; |
189 |
my $item = C4::Items::GetItem( $checkitem ); |
190 |
|
|
|
191 |
# If the reserv had the waiting status, we had the value of the resdate |
190 |
# If the reserv had the waiting status, we had the value of the resdate |
192 |
if ( $found eq 'W' ) { |
191 |
if ( $found eq 'W' ) { |
193 |
$waitingdate = $resdate; |
192 |
$waitingdate = $resdate; |
194 |
} |
|
|
195 |
|
193 |
|
|
|
194 |
#The reserve-object doesn't exist yet in DB, so we must supply what information we have to GetLastPickupDate() so it can do it's work. |
195 |
my $reserve = {borrowernumber => $borrowernumber, waitingdate => $waitingdate, branchcode => $branch}; |
196 |
my $patron = Koha::Patrons->find( {borrowernumber => $borrowernumber} ); |
197 |
$lastpickupdate = GetLastPickupDate( $reserve, $item, $patron ); |
198 |
} |
196 |
# Don't add itemtype limit if specific item is selected |
199 |
# Don't add itemtype limit if specific item is selected |
197 |
$itemtype = undef if $checkitem; |
200 |
$itemtype = undef if $checkitem; |
198 |
|
|
|
199 |
# updates take place here |
201 |
# updates take place here |
200 |
my $hold = Koha::Hold->new( |
202 |
my $hold = Koha::Hold->new( |
201 |
{ |
203 |
{ |
Lines 211-220
sub AddReserve {
Link Here
|
211 |
expirationdate => $expdate, |
213 |
expirationdate => $expdate, |
212 |
itemtype => $itemtype, |
214 |
itemtype => $itemtype, |
213 |
item_level_hold => $checkitem ? 1 : 0, |
215 |
item_level_hold => $checkitem ? 1 : 0, |
|
|
216 |
lastpickupdate => $lastpickupdate, |
214 |
} |
217 |
} |
215 |
)->store(); |
218 |
)->store(); |
216 |
$hold->set_waiting() if $found eq 'W'; |
219 |
$hold->set_waiting() if $found eq 'W'; |
217 |
|
|
|
218 |
logaction( 'HOLDS', 'CREATE', $hold->id, Dumper($hold->unblessed) ) |
220 |
logaction( 'HOLDS', 'CREATE', $hold->id, Dumper($hold->unblessed) ) |
219 |
if C4::Context->preference('HoldsLog'); |
221 |
if C4::Context->preference('HoldsLog'); |
220 |
|
222 |
|
Lines 661-666
sub GetReserveStatus {
Link Here
|
661 |
return ''; # empty string here will remove need for checking undef, or less log lines |
663 |
return ''; # empty string here will remove need for checking undef, or less log lines |
662 |
} |
664 |
} |
663 |
|
665 |
|
|
|
666 |
|
667 |
=head2 GetLastPickupDate |
668 |
|
669 |
my $lastpickupdate = GetLastPickupDate($reserve, $item); |
670 |
my $lastpickupdate = GetLastPickupDate($reserve, $item, $borrower); |
671 |
my $lastpickupdate = GetLastPickupDate(undef, $item); |
672 |
|
673 |
Gets the last pickup date from the issuingrules for the given reserves-row and sets the |
674 |
$reserve->{lastpickupdate}.-value. |
675 |
|
676 |
If the reserves-row is not passed, function tries to figure it out from the item-row. |
677 |
Calculating the last pickup date respects Calendar holidays and skips to the next open day. |
678 |
If the issuingrule's holdspickupwait is 0 or less, means that the lastpickupdate-feature |
679 |
is disabled for this kind of material. |
680 |
|
681 |
@PARAM1 koha.reserves-row |
682 |
@PARAM2 koha.items-row, If the reserve is not given, an item must be given to be |
683 |
able to find a reservation |
684 |
@PARAM3 koha.borrowers-row, OPTIONAL |
685 |
RETURNS DateTime, depicting the last pickup date. |
686 |
OR undef if there is an error or if the issuingrules disable this feature for this material. |
687 |
|
688 |
=cut |
689 |
|
690 |
sub GetLastPickupDate { |
691 |
my ($reserve, $item, $borrower) = @_; |
692 |
##Verify parameters |
693 |
if ( not defined $reserve and not defined $item ) { |
694 |
warn "C4::Reserves::GetMaxPickupDate(), is called without a reserve and an item"; |
695 |
return; |
696 |
} |
697 |
if ( defined $reserve and not defined $item ) { |
698 |
$item = C4::Items::GetItem( $reserve->{itemnumber} ); |
699 |
} |
700 |
|
701 |
unless ( defined $borrower) { |
702 |
my $borrower = Koha::Patrons->find( $reserve->{borrowernumber} ); |
703 |
$borrower = $borrower->unblessed; |
704 |
} |
705 |
|
706 |
unless ( defined $reserve ) { |
707 |
my $reserve = GetReservesFromItemnumber( $item->{itemnumber} ); |
708 |
} |
709 |
my $date = $reserve->{waitingdate}; |
710 |
unless ( $date ) { #It is possible that a reserve is just caught and it doesn't have a waitingdate yet. |
711 |
$date = DateTime->now( time_zone => C4::Context->tz() ); #So default to NOW() |
712 |
} |
713 |
else { |
714 |
$date = (ref $reserve->{waitingdate} eq 'DateTime') ? $reserve->{waitingdate} : dt_from_string($reserve->{waitingdate}); |
715 |
} |
716 |
##Get churning the LastPickupDate |
717 |
|
718 |
# Get the controlbranch |
719 |
my $controlbranch = GetReservesControlBranch( $item, $borrower ); |
720 |
my $hbr = C4::Context->preference('HomeOrHoldingBranch') || "homebranch"; |
721 |
my $branchcode = "*"; |
722 |
if ( $controlbranch eq "ItemHomeLibrary" ) { |
723 |
$branchcode = $item->{$hbr}; |
724 |
} elsif ( $controlbranch eq "PatronLibrary" ) { |
725 |
$branchcode = $borrower->branchcode; |
726 |
} |
727 |
warn 'getlastpickup'; |
728 |
warn $branchcode; |
729 |
warn $borrower->{'categorycode'}; |
730 |
warn $item->{itype}; |
731 |
my $issuingrule = Koha::IssuingRules->get_effective_issuing_rule({ |
732 |
branchcode => $branchcode, |
733 |
categorycode => $borrower->{'categorycode'}, |
734 |
itemtype => $item->{itype}, |
735 |
}); |
736 |
|
737 |
my $reservebranch; |
738 |
if ($reserve->{'branchcode'}) { |
739 |
$reservebranch = $reserve->{'branchcode'}; |
740 |
} else { |
741 |
$reservebranch = $reserve->branchcode; |
742 |
} |
743 |
if ( defined($issuingrule) && defined $issuingrule->holdspickupwait && $issuingrule->holdspickupwait > 0 ) { #If holdspickupwait is <= 0, it means this feature is disabled for this type of material. |
744 |
$date->add( days => $issuingrule->holdspickupwait ); |
745 |
my $calendar = Koha::Calendar->new( branchcode => $reservebranch ); |
746 |
my $is_holiday = $calendar->is_holiday( $date ); |
747 |
while ( $is_holiday ) { |
748 |
$date->add( days => 1 ); |
749 |
$is_holiday = $calendar->is_holiday( $date ); |
750 |
} |
751 |
$reserve->{lastpickupdate} = $date->ymd(); |
752 |
return $date; |
753 |
} |
754 |
#Without explicitly setting the return value undef, the lastpickupdate-column is |
755 |
# set as 0000-00-00 instead of NULL in DBD::MySQL. |
756 |
#This causes this hold to always expire any lastpickupdate check, |
757 |
## effectively canceling it as soon as cancel_expired_holds.pl is ran. |
758 |
##This is exactly the opposite of disabling the autoexpire feature. |
759 |
##So please let me explicitly return undef, because Perl cant always handle everything. |
760 |
delete $reserve->{lastpickupdate}; |
761 |
return undef; |
762 |
} |
763 |
|
664 |
=head2 CheckReserves |
764 |
=head2 CheckReserves |
665 |
|
765 |
|
666 |
($status, $matched_reserve, $possible_reserves) = &CheckReserves($itemnumber); |
766 |
($status, $matched_reserve, $possible_reserves) = &CheckReserves($itemnumber); |
Lines 1006-1012
sub ModReserveFill {
Link Here
|
1006 |
|
1106 |
|
1007 |
=head2 ModReserveStatus |
1107 |
=head2 ModReserveStatus |
1008 |
|
1108 |
|
1009 |
&ModReserveStatus($itemnumber, $newstatus); |
1109 |
&ModReserveStatus($itemnumber, $newstatus, $holdtype); |
1010 |
|
1110 |
|
1011 |
Update the reserve status for the active (priority=0) reserve. |
1111 |
Update the reserve status for the active (priority=0) reserve. |
1012 |
|
1112 |
|
Lines 1017-1030
$newstatus is the new status.
Link Here
|
1017 |
=cut |
1117 |
=cut |
1018 |
|
1118 |
|
1019 |
sub ModReserveStatus { |
1119 |
sub ModReserveStatus { |
1020 |
|
|
|
1021 |
#first : check if we have a reservation for this item . |
1120 |
#first : check if we have a reservation for this item . |
1022 |
my ($itemnumber, $newstatus) = @_; |
1121 |
my ($itemnumber, $newstatus) = @_; |
1023 |
my $dbh = C4::Context->dbh; |
1122 |
my $dbh = C4::Context->dbh; |
1024 |
|
1123 |
|
1025 |
my $query = "UPDATE reserves SET found = ?, waitingdate = NOW() WHERE itemnumber = ? AND found IS NULL AND priority = 0"; |
1124 |
my $now = dt_from_string; |
|
|
1125 |
|
1126 |
my $reserve = $dbh->selectrow_hashref(q{ |
1127 |
SELECT * |
1128 |
FROM reserves |
1129 |
WHERE itemnumber = ? |
1130 |
AND found IS NULL |
1131 |
AND priority = 0 |
1132 |
}, {}, $itemnumber); |
1133 |
|
1134 |
return unless $reserve; |
1135 |
my $borrower = Koha::Patrons->find( $reserve->{borrowernumber} ); |
1136 |
$borrower = $borrower->unblessed; |
1137 |
my $item = C4::Items::GetItem( $reserve->{itemnumber} ); |
1138 |
|
1139 |
my $lastpickupdate = GetLastPickupDate( $reserve, $item, $borrower ); |
1140 |
my $query = q{ |
1141 |
UPDATE reserves |
1142 |
SET found = ?, |
1143 |
waitingdate = ?, |
1144 |
lastpickupdate = ? |
1145 |
WHERE itemnumber = ? |
1146 |
AND found IS NULL |
1147 |
AND priority = 0 |
1148 |
}; |
1026 |
my $sth_set = $dbh->prepare($query); |
1149 |
my $sth_set = $dbh->prepare($query); |
1027 |
$sth_set->execute( $newstatus, $itemnumber ); |
1150 |
$sth_set->execute( $newstatus, $now, $lastpickupdate, $itemnumber ); |
1028 |
|
1151 |
|
1029 |
my $item = Koha::Items->find($itemnumber); |
1152 |
my $item = Koha::Items->find($itemnumber); |
1030 |
if ( ( $item->location eq 'CART' && $item->permanent_location ne 'CART' ) && $newstatus ) { |
1153 |
if ( ( $item->location eq 'CART' && $item->permanent_location ne 'CART' ) && $newstatus ) { |
Lines 1075-1080
sub ModReserveAffect {
Link Here
|
1075 |
$hold->itemnumber($itemnumber); |
1198 |
$hold->itemnumber($itemnumber); |
1076 |
$hold->set_waiting($transferToDo); |
1199 |
$hold->set_waiting($transferToDo); |
1077 |
|
1200 |
|
|
|
1201 |
my $item = C4::Items::GetItem( $itemnumber ); |
1202 |
my $borrower = Koha::Patrons->find( $borrowernumber ); |
1203 |
$borrower = $borrower->unblessed; |
1204 |
my $lastpickupdate = GetLastPickupDate( $hold, $item, $borrower ); |
1205 |
warn $lastpickupdate; |
1206 |
my $query = " |
1207 |
UPDATE reserves |
1208 |
SET lastpickupdate = ? |
1209 |
WHERE borrowernumber = ? |
1210 |
AND itemnumber = ? |
1211 |
"; |
1212 |
$sth = $dbh->prepare($query); |
1213 |
$sth->execute( $lastpickupdate, $borrowernumber,$itemnumber); |
1214 |
|
1078 |
_koha_notify_reserve( $hold->reserve_id ) |
1215 |
_koha_notify_reserve( $hold->reserve_id ) |
1079 |
if ( !$transferToDo && !$already_on_shelf ); |
1216 |
if ( !$transferToDo && !$already_on_shelf ); |
1080 |
|
1217 |
|
Lines 1530-1535
sub _Findgroupreserve {
Link Here
|
1530 |
reserves.borrowernumber AS borrowernumber, |
1667 |
reserves.borrowernumber AS borrowernumber, |
1531 |
reserves.reservedate AS reservedate, |
1668 |
reserves.reservedate AS reservedate, |
1532 |
reserves.branchcode AS branchcode, |
1669 |
reserves.branchcode AS branchcode, |
|
|
1670 |
reserves.lastpickupdate AS lastpickupdate, |
1533 |
reserves.cancellationdate AS cancellationdate, |
1671 |
reserves.cancellationdate AS cancellationdate, |
1534 |
reserves.found AS found, |
1672 |
reserves.found AS found, |
1535 |
reserves.reservenotes AS reservenotes, |
1673 |
reserves.reservenotes AS reservenotes, |
Lines 1565-1570
sub _Findgroupreserve {
Link Here
|
1565 |
reserves.borrowernumber AS borrowernumber, |
1703 |
reserves.borrowernumber AS borrowernumber, |
1566 |
reserves.reservedate AS reservedate, |
1704 |
reserves.reservedate AS reservedate, |
1567 |
reserves.branchcode AS branchcode, |
1705 |
reserves.branchcode AS branchcode, |
|
|
1706 |
reserves.lastpickupdate AS lastpickupdate, |
1568 |
reserves.cancellationdate AS cancellationdate, |
1707 |
reserves.cancellationdate AS cancellationdate, |
1569 |
reserves.found AS found, |
1708 |
reserves.found AS found, |
1570 |
reserves.reservenotes AS reservenotes, |
1709 |
reserves.reservenotes AS reservenotes, |
Lines 1600-1605
sub _Findgroupreserve {
Link Here
|
1600 |
reserves.reservedate AS reservedate, |
1739 |
reserves.reservedate AS reservedate, |
1601 |
reserves.waitingdate AS waitingdate, |
1740 |
reserves.waitingdate AS waitingdate, |
1602 |
reserves.branchcode AS branchcode, |
1741 |
reserves.branchcode AS branchcode, |
|
|
1742 |
reserves.lastpickupdate AS lastpickupdate, |
1603 |
reserves.cancellationdate AS cancellationdate, |
1743 |
reserves.cancellationdate AS cancellationdate, |
1604 |
reserves.found AS found, |
1744 |
reserves.found AS found, |
1605 |
reserves.reservenotes AS reservenotes, |
1745 |
reserves.reservenotes AS reservenotes, |
Lines 1820-1825
sub MoveReserve {
Link Here
|
1820 |
} |
1960 |
} |
1821 |
} |
1961 |
} |
1822 |
|
1962 |
|
|
|
1963 |
=head MoveWaitingdate |
1964 |
|
1965 |
#Move waitingdate two months and fifteen days forward. |
1966 |
my $dateDuration = DateTime::Duration->new( months => 2, days => 15 ); |
1967 |
$reserve = MoveWaitingdate( $reserve, $dateDuration); |
1968 |
|
1969 |
#Move waitingdate one year and eleven days backwards. |
1970 |
my $dateDuration = DateTime::Duration->new( years => -1, days => -11 ); |
1971 |
$reserve = MoveWaitingdate( $reserve, $dateDuration); |
1972 |
|
1973 |
Moves the waitingdate and updates the lastpickupdate to match. |
1974 |
If waitingdate is not defined, uses today. |
1975 |
Is intended to be used from automated tests, because under normal library |
1976 |
operations there should be NO REASON to move the waitingdate. |
1977 |
|
1978 |
@PARAM1 koha.reserves-row, with waitingdate set. |
1979 |
@PARAM2 DateTime::Duration, with the desired offset. |
1980 |
RETURNS koha.reserve-row, with keys waitingdate and lastpickupdate updated. |
1981 |
=cut |
1982 |
sub MoveWaitingdate { |
1983 |
my ($reserve, $dateDuration) = @_; |
1984 |
|
1985 |
my $dt = dt_from_string( $reserve->{waitingdate} ); |
1986 |
$dt->add_duration( $dateDuration ); |
1987 |
$reserve->{waitingdate} = $dt->ymd(); |
1988 |
|
1989 |
GetLastPickupDate( $reserve ); #Update the $reserve->{lastpickupdate} |
1990 |
|
1991 |
#UPDATE the DB part |
1992 |
my $dbh = C4::Context->dbh(); |
1993 |
my $sth = $dbh->prepare( "UPDATE reserves SET waitingdate=?, lastpickupdate=? WHERE reserve_id=?" ); |
1994 |
$sth->execute( $reserve->{waitingdate}, $reserve->{lastpickupdate}, $reserve->{reserve_id} ); |
1995 |
|
1996 |
return $reserve; |
1997 |
} |
1998 |
|
1823 |
=head2 MergeHolds |
1999 |
=head2 MergeHolds |
1824 |
|
2000 |
|
1825 |
MergeHolds($dbh,$to_biblio, $from_biblio); |
2001 |
MergeHolds($dbh,$to_biblio, $from_biblio); |
Lines 1918-1924
sub RevertWaitingStatus {
Link Here
|
1918 |
SET |
2094 |
SET |
1919 |
priority = 1, |
2095 |
priority = 1, |
1920 |
found = NULL, |
2096 |
found = NULL, |
1921 |
waitingdate = NULL |
2097 |
waitingdate = NULL, |
|
|
2098 |
lastpickupdate = NULL, |
1922 |
WHERE |
2099 |
WHERE |
1923 |
reserve_id = ? |
2100 |
reserve_id = ? |
1924 |
"; |
2101 |
"; |
Lines 1992-1998
sub ReserveSlip {
Link Here
|
1992 |
|
2169 |
|
1993 |
return unless $hold; |
2170 |
return unless $hold; |
1994 |
my $reserve = $hold->unblessed; |
2171 |
my $reserve = $hold->unblessed; |
1995 |
|
2172 |
warn Dumper($reserve); |
1996 |
return C4::Letters::GetPreparedLetter ( |
2173 |
return C4::Letters::GetPreparedLetter ( |
1997 |
module => 'circulation', |
2174 |
module => 'circulation', |
1998 |
letter_code => 'HOLD_SLIP', |
2175 |
letter_code => 'HOLD_SLIP', |