Bug 41959 - Holds queue builder doesn't always check all holds when using transport cost matrix
Summary: Holds queue builder doesn't always check all holds when using transport cost ...
Status: NEW
Alias: None
Product: Koha
Classification: Unclassified
Component: Hold requests (show other bugs)
Version: Main
Hardware: All All
: P5 - low major
Assignee: Bugs List
QA Contact: Testopia
URL:
Keywords:
Depends on: 35826
Blocks:
  Show dependency treegraph
 
Reported: 2026-02-28 18:48 UTC by Nick Clemens (kidclamp)
Modified: 2026-02-28 18:49 UTC (History)
3 users (show)

See Also:
GIT URL:
Initiative type: ---
Sponsorship status: ---
Comma delimited list of Sponsors:
Crowdfunding goal: 0
Patch complexity: ---
Documentation contact:
Documentation submission:
Text to go in the release notes:
Version(s) released in:
Circulation function:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Clemens (kidclamp) 2026-02-28 18:48:52 UTC
The scenario presented itself under a specific circumstance

Library A ordered a copy of a book and left in 'on order' status
Library B purchased a copy and made it available

Each library can only fill holds on their own items
The transport cost matrix only allows items to transfer to their own branch
The transfer limits only allows items to transfer to their own branch

A patron of Library A places a title level hold, it can't fill because library A's item is unavailable (on order)

A patron of Library B places a title level hold, it should be queued for library B's item

In C4::HoldsQueue::MapItemsToHoldRequests we call _allocateWithTransportCostMatrix

In _allocateWithTranportCostMatrix we have this code:
    if ( $num_tasks > $num_agents ) {
        @remaining = @requests[ $num_agents .. $num_tasks - 1 ];
        @requests  = @requests[ 0 .. $num_agents - 1 ];
        $num_tasks = $num_agents;
    }

task = requests and agents = items

In our scenario - 2 tasks/requests and 1 item/agent

The code above drops the second request, and sets tasks to 1

We then loop tasks and agents:
        for ( my $i = 0 ; $i < $num_agents ; $i++ ) {
            for ( my $j = $r ; $j < $num_tasks ; $j++ ) {

But since we have dcereased things above, we only check the first task/request - the second hold, which should be filled, is never checked