X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FHoldsQueue.pm;h=8173efaae81f0eabf68ef5a86f54da8505f7a716;hb=eded6edacc5e3bf8dd0be21ed05842c3b78aadce;hp=b4d2b026f28bfbf9d40869b7d04bbdd390878434;hpb=ba23348db60fdf026723deef6e2907f6fc8093e6;p=koha-ffzg.git diff --git a/C4/HoldsQueue.pm b/C4/HoldsQueue.pm index b4d2b026f2..8173efaae8 100644 --- a/C4/HoldsQueue.pm +++ b/C4/HoldsQueue.pm @@ -23,8 +23,7 @@ use strict; use warnings; use C4::Context; -use C4::Search; -use C4::Circulation qw( GetTransfers GetBranchItemRule ); +use C4::Circulation qw( GetBranchItemRule ); use Koha::DateUtils qw( dt_from_string ); use Koha::Items; use Koha::Patrons; @@ -44,6 +43,8 @@ BEGIN { TransportCostMatrix UpdateTransportCostMatrix GetPendingHoldRequestsForBib + load_branches_to_pull_from + update_queue_for_biblio ); } @@ -114,14 +115,14 @@ sub UpdateTransportCostMatrix { =head2 GetHoldsQueueItems - GetHoldsQueueItems($branch); + GetHoldsQueueItems({ branchlimit => $branch, itemtypeslimit => $itype, ccodeslimit => $ccode, locationslimit => $location ); Returns hold queue for a holding branch. If branch is omitted, then whole queue is returned =cut sub GetHoldsQueueItems { - my ($branchlimit) = @_; + my $params = shift; my $dbh = C4::Context->dbh; my @bind_params = (); @@ -135,10 +136,23 @@ sub GetHoldsQueueItems { JOIN biblio USING (biblionumber) LEFT JOIN biblioitems USING (biblionumber) LEFT JOIN items USING ( itemnumber) + WHERE 1=1 /; - if ($branchlimit) { - $query .=" WHERE tmp_holdsqueue.holdingbranch = ?"; - push @bind_params, $branchlimit; + if ($params->{branchlimit}) { + $query .="AND tmp_holdsqueue.holdingbranch = ? "; + push @bind_params, $params->{branchlimit}; + } + if( $params->{itemtypeslimit} ) { + $query .=" AND items.itype = ? "; + push @bind_params, $params->{itemtypeslimit}; + } + if( $params->{ccodeslimit} ) { + $query .=" AND items.ccode = ? "; + push @bind_params, $params->{ccodeslimit}; + } + if( $params->{locationslimit} ) { + $query .=" AND items.location = ? "; + push @bind_params, $params->{locationslimit}; } $query .= " ORDER BY ccode, location, cn_sort, author, title, pickbranch, reservedate"; my $sth = $dbh->prepare($query); @@ -191,27 +205,19 @@ sub CreateQueue { my $bibs_with_pending_requests = GetBibsWithPendingHoldRequests(); foreach my $biblionumber (@$bibs_with_pending_requests) { + $total_bibs++; - my $hold_requests = GetPendingHoldRequestsForBib($biblionumber); - my $available_items = GetItemsAvailableToFillHoldRequestsForBib($biblionumber, $branches_to_use); - $total_requests += scalar(@$hold_requests); - $total_available_items += scalar(@$available_items); - my $item_map = MapItemsToHoldRequests($hold_requests, $available_items, $branches_to_use, $transport_cost_matrix); - $item_map or next; - my $item_map_size = scalar(keys %$item_map) - or next; + my $result = update_queue_for_biblio( + { biblio_id => $biblionumber, + branches_to_use => $branches_to_use, + transport_cost_matrix => $transport_cost_matrix, + } + ); - $num_items_mapped += $item_map_size; - CreatePicklistFromItemMap($item_map); - AddToHoldTargetMap($item_map); - if (($item_map_size < scalar(@$hold_requests )) and - ($item_map_size < scalar(@$available_items))) { - # DOUBLE CHECK, but this is probably OK - unfilled item-level requests - # FIXME - #warn "unfilled requests for $biblionumber"; - #warn Dumper($hold_requests), Dumper($available_items), Dumper($item_map); - } + $total_requests += $result->{requests}; + $total_available_items += $result->{available_items}; + $num_items_mapped += $result->{mapped_items}; } } @@ -308,7 +314,7 @@ sub GetItemsAvailableToFillHoldRequestsForBib { my ($biblionumber, $branches_to_use) = @_; my $dbh = C4::Context->dbh; - my $items_query = "SELECT itemnumber, homebranch, holdingbranch, itemtypes.itemtype AS itype + my $items_query = "SELECT items.itemnumber, homebranch, holdingbranch, itemtypes.itemtype AS itype FROM items "; if (C4::Context->preference('item-level_itypes')) { @@ -317,14 +323,17 @@ sub GetItemsAvailableToFillHoldRequestsForBib { $items_query .= "JOIN biblioitems USING (biblioitemnumber) LEFT JOIN itemtypes USING (itemtype) "; } - $items_query .= "WHERE items.notforloan = 0 + $items_query .= " LEFT JOIN branchtransfers ON (items.itemnumber = branchtransfers.itemnumber)"; + $items_query .= " WHERE items.notforloan = 0 AND holdingbranch IS NOT NULL AND itemlost = 0 AND withdrawn = 0"; + $items_query .= " AND branchtransfers.datearrived IS NULL + AND branchtransfers.datecancelled IS NULL"; $items_query .= " AND damaged = 0" unless C4::Context->preference('AllowHoldsOnDamagedItems'); $items_query .= " AND items.onloan IS NULL AND (itemtypes.notforloan IS NULL OR itemtypes.notforloan = 0) - AND itemnumber NOT IN ( + AND items.itemnumber NOT IN ( SELECT itemnumber FROM reserves WHERE biblionumber = ? @@ -342,12 +351,11 @@ sub GetItemsAvailableToFillHoldRequestsForBib { $sth->execute(@params); my $itm = $sth->fetchall_arrayref({}); - my @items = grep { ! scalar GetTransfers($_->{itemnumber}) } @$itm; return [ grep { - my $rule = GetBranchItemRule($_->{homebranch}, $_->{itype}); + my $rule = C4::Circulation::GetBranchItemRule($_->{homebranch}, $_->{itype}); $_->{holdallowed} = $rule->{holdallowed}; $_->{hold_fulfillment_policy} = $rule->{hold_fulfillment_policy}; - } @items ]; + } @{$itm} ]; } =head2 _checkHoldPolicy @@ -416,7 +424,7 @@ sub MapItemsToHoldRequests { map { $_->{_object} = Koha::Items->find( $_->{itemnumber} ) } @$available_items; my $libraries = {}; - map { $libraries->{$_->id} = $_ } Koha::Libraries->search(); + map { $libraries->{$_->id} = $_ } Koha::Libraries->search->as_list; # group available items by itemnumber my %items_by_itemnumber = map { $_->{itemnumber} => $_ } @$available_items; @@ -842,5 +850,90 @@ sub least_cost_branch { # return $branch[0] if @branch == 1; } +=head3 update_queue_for_biblio + + my $result = update_queue_for_biblio( + { + biblio_id => $biblio_id, + [ branches_to_use => $branches_to_use, + transport_cost_matrix => $transport_cost_matrix, + delete => $delete, ] + } + ); + +Given a I, this method calculates and sets the holds queue entries +for the biblio's holds, and the hold fill targets (items). + +=head4 Return value + +It return a hashref containing: + +=over + +=item I: the pending holds count for the biblio. + +=item I the count of items that are available to fill holds for the biblio. + +=item I the total items that got mapped. + +=back + +=head4 Optional parameters + +=over + +=item I a list of branchcodes to be used to restrict which items can be used. + +=item I is the output of C. + +=item I tells the method to delete prior entries on the related tables for the biblio_id. + +=back + +Note: All the optional parameters will be calculated in the method if omitted. They +are allowed to be passed to avoid calculating them many times inside loops. + +=cut + +sub update_queue_for_biblio { + my ($args) = @_; + + my $biblio_id = $args->{biblio_id}; + + my $branches_to_use = $args->{branches_to_use} // load_branches_to_pull_from( C4::Context->preference('UseTransportCostMatrix') ); + my $transport_cost_matrix; + + if ( !exists $args->{transport_cost_matrix} + && C4::Context->preference('UseTransportCostMatrix') ) { + $transport_cost_matrix = TransportCostMatrix(); + } else { + $transport_cost_matrix = $args->{transport_cost_matrix}; + } + + if ( $args->{delete} ) { + my $dbh = C4::Context->dbh; + + $dbh->do("DELETE FROM tmp_holdsqueue WHERE biblionumber=$biblio_id"); + $dbh->do("DELETE FROM hold_fill_targets WHERE biblionumber=$biblio_id"); + } + + my $hold_requests = GetPendingHoldRequestsForBib($biblio_id); + my $available_items = GetItemsAvailableToFillHoldRequestsForBib( $biblio_id, $branches_to_use ); + + my $result = { + requests => scalar( @{$hold_requests} ), + available_items => scalar( @{$available_items} ), + }; + + my $item_map = MapItemsToHoldRequests( $hold_requests, $available_items, $branches_to_use, $transport_cost_matrix ); + $result->{mapped_items} = scalar( keys %{$item_map} ); + + if ($item_map) { + CreatePicklistFromItemMap($item_map); + AddToHoldTargetMap($item_map); + } + + return $result; +} 1;