# Look for a NeedBeforeDate to set the expiration.
my $expiration = $request->{$message}->{NeedBeforeDate};
+ # Check for eligible copies:
+ if ($self->count_eligible_copies($bre, $user, $pickup_ou, $selection_ou) == 0) {
+ $response->problem(
+ NCIP::Problem->new(
+ {
+ ProblemType => 'Item Not Available By Need Before Date',
+ ProblemDetail => 'Item requested will not be available by the date/time the User needs the Item',
+ ProblemElement => 'BibliographicRecordIdentifier',
+ ProblemValue => $bre->id()
+ }
+ )
+ );
+ return $response;
+ }
+
# Place the hold:
my $hold = $self->place_hold($bre, $user, $pickup_ou, $expiration, $selection_ou);
if (ref($hold) eq 'NCIP::Problem') {
return $hold;
}
+=head2 count_eligible_copies
+
+ $result = $ils->count_eligible_copies($target, $patron, $pickup_lib, $selection_lib);
+
+This method counts the copies eligible to fill the remote hold on the
+target bre for the patron at pickup lib where the copies are owned at
+or below the selection lib. It returns the count of copies eligible
+to fill the hold at the time of the call, so zero if none are
+available or a positive integer otherwise.
+
+=cut
+
+sub count_eligible_copies {
+ my $self = shift;
+ my $target = shift;
+ my $user = shift;
+ my $pickup_lib = shift;
+ my $selection_lib = shift;
+
+ $pickup_lib = $user->home_ou() unless ($pickup_lib);
+
+ # To be used in the pcrud query:
+ my $selection_ou = (ref($selection_lib)) ? $selection_lib->id() : 1;
+
+ # Base params for hold is possible check:
+ my $params = {
+ hold_type => 'C',
+ patronid => $user->id(),
+ pickup_lib => $pickup_lib->id()
+ };
+
+ # return value: count of eligible copies found.
+ my $eligible_copies = 0;
+
+ # pcrud query to find eligible copies:
+ my $query = {deleted => 'f', circulate => 't', holdable => 't', status => [0,7]};
+ # Limit copies by call numbers for the target bre:
+ $query->{call_number} = {
+ 'in' => {
+ select => {acn => ['id']},
+ from => 'acn',
+ where => {
+ record => $target->id(),
+ deleted => 'f',
+ owning_lib => {
+ 'in' => {
+ select => {
+ aou => [{
+ transform => 'actor.org_unit_descendants',
+ column => 'id',
+ result_field => 'id'
+ }]
+ },
+ from => 'aou',
+ where => {id => $selection_ou}
+ }
+ }
+ }
+ }
+ };
+ # Limit copies by circ_lib:
+ $query->{circ_lib} = {
+ 'in' => {
+ select => {
+ aou => [{
+ column => 'id',
+ transform => 'actor.org_unit_descendants',
+ result_field => 'id'
+ }]
+ },
+ from => 'aou',
+ where => {id => $selection_ou}
+ }
+ };
+ # Limit copies by copy locations that allow circ and holds:
+ $query->{location} = {
+ 'in' => {
+ select => { acpl => ['id'] },
+ from => 'acpl',
+ where => {holdable => 't', circulate => 't'}
+ }
+ };
+ # Search for the copies and check each one to see if it could fill the hold.
+ my $search = OpenSRF::AppSession->create('open-ils.pcrud')->request(
+ 'open-ils.pcrud.search.acp',
+ $self->{session}->{authtoken},
+ $query
+ );
+ while (my $response = $search->recv()) {
+ if ($response->status() eq 'OK') {
+ my $copy = $response->content();
+ $params->{copy_id} = $copy->id();
+ my $result = $U->simplereq(
+ 'open-ils.circ',
+ 'open-ils.circ.title_hold.is_possible',
+ $self->{session}->{authtoken},
+ $params
+ );
+ if ($result->{success}) {
+ $eligible_copies++;
+ }
+ }
+ }
+ $search->finish();
+
+ return $eligible_copies;
+}
+
=head2 cancel_hold
$result = $ils->cancel_hold($hold);