|
Lines 30-37
use Koha::Items;
Link Here
|
| 30 |
use Koha::Patrons; |
30 |
use Koha::Patrons; |
| 31 |
use Koha::Libraries; |
31 |
use Koha::Libraries; |
| 32 |
|
32 |
|
| 33 |
use List::Util qw( shuffle ); |
|
|
| 34 |
use List::MoreUtils qw( any ); |
33 |
use List::MoreUtils qw( any ); |
|
|
34 |
use List::Util qw( shuffle ); |
| 35 |
use POSIX qw(ceil); |
| 36 |
use Parallel::ForkManager; |
| 35 |
|
37 |
|
| 36 |
our (@ISA, @EXPORT_OK); |
38 |
our (@ISA, @EXPORT_OK); |
| 37 |
BEGIN { |
39 |
BEGIN { |
|
Lines 165-180
Top level function that turns reserves into tmp_holdsqueue and hold_fill_targets
Link Here
|
| 165 |
=cut |
167 |
=cut |
| 166 |
|
168 |
|
| 167 |
sub CreateQueue { |
169 |
sub CreateQueue { |
| 168 |
my $dbh = C4::Context->dbh; |
170 |
my $loops = shift || 1; |
|
|
171 |
|
| 172 |
my $dbh = C4::Context->dbh; |
| 169 |
|
173 |
|
| 170 |
$dbh->do("DELETE FROM tmp_holdsqueue"); # clear the old table for new info |
174 |
$dbh->do("DELETE FROM tmp_holdsqueue"); # clear the old table for new info |
| 171 |
$dbh->do("DELETE FROM hold_fill_targets"); |
175 |
$dbh->do("DELETE FROM hold_fill_targets"); |
| 172 |
|
176 |
|
| 173 |
my $total_bibs = 0; |
|
|
| 174 |
my $total_requests = 0; |
| 175 |
my $total_available_items = 0; |
| 176 |
my $num_items_mapped = 0; |
| 177 |
|
| 178 |
my $branches_to_use; |
177 |
my $branches_to_use; |
| 179 |
my $transport_cost_matrix; |
178 |
my $transport_cost_matrix; |
| 180 |
my $use_transport_cost_matrix = C4::Context->preference("UseTransportCostMatrix"); |
179 |
my $use_transport_cost_matrix = C4::Context->preference("UseTransportCostMatrix"); |
|
Lines 190-208
sub CreateQueue {
Link Here
|
| 190 |
|
189 |
|
| 191 |
my $bibs_with_pending_requests = GetBibsWithPendingHoldRequests(); |
190 |
my $bibs_with_pending_requests = GetBibsWithPendingHoldRequests(); |
| 192 |
|
191 |
|
|
|
192 |
# Split the list of bibs into chunks to run in parallel |
| 193 |
my @chunks; |
| 194 |
if ( $loops > 1 ) { |
| 195 |
my $i = 0; |
| 196 |
while (@$bibs_with_pending_requests) { |
| 197 |
push( @{ $chunks[$i] }, pop(@$bibs_with_pending_requests) ); |
| 198 |
|
| 199 |
$i++; |
| 200 |
$i = 0 if $i >= $loops; |
| 201 |
} |
| 202 |
|
| 203 |
my $pm = Parallel::ForkManager->new($loops); |
| 204 |
|
| 205 |
DATA_LOOP: |
| 206 |
foreach my $chunk (@chunks) { |
| 207 |
my $pid = $pm->start and next DATA_LOOP; |
| 208 |
_ProcessBiblios( $chunk, $branches_to_use, $transport_cost_matrix ); |
| 209 |
$pm->finish; |
| 210 |
} |
| 211 |
|
| 212 |
$pm->wait_all_children; |
| 213 |
} else { |
| 214 |
_ProcessBiblios( $bibs_with_pending_requests, $branches_to_use, $transport_cost_matrix ); |
| 215 |
} |
| 216 |
} |
| 217 |
|
| 218 |
=head2 _ProcessBiblios |
| 219 |
|
| 220 |
=cut |
| 221 |
|
| 222 |
sub _ProcessBiblios { |
| 223 |
my $bibs_with_pending_requests = shift; |
| 224 |
my $branches_to_use = shift; |
| 225 |
my $transport_cost_matrix = shift; |
| 226 |
|
| 193 |
foreach my $biblionumber (@$bibs_with_pending_requests) { |
227 |
foreach my $biblionumber (@$bibs_with_pending_requests) { |
| 194 |
$total_bibs++; |
|
|
| 195 |
my $hold_requests = GetPendingHoldRequestsForBib($biblionumber); |
228 |
my $hold_requests = GetPendingHoldRequestsForBib($biblionumber); |
| 196 |
my $available_items = GetItemsAvailableToFillHoldRequestsForBib($biblionumber, $branches_to_use); |
229 |
my $available_items = GetItemsAvailableToFillHoldRequestsForBib($biblionumber, $branches_to_use); |
| 197 |
$total_requests += scalar(@$hold_requests); |
|
|
| 198 |
$total_available_items += scalar(@$available_items); |
| 199 |
|
230 |
|
| 200 |
my $item_map = MapItemsToHoldRequests($hold_requests, $available_items, $branches_to_use, $transport_cost_matrix); |
231 |
my $item_map = MapItemsToHoldRequests($hold_requests, $available_items, $branches_to_use, $transport_cost_matrix); |
| 201 |
$item_map or next; |
232 |
$item_map or next; |
| 202 |
my $item_map_size = scalar(keys %$item_map) |
233 |
my $item_map_size = scalar(keys %$item_map) |
| 203 |
or next; |
234 |
or next; |
| 204 |
|
235 |
|
| 205 |
$num_items_mapped += $item_map_size; |
|
|
| 206 |
CreatePicklistFromItemMap($item_map); |
236 |
CreatePicklistFromItemMap($item_map); |
| 207 |
AddToHoldTargetMap($item_map); |
237 |
AddToHoldTargetMap($item_map); |
| 208 |
if (($item_map_size < scalar(@$hold_requests )) and |
238 |
if (($item_map_size < scalar(@$hold_requests )) and |
|
Lines 227-238
that have one or more unfilled hold requests.
Link Here
|
| 227 |
sub GetBibsWithPendingHoldRequests { |
257 |
sub GetBibsWithPendingHoldRequests { |
| 228 |
my $dbh = C4::Context->dbh; |
258 |
my $dbh = C4::Context->dbh; |
| 229 |
|
259 |
|
| 230 |
my $bib_query = "SELECT DISTINCT biblionumber |
260 |
my $bib_query = "SELECT biblionumber, |
| 231 |
FROM reserves |
261 |
COUNT(biblionumber) AS holds_count |
| 232 |
WHERE found IS NULL |
262 |
FROM reserves |
| 233 |
AND priority > 0 |
263 |
WHERE found IS NULL |
| 234 |
AND reservedate <= CURRENT_DATE() |
264 |
AND priority > 0 |
| 235 |
AND suspend = 0 |
265 |
AND reservedate <= CURRENT_DATE() |
|
|
266 |
AND suspend = 0 |
| 267 |
GROUP BY biblionumber |
| 268 |
ORDER BY biblionumber DESC |
| 236 |
"; |
269 |
"; |
| 237 |
my $sth = $dbh->prepare($bib_query); |
270 |
my $sth = $dbh->prepare($bib_query); |
| 238 |
|
271 |
|