# figure out which item-level requests can be filled
my $num_items_remaining = scalar(@$available_items);
+
+ # Look for Local Holds Priority matches first
+ if ( C4::Context->preference('LocalHoldsPriority') ) {
+ my $LocalHoldsPriorityPatronControl =
+ C4::Context->preference('LocalHoldsPriorityPatronControl');
+ my $LocalHoldsPriorityItemControl =
+ C4::Context->preference('LocalHoldsPriorityItemControl');
+
+ foreach my $request (@$hold_requests) {
+ last if $num_items_remaining == 0;
+
+ my $local_hold_match;
+ foreach my $item (@$available_items) {
+ next
+ if ( !$item->{holdallowed} )
+ || ( $item->{holdallowed} == 1
+ && $item->{homebranch} ne $request->{borrowerbranch} );
+
+ my $local_holds_priority_item_branchcode =
+ $item->{$LocalHoldsPriorityItemControl};
+
+ my $local_holds_priority_patron_branchcode =
+ ( $LocalHoldsPriorityPatronControl eq 'PickupLibrary' )
+ ? $request->{branchcode}
+ : ( $LocalHoldsPriorityPatronControl eq 'HomeLibrary' )
+ ? $request->{borrowerbranch}
+ : undef;
+
+ $local_hold_match =
+ $local_holds_priority_item_branchcode eq
+ $local_holds_priority_patron_branchcode;
+
+ if ($local_hold_match) {
+ if ( exists $items_by_itemnumber{ $item->{itemnumber} }
+ and not exists $allocated_items{ $item->{itemnumber} } )
+ {
+ $item_map{ $item->{itemnumber} } = {
+ borrowernumber => $request->{borrowernumber},
+ biblionumber => $request->{biblionumber},
+ holdingbranch => $item->{holdingbranch},
+ pickup_branch => $request->{branchcode}
+ || $request->{borrowerbranch},
+ item_level => 0,
+ reservedate => $request->{reservedate},
+ reservenotes => $request->{reservenotes},
+ };
+ $allocated_items{ $item->{itemnumber} }++;
+ $num_items_remaining--;
+ }
+ }
+ }
+ }
+ }
+
foreach my $request (@$hold_requests) {
last if $num_items_remaining == 0;
use Modern::Perl;
-use Test::More tests => 38;
+use Test::More tests => 42;
use Data::Dumper;
use C4::Calendar;
#Set up the stage
# Sysprefs and cost matrix
C4::Context->set_preference('HoldsQueueSkipClosed', 0);
+C4::Context->set_preference('LocalHoldsPriority', 0);
$dbh->do("UPDATE systempreferences SET value = ? WHERE variable = 'StaticHoldsQueueWeight'", undef,
join( ',', @other_branches, $borrower_branchcode, $least_cost_branch_code));
$dbh->do("UPDATE systempreferences SET value = '0' WHERE variable = 'RandomizeHoldsQueueWeight'");
is( scalar( @$holds_queue ), 2, "Holds not filled with items from closed libraries" );
C4::Context->set_preference( 'HoldsQueueSkipClosed', 0 );
+## Test LocalHoldsPriority
+C4::Context->set_preference('LocalHoldsPriority', 1);
+
+$dbh->do("DELETE FROM default_circ_rules");
+$dbh->do("INSERT INTO default_circ_rules ( holdallowed ) VALUES ( 2 )");
+$dbh->do("DELETE FROM issues");
+
+# Test homebranch = patron branch
+C4::Context->set_preference('LocalHoldsPriorityPatronControl', 'HomeLibrary');
+C4::Context->set_preference('LocalHoldsPriorityItemControl', 'homebranch');
+C4::Context->clear_syspref_cache();
+$dbh->do("DELETE FROM reserves");
+$sth->execute( $borrower1->{borrowernumber}, $biblionumber, $branchcodes[0], 1 );
+$sth->execute( $borrower2->{borrowernumber}, $biblionumber, $branchcodes[0], 2 );
+$sth->execute( $borrower3->{borrowernumber}, $biblionumber, $branchcodes[0], 3 );
+
+$dbh->do("DELETE FROM items");
+# barcode, homebranch, holdingbranch, itemtype
+$items_insert_sth->execute( $barcode + 4, $branchcodes[2], $branchcodes[0] );
+
+C4::HoldsQueue::CreateQueue();
+$holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
+is( $holds_queue->[0]->{cardnumber}, $borrower3->{cardnumber}, "Holds queue giving priority to patron who's home library matches item's home library");
+
+# Test holdingbranch = patron branch
+C4::Context->set_preference('LocalHoldsPriorityPatronControl', 'HomeLibrary');
+C4::Context->set_preference('LocalHoldsPriorityItemControl', 'holdingbranch');
+C4::Context->clear_syspref_cache();
+$dbh->do("DELETE FROM reserves");
+$sth->execute( $borrower1->{borrowernumber}, $biblionumber, $branchcodes[0], 1 );
+$sth->execute( $borrower2->{borrowernumber}, $biblionumber, $branchcodes[0], 2 );
+$sth->execute( $borrower3->{borrowernumber}, $biblionumber, $branchcodes[0], 3 );
+
+$dbh->do("DELETE FROM items");
+# barcode, homebranch, holdingbranch, itemtype
+$items_insert_sth->execute( $barcode + 4, $branchcodes[0], $branchcodes[2] );
+
+C4::HoldsQueue::CreateQueue();
+$holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
+is( $holds_queue->[0]->{cardnumber}, $borrower3->{cardnumber}, "Holds queue giving priority to patron who's home library matches item's holding library");
+
+# Test holdingbranch = pickup branch
+C4::Context->set_preference('LocalHoldsPriorityPatronControl', 'PickupLibrary');
+C4::Context->set_preference('LocalHoldsPriorityItemControl', 'holdingbranch');
+C4::Context->clear_syspref_cache();
+$dbh->do("DELETE FROM reserves");
+$sth->execute( $borrower1->{borrowernumber}, $biblionumber, $branchcodes[0], 1 );
+$sth->execute( $borrower2->{borrowernumber}, $biblionumber, $branchcodes[0], 2 );
+$sth->execute( $borrower3->{borrowernumber}, $biblionumber, $branchcodes[2], 3 );
+
+$dbh->do("DELETE FROM items");
+# barcode, homebranch, holdingbranch, itemtype
+$items_insert_sth->execute( $barcode + 4, $branchcodes[0], $branchcodes[2] );
+
+C4::HoldsQueue::CreateQueue();
+$holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
+is( $holds_queue->[0]->{cardnumber}, $borrower3->{cardnumber}, "Holds queue giving priority to patron who's home library matches item's holding library");
+
+# Test homebranch = pickup branch
+C4::Context->set_preference('LocalHoldsPriorityPatronControl', 'PickupLibrary');
+C4::Context->set_preference('LocalHoldsPriorityItemControl', 'homebranch');
+C4::Context->clear_syspref_cache();
+$dbh->do("DELETE FROM reserves");
+$sth->execute( $borrower1->{borrowernumber}, $biblionumber, $branchcodes[0], 1 );
+$sth->execute( $borrower2->{borrowernumber}, $biblionumber, $branchcodes[0], 2 );
+$sth->execute( $borrower3->{borrowernumber}, $biblionumber, $branchcodes[2], 3 );
+
+$dbh->do("DELETE FROM items");
+# barcode, homebranch, holdingbranch, itemtype
+$items_insert_sth->execute( $barcode + 4, $branchcodes[2], $branchcodes[0] );
+
+C4::HoldsQueue::CreateQueue();
+$holds_queue = $dbh->selectall_arrayref("SELECT * FROM tmp_holdsqueue", { Slice => {} });
+is( $holds_queue->[0]->{cardnumber}, $borrower3->{cardnumber}, "Holds queue giving priority to patron who's home library matches item's holding library");
+
+C4::Context->set_preference('LocalHoldsPriority', 0);
+## End testing of LocalHoldsPriority
+
+
# Bug 14297
$itemtype = $builder->build({ source => 'Itemtype', value => { notforloan => 0 } })->{itemtype};
$borrowernumber = $borrower3->{borrowernumber};