3 # Test C4::HoldsQueue::CreateQueue() for both transport cost matrix
4 # and StaticHoldsQueueWeight array (no RandomizeHoldsQueueWeight, no point)
5 # Wraps tests in transaction that's rolled back, so no data is destroyed
6 # MySQL WARNING: This makes sense only if your tables are InnoDB, otherwise
7 # transactions are not supported and mess is left behind
11 use Test::More tests => 54;
21 use Koha::CirculationRules;
23 use t::lib::TestBuilder;
28 use lib $FindBin::Bin;
29 use_ok('C4::Reserves');
30 use_ok('C4::HoldsQueue');
33 my $schema = Koha::Database->schema;
34 $schema->storage->txn_begin;
35 my $dbh = C4::Context->dbh;
36 $dbh->do("DELETE FROM circulation_rules");
38 my $builder = t::lib::TestBuilder->new;
40 t::lib::Mocks::mock_preference( 'UseBranchTransferLimits', '0' );
41 t::lib::Mocks::mock_preference( 'BranchTransferLimitsType', 'itemtype' );
43 my $library1 = $builder->build({
46 my $library2 = $builder->build({
49 my $library3 = $builder->build({
53 my $TITLE = "Test Holds Queue XXX";
55 my $borrower = $builder->build({
58 branchcode => $library1->{branchcode},
62 my $borrowernumber = $borrower->{borrowernumber};
63 # Set special (for this test) branches
64 my $borrower_branchcode = $borrower->{branchcode};
65 my @branchcodes = ( $library1->{branchcode}, $library2->{branchcode}, $library3->{branchcode} );
66 my @other_branches = ( $library2->{branchcode}, $library3->{branchcode} );
67 my $least_cost_branch_code = pop @other_branches;
68 my $itemtype = $builder->build({ source => 'Itemtype', value => { notforloan => 0 } })->{itemtype};
71 # Sysprefs and cost matrix
72 t::lib::Mocks::mock_preference('HoldsQueueSkipClosed', 0);
73 t::lib::Mocks::mock_preference('LocalHoldsPriority', 0);
74 $dbh->do("UPDATE systempreferences SET value = ? WHERE variable = 'StaticHoldsQueueWeight'", undef,
75 join( ',', @other_branches, $borrower_branchcode, $least_cost_branch_code));
76 $dbh->do("UPDATE systempreferences SET value = '0' WHERE variable = 'RandomizeHoldsQueueWeight'");
78 $dbh->do("DELETE FROM transport_cost");
79 my $transport_cost_insert_sth = $dbh->prepare("insert into transport_cost (frombranch, tobranch, cost) values (?, ?, ?)");
80 # Favour $least_cost_branch_code
81 $transport_cost_insert_sth->execute($borrower_branchcode, $least_cost_branch_code, 0.2);
82 $transport_cost_insert_sth->execute($least_cost_branch_code, $borrower_branchcode, 0.2);
83 my @b = @other_branches;
84 while ( my $b1 = shift @b ) {
85 foreach my $b2 ($borrower_branchcode, $least_cost_branch_code, @b) {
86 $transport_cost_insert_sth->execute($b1, $b2, 0.5);
87 $transport_cost_insert_sth->execute($b2, $b1, 0.5);
92 # Loanable items - all possible combinations of homebranch and holdingbranch
93 $dbh->do("INSERT INTO biblio (frameworkcode, author, title, datecreated)
94 VALUES ('SER', 'Koha test', '$TITLE', '2011-02-01')");
95 my $biblionumber = $dbh->selectrow_array("SELECT biblionumber FROM biblio WHERE title = '$TITLE'")
96 or BAIL_OUT("Cannot find newly created biblio record");
97 $dbh->do("INSERT INTO biblioitems (biblionumber, itemtype)
98 VALUES ($biblionumber, '$itemtype')");
99 my $biblioitemnumber = $dbh->selectrow_array("SELECT biblioitemnumber FROM biblioitems WHERE biblionumber = $biblionumber")
100 or BAIL_OUT("Cannot find newly created biblioitems record");
102 my $items_insert_sth = $dbh->prepare("INSERT INTO items (biblionumber, biblioitemnumber, barcode, homebranch, holdingbranch, notforloan, damaged, itemlost, withdrawn, onloan, itype)
103 VALUES ($biblionumber, $biblioitemnumber, ?, ?, ?, 0, 0, 0, 0, NULL, '$itemtype')"); # CURRENT_DATE - 3)");
104 my $first_barcode = int(rand(1000000000000)); # XXX
105 my $barcode = $first_barcode;
106 foreach ( $borrower_branchcode, $least_cost_branch_code, @other_branches ) {
107 $items_insert_sth->execute($barcode++, $borrower_branchcode, $_);
108 $items_insert_sth->execute($barcode++, $_, $_);
109 $items_insert_sth->execute($barcode++, $_, $borrower_branchcode);
112 # Remove existing reserves, makes debugging easier
113 $dbh->do("DELETE FROM reserves");
114 my $bibitems = undef;
119 branchcode => $borrower_branchcode,
120 borrowernumber => $borrowernumber,
121 biblionumber => $biblionumber,
122 priority => $priority,
125 # $resdate, $expdate, $notes, $title, $checkitem, $found
126 $dbh->do("UPDATE reserves SET reservedate = DATE_SUB( reservedate, INTERVAL 1 DAY )");
129 my $use_cost_matrix_sth = $dbh->prepare("UPDATE systempreferences SET value = ? WHERE variable = 'UseTransportCostMatrix'");
130 my $test_sth = $dbh->prepare("SELECT * FROM hold_fill_targets
131 JOIN tmp_holdsqueue USING (borrowernumber, biblionumber, itemnumber)
132 JOIN items USING (itemnumber)
133 WHERE borrowernumber = $borrowernumber");
135 # We have a book available homed in borrower branch, no point fiddling with AutomaticItemReturn
136 t::lib::Mocks::mock_preference('AutomaticItemReturn', 0);
137 test_queue ('take from homebranch', 0, $borrower_branchcode, $borrower_branchcode);
138 test_queue ('take from homebranch', 1, $borrower_branchcode, $borrower_branchcode);
140 $dbh->do("DELETE FROM tmp_holdsqueue");
141 $dbh->do("DELETE FROM hold_fill_targets");
142 $dbh->do("DELETE FROM issues WHERE itemnumber IN (SELECT itemnumber FROM items WHERE homebranch = '$borrower_branchcode' AND holdingbranch = '$borrower_branchcode')");
143 $dbh->do("DELETE FROM items WHERE homebranch = '$borrower_branchcode' AND holdingbranch = '$borrower_branchcode'");
144 # test_queue will flush
145 t::lib::Mocks::mock_preference('AutomaticItemReturn', 1);
146 # Not sure how to make this test more difficult - holding branch does not matter
148 $dbh->do("DELETE FROM tmp_holdsqueue");
149 $dbh->do("DELETE FROM hold_fill_targets");
150 $dbh->do("DELETE FROM issues WHERE itemnumber IN (SELECT itemnumber FROM items WHERE homebranch = '$borrower_branchcode')");
151 $dbh->do("DELETE FROM items WHERE homebranch = '$borrower_branchcode'");
152 t::lib::Mocks::mock_preference('AutomaticItemReturn', 0);
153 # We have a book available held in borrower branch
154 test_queue ('take from holdingbranch', 0, $borrower_branchcode, $borrower_branchcode);
155 test_queue ('take from holdingbranch', 1, $borrower_branchcode, $borrower_branchcode);
157 $dbh->do("DELETE FROM tmp_holdsqueue");
158 $dbh->do("DELETE FROM hold_fill_targets");
159 $dbh->do("DELETE FROM issues WHERE itemnumber IN (SELECT itemnumber FROM items WHERE holdingbranch = '$borrower_branchcode')");
160 $dbh->do("DELETE FROM items WHERE holdingbranch = '$borrower_branchcode'");
161 # No book available in borrower branch, pick according to the rules
162 # Frst branch from StaticHoldsQueueWeight
163 test_queue ('take from lowest cost branch', 0, $borrower_branchcode, $other_branches[0]);
164 test_queue ('take from lowest cost branch', 1, $borrower_branchcode, $least_cost_branch_code);
165 my $queue = C4::HoldsQueue::GetHoldsQueueItems($least_cost_branch_code) || [];
166 my $queue_item = $queue->[0];
168 && $queue_item->{pickbranch} eq $borrower_branchcode
169 && $queue_item->{holdingbranch} eq $least_cost_branch_code, "GetHoldsQueueItems" )
170 or diag( "Expected item for pick $borrower_branchcode, hold $least_cost_branch_code, got ".Dumper($queue_item) );
171 ok( exists($queue_item->{itype}), 'item type included in queued items list (bug 5825)' );
174 C4::HoldsQueue::least_cost_branch( 'B', [ 'A', 'B', 'C' ] ) eq 'B',
175 'C4::HoldsQueue::least_cost_branch returns the local branch if it is in the list of branches to pull from'
178 # XXX All this tests are for borrower branch pick-up.
179 # Maybe needs expanding to homebranch or holdingbranch pick-up.
181 $schema->txn_rollback;
184 ### Test holds queue builder does not violate holds policy ###
186 # Clear out existing rules relating to holdallowed
187 $dbh->do("DELETE FROM circulation_rules");
189 t::lib::Mocks::mock_preference('UseTransportCostMatrix', 0);
191 $itemtype = $builder->build({ source => 'Itemtype', value => { notforloan => 0 } })->{itemtype};
193 $library1 = $builder->build({
196 $library2 = $builder->build({
199 $library3 = $builder->build({
202 @branchcodes = ( $library1->{branchcode}, $library2->{branchcode}, $library3->{branchcode} );
204 my $borrower1 = $builder->build({
205 source => 'Borrower',
207 branchcode => $branchcodes[0],
210 my $borrower2 = $builder->build({
211 source => 'Borrower',
213 branchcode => $branchcodes[1],
216 my $borrower3 = $builder->build({
217 source => 'Borrower',
219 branchcode => $branchcodes[2],
236 $biblionumber = $dbh->selectrow_array("SELECT biblionumber FROM biblio WHERE title = '$TITLE'")
237 or BAIL_OUT("Cannot find newly created biblio record");
240 INSERT INTO biblioitems (
248 $biblioitemnumber = $dbh->selectrow_array("SELECT biblioitemnumber FROM biblioitems WHERE biblionumber = $biblionumber")
249 or BAIL_OUT("Cannot find newly created biblioitems record");
251 $items_insert_sth = $dbh->prepare(qq{
278 # Create 3 items from 2 branches ( branches are for borrowers 1 and 2 respectively )
279 $barcode = int( rand(1000000000000) );
280 $items_insert_sth->execute( $barcode + 0, $branchcodes[0], $branchcodes[0] );
281 $items_insert_sth->execute( $barcode + 1, $branchcodes[1], $branchcodes[1] );
282 $items_insert_sth->execute( $barcode + 2, $branchcodes[1], $branchcodes[1] );
284 $dbh->do("DELETE FROM reserves");
285 my $sth = $dbh->prepare(q{
286 INSERT INTO reserves (
292 ) VALUES ( ?,?,?,?, CURRENT_DATE() )
294 $sth->execute( $borrower1->{borrowernumber}, $biblionumber, $branchcodes[0], 1 );
295 $sth->execute( $borrower2->{borrowernumber}, $biblionumber, $branchcodes[0], 2 );
296 $sth->execute( $borrower3->{borrowernumber}, $biblionumber, $branchcodes[0], 3 );
300 $dbh->do("DELETE FROM circulation_rules");
301 Koha::CirculationRules->set_rule(
303 rule_name => 'holdallowed',
309 C4::HoldsQueue::CreateQueue();
310 $holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
311 is( @$holds_queue, 2, "Holds queue filling correct number for default holds policy 'from home library'" );
312 is( $holds_queue->[0]->{cardnumber}, $borrower1->{cardnumber}, "Holds queue filling 1st correct hold for default holds policy 'from home library'");
313 is( $holds_queue->[1]->{cardnumber}, $borrower2->{cardnumber}, "Holds queue filling 2nd correct hold for default holds policy 'from home library'");
315 # Test skipping hold picks for closed libraries.
316 # At this point in the test, we have 2 rows in the holds queue
317 # 1 of which is coming from MPL. Let's enable HoldsQueueSkipClosed
318 # and make today a holiday for MPL. When we run it again we should only
319 # have 1 row in the holds queue
320 t::lib::Mocks::mock_preference('HoldsQueueSkipClosed', 1);
321 my $today = dt_from_string();
322 C4::Calendar->new( branchcode => $branchcodes[0] )->insert_single_holiday(
323 day => $today->day(),
324 month => $today->month(),
325 year => $today->year(),
327 description => "$today",
329 # If the test below is removed, aother tests using the holiday will fail. For some reason if we call is_holiday now
330 # the holiday will get set in cache correctly, but not if we let C4::HoldsQueue call is_holiday instead.
331 is( Koha::Calendar->new( branchcode => $branchcodes[0] )->is_holiday( $today ), 1, 'Is today a holiday for pickup branch' );
332 C4::HoldsQueue::CreateQueue();
333 $holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
334 is( scalar( @$holds_queue ), 1, "Holds not filled with items from closed libraries" );
335 t::lib::Mocks::mock_preference('HoldsQueueSkipClosed', 0);
337 $dbh->do("DELETE FROM circulation_rules");
338 Koha::CirculationRules->set_rule(
340 rule_name => 'holdallowed',
346 C4::HoldsQueue::CreateQueue();
347 $holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
348 is( @$holds_queue, 3, "Holds queue filling correct number for holds for default holds policy 'from any library'" );
350 # Test skipping hold picks for closed libraries without transport cost matrix
351 # At this point in the test, we have 3 rows in the holds queue
352 # one of which is coming from MPL. Let's enable HoldsQueueSkipClosed
353 # and use our previously created holiday for MPL
354 # When we run it again we should only have 2 rows in the holds queue
355 t::lib::Mocks::mock_preference( 'HoldsQueueSkipClosed', 1 );
356 C4::HoldsQueue::CreateQueue();
357 $holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
358 is( scalar( @$holds_queue ), 2, "Holds not filled with items from closed libraries" );
359 t::lib::Mocks::mock_preference( 'HoldsQueueSkipClosed', 0 );
361 ## Test LocalHoldsPriority
362 t::lib::Mocks::mock_preference('LocalHoldsPriority', 1);
364 $dbh->do("DELETE FROM circulation_rules");
365 Koha::CirculationRules->set_rule(
367 rule_name => 'holdallowed',
373 $dbh->do("DELETE FROM issues");
375 # Test homebranch = patron branch
376 t::lib::Mocks::mock_preference('LocalHoldsPriorityPatronControl', 'HomeLibrary');
377 t::lib::Mocks::mock_preference('LocalHoldsPriorityItemControl', 'homebranch');
378 C4::Context->clear_syspref_cache();
379 $dbh->do("DELETE FROM reserves");
380 $sth->execute( $borrower1->{borrowernumber}, $biblionumber, $branchcodes[0], 1 );
381 $sth->execute( $borrower2->{borrowernumber}, $biblionumber, $branchcodes[0], 2 );
382 $sth->execute( $borrower3->{borrowernumber}, $biblionumber, $branchcodes[0], 3 );
384 $dbh->do("DELETE FROM items");
385 # barcode, homebranch, holdingbranch, itemtype
386 $items_insert_sth->execute( $barcode + 4, $branchcodes[2], $branchcodes[0] );
388 C4::HoldsQueue::CreateQueue();
389 $holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
390 is( $holds_queue->[0]->{cardnumber}, $borrower3->{cardnumber}, "Holds queue giving priority to patron who's home library matches item's home library");
392 ### Test branch transfer limits ###
393 t::lib::Mocks::mock_preference('LocalHoldsPriorityPatronControl', 'HomeLibrary');
394 t::lib::Mocks::mock_preference('LocalHoldsPriorityItemControl', 'holdingbranch');
395 t::lib::Mocks::mock_preference( 'UseBranchTransferLimits', '1' );
396 C4::Context->clear_syspref_cache();
397 $dbh->do("DELETE FROM reserves");
398 $sth->execute( $borrower1->{borrowernumber}, $biblionumber, $branchcodes[0], 1 );
399 $sth->execute( $borrower2->{borrowernumber}, $biblionumber, $branchcodes[1], 2 );
401 $dbh->do("DELETE FROM items");
402 # barcode, homebranch, holdingbranch, itemtype
403 $items_insert_sth->execute( $barcode, $branchcodes[2], $branchcodes[2] );
404 my $item = Koha::Items->find( { barcode => $barcode } );
406 my $limit1 = Koha::Item::Transfer::Limit->new(
408 toBranch => $branchcodes[0],
409 fromBranch => $branchcodes[2],
410 itemtype => $item->effective_itemtype,
414 C4::HoldsQueue::CreateQueue();
415 $holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
416 is( $holds_queue->[0]->{cardnumber}, $borrower2->{cardnumber}, "Holds queue skips hold transfer that would violate branch transfer limits");
418 my $limit2 = Koha::Item::Transfer::Limit->new(
420 toBranch => $branchcodes[1],
421 fromBranch => $branchcodes[2],
422 itemtype => $item->effective_itemtype,
426 C4::HoldsQueue::CreateQueue();
427 $holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
428 is( $holds_queue->[0]->{cardnumber}, undef, "Holds queue doesn't fill hold where all available items would violate branch transfer limits");
432 t::lib::Mocks::mock_preference( 'UseBranchTransferLimits', '0' );
433 ### END Test branch transfer limits ###
435 # Test holdingbranch = patron branch
436 t::lib::Mocks::mock_preference('LocalHoldsPriorityPatronControl', 'HomeLibrary');
437 t::lib::Mocks::mock_preference('LocalHoldsPriorityItemControl', 'holdingbranch');
438 C4::Context->clear_syspref_cache();
439 $dbh->do("DELETE FROM reserves");
440 $sth->execute( $borrower1->{borrowernumber}, $biblionumber, $branchcodes[0], 1 );
441 $sth->execute( $borrower2->{borrowernumber}, $biblionumber, $branchcodes[0], 2 );
442 $sth->execute( $borrower3->{borrowernumber}, $biblionumber, $branchcodes[0], 3 );
444 $dbh->do("DELETE FROM items");
445 # barcode, homebranch, holdingbranch, itemtype
446 $items_insert_sth->execute( $barcode + 4, $branchcodes[0], $branchcodes[2] );
448 C4::HoldsQueue::CreateQueue();
449 $holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
450 is( $holds_queue->[0]->{cardnumber}, $borrower3->{cardnumber}, "Holds queue giving priority to patron who's home library matches item's holding library");
452 # Test holdingbranch = pickup branch
453 t::lib::Mocks::mock_preference('LocalHoldsPriorityPatronControl', 'PickupLibrary');
454 t::lib::Mocks::mock_preference('LocalHoldsPriorityItemControl', 'holdingbranch');
455 C4::Context->clear_syspref_cache();
456 $dbh->do("DELETE FROM reserves");
457 $sth->execute( $borrower1->{borrowernumber}, $biblionumber, $branchcodes[0], 1 );
458 $sth->execute( $borrower2->{borrowernumber}, $biblionumber, $branchcodes[0], 2 );
459 $sth->execute( $borrower3->{borrowernumber}, $biblionumber, $branchcodes[2], 3 );
461 $dbh->do("DELETE FROM items");
462 # barcode, homebranch, holdingbranch, itemtype
463 $items_insert_sth->execute( $barcode + 4, $branchcodes[0], $branchcodes[2] );
465 C4::HoldsQueue::CreateQueue();
466 $holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
467 is( $holds_queue->[0]->{cardnumber}, $borrower3->{cardnumber}, "Holds queue giving priority to patron who's home library matches item's holding library");
469 # Test homebranch = pickup branch
470 t::lib::Mocks::mock_preference('LocalHoldsPriorityPatronControl', 'PickupLibrary');
471 t::lib::Mocks::mock_preference('LocalHoldsPriorityItemControl', 'homebranch');
472 C4::Context->clear_syspref_cache();
473 $dbh->do("DELETE FROM reserves");
474 $sth->execute( $borrower1->{borrowernumber}, $biblionumber, $branchcodes[0], 1 );
475 $sth->execute( $borrower2->{borrowernumber}, $biblionumber, $branchcodes[0], 2 );
476 $sth->execute( $borrower3->{borrowernumber}, $biblionumber, $branchcodes[2], 3 );
478 $dbh->do("DELETE FROM items");
479 # barcode, homebranch, holdingbranch, itemtype
480 $items_insert_sth->execute( $barcode + 4, $branchcodes[2], $branchcodes[0] );
482 C4::HoldsQueue::CreateQueue();
483 $holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
484 is( $holds_queue->[0]->{cardnumber}, $borrower3->{cardnumber}, "Holds queue giving priority to patron who's home library matches item's holding library");
486 t::lib::Mocks::mock_preference('LocalHoldsPriority', 0);
487 ## End testing of LocalHoldsPriority
491 $itemtype = $builder->build({ source => 'Itemtype', value => { notforloan => 0 } })->{itemtype};
492 $borrowernumber = $borrower3->{borrowernumber};
493 my $library_A = $library1->{branchcode};
494 my $library_B = $library2->{branchcode};
495 my $library_C = $borrower3->{branchcode};
496 $dbh->do("DELETE FROM reserves");
497 $dbh->do("DELETE FROM issues");
498 $dbh->do("DELETE FROM items");
499 $dbh->do("DELETE FROM biblio");
500 $dbh->do("DELETE FROM biblioitems");
501 $dbh->do("DELETE FROM transport_cost");
502 $dbh->do("DELETE FROM tmp_holdsqueue");
503 $dbh->do("DELETE FROM hold_fill_targets");
506 INSERT INTO biblio (frameworkcode, author, title, datecreated) VALUES ('', 'Koha test', '$TITLE', '2011-02-01')
509 $biblionumber = $dbh->selectrow_array("SELECT biblionumber FROM biblio WHERE title = '$TITLE'")
510 or BAIL_OUT("Cannot find newly created biblio record");
512 $dbh->do("INSERT INTO biblioitems (biblionumber, itemtype) VALUES ($biblionumber, '$itemtype')");
515 $dbh->selectrow_array("SELECT biblioitemnumber FROM biblioitems WHERE biblionumber = $biblionumber")
516 or BAIL_OUT("Cannot find newly created biblioitems record");
519 INSERT INTO items (biblionumber, biblioitemnumber, homebranch, holdingbranch, notforloan, damaged, itemlost, withdrawn, onloan, itype)
520 VALUES ($biblionumber, $biblioitemnumber, '$library_A', '$library_A', 0, 0, 0, 0, NULL, '$itemtype')
524 INSERT INTO items (biblionumber, biblioitemnumber, homebranch, holdingbranch, notforloan, damaged, itemlost, withdrawn, onloan, itype)
525 VALUES ($biblionumber, $biblioitemnumber, '$library_B', '$library_B', 0, 0, 0, 0, NULL, '$itemtype')
528 Koha::CirculationRules->set_rules(
530 branchcode => $library_A,
531 itemtype => $itemtype,
534 returnbranch => 'homebranch',
539 $dbh->do( "UPDATE systempreferences SET value = ? WHERE variable = 'StaticHoldsQueueWeight'",
540 undef, join( ',', $library_B, $library_A, $library_C ) );
541 $dbh->do( "UPDATE systempreferences SET value = 0 WHERE variable = 'RandomizeHoldsQueueWeight'" );
543 my $reserve_id = AddReserve(
545 branchcode => $library_C,
546 borrowernumber => $borrowernumber,
547 biblionumber => $biblionumber,
551 C4::HoldsQueue::CreateQueue();
552 $holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
553 is( @$holds_queue, 1, "Bug 14297 - Holds Queue building ignoring holds where pickup & home branch don't match and item is not from le");
557 $itemtype = $builder->build({ source => 'Itemtype', value => { notforloan => 0 } })->{itemtype};
558 $borrowernumber = $borrower2->{borrowernumber};
559 $library_A = $library1->{branchcode};
560 $library_B = $library2->{branchcode};
561 $dbh->do("DELETE FROM reserves");
562 $dbh->do("DELETE FROM issues");
563 $dbh->do("DELETE FROM items");
564 $dbh->do("DELETE FROM biblio");
565 $dbh->do("DELETE FROM biblioitems");
566 $dbh->do("DELETE FROM transport_cost");
567 $dbh->do("DELETE FROM tmp_holdsqueue");
568 $dbh->do("DELETE FROM hold_fill_targets");
570 t::lib::Mocks::mock_preference("UseTransportCostMatrix",1);
572 my $tc_rs = $schema->resultset('TransportCost');
573 $tc_rs->create({ frombranch => $library_A, tobranch => $library_B, cost => 0, disable_transfer => 1 });
574 $tc_rs->create({ frombranch => $library_B, tobranch => $library_A, cost => 0, disable_transfer => 1 });
577 INSERT INTO biblio (frameworkcode, author, title, datecreated) VALUES ('', 'Koha test', '$TITLE', '2011-02-01')
580 $biblionumber = $dbh->selectrow_array("SELECT biblionumber FROM biblio WHERE title = '$TITLE'")
581 or BAIL_OUT("Cannot find newly created biblio record");
583 $dbh->do("INSERT INTO biblioitems (biblionumber, itemtype) VALUES ($biblionumber, '$itemtype')");
586 $dbh->selectrow_array("SELECT biblioitemnumber FROM biblioitems WHERE biblionumber = $biblionumber")
587 or BAIL_OUT("Cannot find newly created biblioitems record");
590 INSERT INTO items (biblionumber, biblioitemnumber, homebranch, holdingbranch, notforloan, damaged, itemlost, withdrawn, onloan, itype)
591 VALUES ($biblionumber, $biblioitemnumber, '$library_A', '$library_A', 0, 0, 0, 0, NULL, '$itemtype')
594 $reserve_id = AddReserve(
596 branchcode => $library_B,
597 borrowernumber => $borrowernumber,
598 biblionumber => $biblionumber,
603 C4::HoldsQueue::CreateQueue();
604 $holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
605 is( @$holds_queue, 0, "Bug 15062 - Holds queue with Transport Cost Matrix will transfer item even if transfers disabled");
608 # Test hold_fulfillment_policy
609 t::lib::Mocks::mock_preference( "UseTransportCostMatrix", 0 );
610 $borrowernumber = $borrower3->{borrowernumber};
611 $library_A = $library1->{branchcode};
612 $library_B = $library2->{branchcode};
613 $library_C = $library3->{branchcode};
614 $dbh->do("DELETE FROM reserves");
615 $dbh->do("DELETE FROM issues");
616 $dbh->do("DELETE FROM items");
617 $dbh->do("DELETE FROM biblio");
618 $dbh->do("DELETE FROM biblioitems");
619 $dbh->do("DELETE FROM transport_cost");
620 $dbh->do("DELETE FROM tmp_holdsqueue");
621 $dbh->do("DELETE FROM hold_fill_targets");
623 $dbh->do("INSERT INTO biblio (frameworkcode, author, title, datecreated) VALUES ('', 'Koha test', '$TITLE', '2011-02-01')");
625 $biblionumber = $dbh->selectrow_array("SELECT biblionumber FROM biblio WHERE title = '$TITLE'")
626 or BAIL_OUT("Cannot find newly created biblio record");
628 $dbh->do("INSERT INTO biblioitems (biblionumber, itemtype) VALUES ($biblionumber, '$itemtype')");
631 $dbh->selectrow_array("SELECT biblioitemnumber FROM biblioitems WHERE biblionumber = $biblionumber")
632 or BAIL_OUT("Cannot find newly created biblioitems record");
635 INSERT INTO items (biblionumber, biblioitemnumber, homebranch, holdingbranch, notforloan, damaged, itemlost, withdrawn, onloan, itype)
636 VALUES ($biblionumber, $biblioitemnumber, '$library_A', '$library_B', 0, 0, 0, 0, NULL, '$itemtype')
639 # With hold_fulfillment_policy = homebranch, hold should only be picked up if pickup branch = homebranch
640 $dbh->do("DELETE FROM circulation_rules");
641 Koha::CirculationRules->set_rules(
647 hold_fulfillment_policy => 'homebranch',
652 # Home branch matches pickup branch
653 $reserve_id = AddReserve(
655 branchcode => $library_A,
656 borrowernumber => $borrowernumber,
657 biblionumber => $biblionumber,
662 C4::HoldsQueue::CreateQueue();
663 $holds_queue = $dbh->selectall_arrayref( "SELECT * FROM tmp_holdsqueue", { Slice => {} } );
664 is( @$holds_queue, 1, "Hold where pickup branch matches home branch targeted" );
665 my $target_rs = $schema->resultset('HoldFillTarget');
666 is( $target_rs->next->reserve_id, $reserve_id, "Reserve id correctly set in hold fill target for title level hold" );
667 Koha::Holds->find( $reserve_id )->cancel;
669 # Holding branch matches pickup branch
670 $reserve_id = AddReserve(
672 branchcode => $library_B,
673 borrowernumber => $borrowernumber,
674 biblionumber => $biblionumber,
680 C4::HoldsQueue::CreateQueue();
681 $holds_queue = $dbh->selectall_arrayref( "SELECT * FROM tmp_holdsqueue", { Slice => {} } );
682 is( @$holds_queue, 0, "Hold where pickup ne home, pickup eq home not targeted" );
683 Koha::Holds->find( $reserve_id )->cancel;
685 # Neither branch matches pickup branch
686 $reserve_id = AddReserve(
688 branchcode => $library_C,
689 borrowernumber => $borrowernumber,
690 biblionumber => $biblionumber,
695 C4::HoldsQueue::CreateQueue();
696 $holds_queue = $dbh->selectall_arrayref( "SELECT * FROM tmp_holdsqueue", { Slice => {} } );
697 is( @$holds_queue, 0, "Hold where pickup ne home, pickup ne holding not targeted" );
698 Koha::Holds->find( $reserve_id )->cancel;
700 # With hold_fulfillment_policy = holdingbranch, hold should only be picked up if pickup branch = holdingbranch
701 $dbh->do("DELETE FROM circulation_rules");
702 Koha::CirculationRules->set_rules(
708 hold_fulfillment_policy => 'holdingbranch',
713 # Home branch matches pickup branch
714 $reserve_id = AddReserve(
716 branchcode => $library_A,
717 borrowernumber => $borrowernumber,
718 biblionumber => $biblionumber,
723 C4::HoldsQueue::CreateQueue();
724 $holds_queue = $dbh->selectall_arrayref( "SELECT * FROM tmp_holdsqueue", { Slice => {} } );
725 is( @$holds_queue, 0, "Hold where pickup eq home, pickup ne holding not targeted" );
726 Koha::Holds->find( $reserve_id )->cancel;
728 # Holding branch matches pickup branch
729 $reserve_id = AddReserve(
731 branchcode => $library_B,
732 borrowernumber => $borrowernumber,
733 biblionumber => $biblionumber,
738 C4::HoldsQueue::CreateQueue();
739 $holds_queue = $dbh->selectall_arrayref( "SELECT * FROM tmp_holdsqueue", { Slice => {} } );
740 is( @$holds_queue, 1, "Hold where pickup ne home, pickup eq holding targeted" );
741 Koha::Holds->find( $reserve_id )->cancel;
743 # Neither branch matches pickup branch
744 $reserve_id = AddReserve(
746 branchcode => $library_C,
747 borrowernumber => $borrowernumber,
748 biblionumber => $biblionumber,
753 C4::HoldsQueue::CreateQueue();
754 $holds_queue = $dbh->selectall_arrayref( "SELECT * FROM tmp_holdsqueue", { Slice => {} } );
755 is( @$holds_queue, 0, "Hold where pickup ne home, pickup ne holding not targeted" );
756 Koha::Holds->find( $reserve_id )->cancel;
758 # With hold_fulfillment_policy = any, hold should be pikcup up reguardless of matching home or holding branch
759 $dbh->do("DELETE FROM circulation_rules");
760 Koha::CirculationRules->set_rules(
766 hold_fulfillment_policy => 'any',
771 # Home branch matches pickup branch
772 $reserve_id = AddReserve(
774 branchcode => $library_A,
775 borrowernumber => $borrowernumber,
776 biblionumber => $biblionumber,
781 C4::HoldsQueue::CreateQueue();
782 $holds_queue = $dbh->selectall_arrayref( "SELECT * FROM tmp_holdsqueue", { Slice => {} } );
783 is( @$holds_queue, 1, "Hold where pickup eq home, pickup ne holding targeted" );
784 Koha::Holds->find( $reserve_id )->cancel;
786 # Holding branch matches pickup branch
787 $reserve_id = AddReserve(
789 branchcode => $library_B,
790 borrowernumber => $borrowernumber,
791 biblionumber => $biblionumber,
796 C4::HoldsQueue::CreateQueue();
797 $holds_queue = $dbh->selectall_arrayref( "SELECT * FROM tmp_holdsqueue", { Slice => {} } );
798 is( @$holds_queue, 1, "Hold where pickup ne home, pickup eq holding targeted" );
799 Koha::Holds->find( $reserve_id )->cancel;
801 # Neither branch matches pickup branch
802 $reserve_id = AddReserve(
804 branchcode => $library_C,
805 borrowernumber => $borrowernumber,
806 biblionumber => $biblionumber,
811 C4::HoldsQueue::CreateQueue();
812 $holds_queue = $dbh->selectall_arrayref( "SELECT * FROM tmp_holdsqueue", { Slice => {} } );
813 is( @$holds_queue, 1, "Hold where pickup ne home, pickup ne holding targeted" );
814 Koha::Holds->find( $reserve_id )->cancel;
816 # End testing hold_fulfillment_policy
818 # Test hold itemtype limit
819 t::lib::Mocks::mock_preference( "UseTransportCostMatrix", 0 );
820 my $wrong_itemtype = $builder->build({ source => 'Itemtype', value => { notforloan => 0 } })->{itemtype};
821 my $right_itemtype = $builder->build({ source => 'Itemtype', value => { notforloan => 0 } })->{itemtype};
822 $borrowernumber = $borrower3->{borrowernumber};
823 my $branchcode = $library1->{branchcode};
824 $dbh->do("DELETE FROM reserves");
825 $dbh->do("DELETE FROM issues");
826 $dbh->do("DELETE FROM items");
827 $dbh->do("DELETE FROM biblio");
828 $dbh->do("DELETE FROM biblioitems");
829 $dbh->do("DELETE FROM transport_cost");
830 $dbh->do("DELETE FROM tmp_holdsqueue");
831 $dbh->do("DELETE FROM hold_fill_targets");
833 $dbh->do("INSERT INTO biblio (frameworkcode, author, title, datecreated) VALUES ('', 'Koha test', '$TITLE', '2011-02-01')");
835 $biblionumber = $dbh->selectrow_array("SELECT biblionumber FROM biblio WHERE title = '$TITLE'")
836 or BAIL_OUT("Cannot find newly created biblio record");
838 $dbh->do("INSERT INTO biblioitems (biblionumber, itemtype) VALUES ($biblionumber, '$itemtype')");
841 $dbh->selectrow_array("SELECT biblioitemnumber FROM biblioitems WHERE biblionumber = $biblionumber")
842 or BAIL_OUT("Cannot find newly created biblioitems record");
845 INSERT INTO items (biblionumber, biblioitemnumber, homebranch, holdingbranch, notforloan, damaged, itemlost, withdrawn, onloan, itype)
846 VALUES ($biblionumber, $biblioitemnumber, '$library_A', '$library_B', 0, 0, 0, 0, NULL, '$right_itemtype')
849 # With hold_fulfillment_policy = homebranch, hold should only be picked up if pickup branch = homebranch
850 $dbh->do("DELETE FROM circulation_rules");
851 Koha::CirculationRules->set_rules(
857 hold_fulfillment_policy => 'any',
862 # Home branch matches pickup branch
863 $reserve_id = AddReserve(
865 branchcode => $library_A,
866 borrowernumber => $borrowernumber,
867 biblionumber => $biblionumber,
869 itemtype => $wrong_itemtype,
873 C4::HoldsQueue::CreateQueue();
874 $holds_queue = $dbh->selectall_arrayref( "SELECT * FROM tmp_holdsqueue", { Slice => {} } );
875 is( @$holds_queue, 0, "Item with incorrect itemtype not targeted" );
876 Koha::Holds->find( $reserve_id )->cancel;
878 # Holding branch matches pickup branch
879 $reserve_id = AddReserve(
881 branchcode => $library_A,
882 borrowernumber => $borrowernumber,
883 biblionumber => $biblionumber,
885 itemtype => $right_itemtype,
889 C4::HoldsQueue::CreateQueue();
890 $holds_queue = $dbh->selectall_arrayref( "SELECT * FROM tmp_holdsqueue", { Slice => {} } );
891 is( @$holds_queue, 1, "Item with matching itemtype is targeted" );
892 Koha::Holds->find( $reserve_id )->cancel;
894 # Neither branch matches pickup branch
895 $reserve_id = AddReserve(
897 branchcode => $library_A,
898 borrowernumber => $borrowernumber,
899 biblionumber => $biblionumber,
904 C4::HoldsQueue::CreateQueue();
905 $holds_queue = $dbh->selectall_arrayref( "SELECT * FROM tmp_holdsqueue", { Slice => {} } );
906 is( @$holds_queue, 1, "Item targeted when hold itemtype is not set" );
907 Koha::Holds->find( $reserve_id )->cancel;
909 # End testing hold itemtype limit
912 subtest "Test Local Holds Priority - Bib level" => sub {
915 Koha::Biblios->delete();
916 t::lib::Mocks::mock_preference( 'LocalHoldsPriority', 1 );
917 t::lib::Mocks::mock_preference( 'LocalHoldsPriorityPatronControl', 'PickupLibrary' );
918 t::lib::Mocks::mock_preference( 'LocalHoldsPriorityItemControl', 'homebranch' );
919 my $branch = $builder->build_object( { class => 'Koha::Libraries' } );
920 my $branch2 = $builder->build_object( { class => 'Koha::Libraries' } );
921 my $local_patron = $builder->build_object(
923 class => "Koha::Patrons",
925 branchcode => $branch->branchcode
929 my $other_patron = $builder->build_object(
931 class => "Koha::Patrons",
933 branchcode => $branch2->branchcode
937 my $biblio = $builder->build_sample_biblio();
938 my $item = $builder->build_sample_item(
940 biblionumber => $biblio->biblionumber,
941 library => $branch->branchcode,
945 my $reserve_id = AddReserve(
947 branchcode => $branch2->branchcode,
948 borrowernumber => $other_patron->borrowernumber,
949 biblionumber => $biblio->biblionumber,
953 my $reserve_id2 = AddReserve(
955 branchcode => $item->homebranch,
956 borrowernumber => $local_patron->borrowernumber,
957 biblionumber => $biblio->biblionumber,
962 C4::HoldsQueue::CreateQueue();
964 my $queue_rs = $schema->resultset('TmpHoldsqueue');
965 my $target_rs = $schema->resultset('HoldFillTarget');
966 is( $queue_rs->count(), 1,
967 "Hold queue contains one hold" );
969 $queue_rs->next->borrowernumber,
970 $local_patron->borrowernumber,
971 "We should pick the local hold over the next available"
973 is( $target_rs->next->reserve_id, $reserve_id2, "Reserve id correctly set in hold fill target" );
976 subtest "Test Local Holds Priority - Item level" => sub {
979 Koha::Biblios->delete();
980 t::lib::Mocks::mock_preference( 'LocalHoldsPriority', 1 );
981 t::lib::Mocks::mock_preference( 'LocalHoldsPriorityPatronControl', 'PickupLibrary' );
982 t::lib::Mocks::mock_preference( 'LocalHoldsPriorityItemControl', 'homebranch' );
983 my $branch = $builder->build_object( { class => 'Koha::Libraries' } );
984 my $branch2 = $builder->build_object( { class => 'Koha::Libraries' } );
985 my $local_patron = $builder->build_object(
987 class => "Koha::Patrons",
989 branchcode => $branch->branchcode
993 my $other_patron = $builder->build_object(
995 class => "Koha::Patrons",
997 branchcode => $branch2->branchcode
1001 my $biblio = $builder->build_sample_biblio();
1002 my $item = $builder->build_sample_item(
1004 biblionumber => $biblio->biblionumber,
1005 library => $branch->branchcode,
1009 my $reserve_id = AddReserve(
1011 branchcode => $branch2->branchcode,
1012 borrowernumber => $other_patron->borrowernumber,
1013 biblionumber => $biblio->biblionumber,
1015 itemnumber => $item->id,
1018 my $reserve_id2 = AddReserve(
1020 branchcode => $item->homebranch,
1021 borrowernumber => $local_patron->borrowernumber,
1022 biblionumber => $biblio->biblionumber,
1024 itemnumber => $item->id,
1028 C4::HoldsQueue::CreateQueue();
1030 my $queue_rs = $schema->resultset('TmpHoldsqueue');
1031 my $q = $queue_rs->next;
1032 is( $queue_rs->count(), 1,
1033 "Hold queue contains one hold" );
1036 $local_patron->borrowernumber,
1037 "We should pick the local hold over the next available"
1041 subtest "Test Local Holds Priority - Item level hold over Record level hold (Bug 23934)" => sub {
1044 Koha::Biblios->delete();
1045 t::lib::Mocks::mock_preference( 'LocalHoldsPriority', 1 );
1046 t::lib::Mocks::mock_preference( 'LocalHoldsPriorityPatronControl', 'PickupLibrary' );
1047 t::lib::Mocks::mock_preference( 'LocalHoldsPriorityItemControl', 'homebranch' );
1048 my $branch = $builder->build_object( { class => 'Koha::Libraries' } );
1049 my $branch2 = $builder->build_object( { class => 'Koha::Libraries' } );
1050 my $local_patron = $builder->build_object(
1052 class => "Koha::Patrons",
1054 branchcode => $branch->branchcode
1058 my $other_patron = $builder->build_object(
1060 class => "Koha::Patrons",
1062 branchcode => $branch2->branchcode
1066 my $biblio = $builder->build_sample_biblio();
1067 my $item = $builder->build_sample_item(
1069 biblionumber => $biblio->biblionumber,
1070 library => $branch->branchcode,
1074 my $reserve_id = AddReserve(
1076 branchcode => $branch2->branchcode,
1077 borrowernumber => $other_patron->borrowernumber,
1078 biblionumber => $biblio->biblionumber,
1082 my $reserve_id2 = AddReserve(
1084 branchcode => $item->homebranch,
1085 borrowernumber => $local_patron->borrowernumber,
1086 biblionumber => $biblio->biblionumber,
1088 itemnumber => $item->id,
1092 C4::HoldsQueue::CreateQueue();
1094 my $queue_rs = $schema->resultset('TmpHoldsqueue');
1095 my $q = $queue_rs->next;
1096 is( $queue_rs->count(), 1,
1097 "Hold queue contains one hold" );
1100 $local_patron->borrowernumber,
1101 "We should pick the local hold over the next available"
1105 subtest "Test Local Holds Priority - Get correct item for item level hold" => sub {
1108 Koha::Biblios->delete();
1109 t::lib::Mocks::mock_preference( 'LocalHoldsPriority', 1 );
1110 t::lib::Mocks::mock_preference( 'LocalHoldsPriorityPatronControl', 'PickupLibrary' );
1111 t::lib::Mocks::mock_preference( 'LocalHoldsPriorityItemControl', 'homebranch' );
1112 my $branch = $builder->build_object( { class => 'Koha::Libraries' } );
1113 my $branch2 = $builder->build_object( { class => 'Koha::Libraries' } );
1114 my $local_patron = $builder->build_object(
1116 class => "Koha::Patrons",
1118 branchcode => $branch->branchcode
1122 my $other_patron = $builder->build_object(
1124 class => "Koha::Patrons",
1126 branchcode => $branch2->branchcode
1130 my $biblio = $builder->build_sample_biblio();
1132 my $item1 = $builder->build_sample_item(
1134 biblionumber => $biblio->biblionumber,
1135 library => $branch->branchcode,
1138 my $item2 = $builder->build_sample_item(
1140 biblionumber => $biblio->biblionumber,
1141 library => $branch->branchcode,
1144 my $item3 = $builder->build_sample_item(
1146 biblionumber => $biblio->biblionumber,
1147 library => $branch->branchcode,
1154 branchcode => $item2->homebranch,
1155 borrowernumber => $local_patron->borrowernumber,
1156 biblionumber => $biblio->biblionumber,
1158 itemnumber => $item2->id,
1163 C4::HoldsQueue::CreateQueue();
1165 my $queue_rs = $schema->resultset('TmpHoldsqueue');
1166 my $q = $queue_rs->next;
1167 is( $queue_rs->count(), 1,
1168 "Hold queue contains one hold" );
1171 $local_patron->borrowernumber,
1172 "We should pick the local hold over the next available"
1174 is( $q->itemnumber->id, $item2->id, "Got the correct item for item level local holds priority" );
1177 subtest "Test Local Holds Priority - Ensure no duplicate requests in holds queue (Bug 18001)" => sub {
1180 $dbh->do("DELETE FROM tmp_holdsqueue");
1181 $dbh->do("DELETE FROM hold_fill_targets");
1182 $dbh->do("DELETE FROM reserves");
1183 $dbh->do("DELETE FROM circulation_rules");
1184 Koha::Biblios->delete();
1186 t::lib::Mocks::mock_preference( 'LocalHoldsPriority', 1 );
1187 t::lib::Mocks::mock_preference( 'LocalHoldsPriorityPatronControl', 'PickupLibrary' );
1188 t::lib::Mocks::mock_preference( 'LocalHoldsPriorityItemControl', 'homebranch' );
1189 my $branch = $builder->build_object( { class => 'Koha::Libraries' } );
1190 my $branch2 = $builder->build_object( { class => 'Koha::Libraries' } );
1191 my $patron = $builder->build_object(
1193 class => "Koha::Patrons",
1195 branchcode => $branch->branchcode
1199 my $biblio = $builder->build_sample_biblio();
1200 my $item1 = $builder->build_sample_item(
1202 biblionumber => $biblio->biblionumber,
1203 library => $branch->branchcode,
1206 my $item2 = $builder->build_sample_item(
1208 biblionumber => $biblio->biblionumber,
1209 library => $branch->branchcode,
1213 my $item3 = $builder->build_sample_item(
1215 biblionumber => $biblio->biblionumber,
1216 library => $branch->branchcode,
1220 $reserve_id = AddReserve(
1222 branchcode => $item1->homebranch,
1223 borrowernumber => $patron->borrowernumber,
1224 biblionumber => $biblio->id,
1229 C4::HoldsQueue::CreateQueue();
1231 my $queue_rs = $schema->resultset('TmpHoldsqueue');
1233 is( $queue_rs->count(), 1,
1234 "Hold queue contains one hold from chosen from three possible items" );
1238 subtest "Item level holds info is preserved (Bug 25738)" => sub {
1242 $dbh->do("DELETE FROM tmp_holdsqueue");
1243 $dbh->do("DELETE FROM hold_fill_targets");
1244 $dbh->do("DELETE FROM reserves");
1245 $dbh->do("DELETE FROM circulation_rules");
1247 my $library = $builder->build_object({ class => 'Koha::Libraries' });
1248 my $patron_1 = $builder->build_object(
1250 class => "Koha::Patrons",
1252 branchcode => $library->branchcode
1257 my $patron_2 = $builder->build_object(
1259 class => "Koha::Patrons",
1261 branchcode => $library->branchcode
1266 my $biblio = $builder->build_sample_biblio();
1267 my $item_1 = $builder->build_sample_item(
1269 biblionumber => $biblio->biblionumber,
1270 library => $library->branchcode,
1273 my $item_2 = $builder->build_sample_item(
1275 biblionumber => $biblio->biblionumber,
1276 library => $library->branchcode,
1280 # Add item-level hold for patron_1
1281 my $reserve_id_1 = AddReserve(
1283 branchcode => $library->branchcode,
1284 borrowernumber => $patron_1->borrowernumber,
1285 biblionumber => $biblio->id,
1286 itemnumber => $item_1->itemnumber,
1291 my $reserve_id_2 = AddReserve(
1293 branchcode => $library->branchcode,
1294 borrowernumber => $patron_2->borrowernumber,
1295 biblionumber => $biblio->id,
1300 C4::HoldsQueue::CreateQueue();
1302 my $queue_rs = $schema->resultset('TmpHoldsqueue');
1304 is( $queue_rs->count(), 2, "Hold queue contains two holds" );
1306 my $queue_line_1 = $queue_rs->next;
1307 is( $queue_line_1->item_level_request, 1, 'Request is correctly advertised as item-level' );
1308 my $target_rs = $schema->resultset('HoldFillTarget')->search({borrowernumber=>$patron_1->borrowernumber});;
1309 is( $target_rs->next->reserve_id, $reserve_id_1, "Reserve id correctly set in hold fill target for item level hold" );
1311 my $queue_line_2 = $queue_rs->next;
1312 is( $queue_line_2->item_level_request, 0, 'Request is correctly advertised as biblio-level' );
1316 subtest 'Trivial test for UpdateTransportCostMatrix' => sub {
1319 { frombranch => $library1->{branchcode}, tobranch => $library2->{branchcode}, cost => 1, disable_transfer => 0 },
1320 { frombranch => $library2->{branchcode}, tobranch => $library3->{branchcode}, cost => 0, disable_transfer => 1 },
1322 C4::HoldsQueue::UpdateTransportCostMatrix( $recs );
1323 is( $schema->resultset('TransportCost')->count, 2, 'UpdateTransportCostMatrix added two records' );
1327 $schema->storage->txn_rollback;
1329 ### END Test holds queue builder does not violate holds policy ###
1332 my ($test_name, $use_cost_matrix, $pick_branch, $hold_branch) = @_;
1334 $test_name = "$test_name (".($use_cost_matrix ? "" : "don't ")."use cost matrix)";
1336 $use_cost_matrix_sth->execute($use_cost_matrix);
1337 C4::Context->clear_syspref_cache();
1338 C4::HoldsQueue::CreateQueue();
1340 my $results = $dbh->selectall_arrayref($test_sth, { Slice => {} }); # should be only one
1341 my $r = $results->[0];
1343 my $ok = is( $r->{pickbranch}, $pick_branch, "$test_name pick up branch");
1344 $ok &&= is( $r->{holdingbranch}, $hold_branch, "$test_name holding branch")
1347 diag( "Wrong pick-up/hold for first target (pick_branch, hold_branch, reserves, hold_fill_targets, tmp_holdsqueue): "
1348 . Dumper ($pick_branch, $hold_branch, map dump_records($_), qw(reserves hold_fill_targets tmp_holdsqueue)) )
1351 # Test enforcement of branch transfer limit
1352 if ( $r->{pickbranch} ne $r->{holdingbranch} ) {
1353 t::lib::Mocks::mock_preference( 'UseBranchTransferLimits', '1' );
1354 my $limit = Koha::Item::Transfer::Limit->new(
1356 toBranch => $r->{pickbranch},
1357 fromBranch => $r->{holdingbranch},
1358 itemtype => $r->{itype},
1361 C4::Context->clear_syspref_cache();
1362 C4::HoldsQueue::CreateQueue();
1363 $results = $dbh->selectall_arrayref( $test_sth, { Slice => {} } )
1364 ; # should be only one
1365 my $s = $results->[0];
1366 isnt( $r->{holdingbranch}, $s->{holdingbranch}, 'Hold is not trapped for pickup at a branch that cannot be transferred to');
1369 t::lib::Mocks::mock_preference( 'UseBranchTransferLimits', '0' );
1370 C4::Context->clear_syspref_cache();
1371 C4::HoldsQueue::CreateQueue();
1377 my ($tablename) = @_;
1378 return $dbh->selectall_arrayref("SELECT * from $tablename where borrowernumber = ?", { Slice => {} }, $borrowernumber);