</desc>
</event>
- <event code='1503' textcode='TRANSIT_NOT_FOUND'>
+ <event code='1504' textcode='TRANSIT_NOT_FOUND'>
<desc>
Someone attempted to retrieve a transit object from the
system and the object was not found.
</desc>
</event>
- <event code='1503' textcode='BILLING_NOT_FOUND'>
+ <event code='1505' textcode='BILLING_NOT_FOUND'>
<desc>
Someone attempted to retrieve a transit object from the
system and the object was not found.
</desc>
</event>
- <event code='1504' textcode='CONTAINER_NOT_FOUND'>
+ <event code='1506' textcode='CONTAINER_NOT_FOUND'>
<desc>
Someone attempted to retrieve a container object from the
system and the object was not found.
</desc>
</event>
- <event code='1505' textcode='CONTAINER_ITEM_NOT_FOUND'>
+ <event code='1507' textcode='CONTAINER_ITEM_NOT_FOUND'>
<desc>
Someone attempted to retrieve a container item object from the
system and the object was not found.
</desc>
</event>
- <event code='1506' textcode='VOLUME_NOT_FOUND'>
+ <event code='1508' textcode='VOLUME_NOT_FOUND'>
<desc>
Someone attempted to retrieve a volume object from the
system and the object was not found.
</desc>
</event>
- <event code='1507' textcode='ORG_UNIT_NOT_FOUND'>
+ <event code='1509' textcode='ORG_UNIT_NOT_FOUND'>
<desc>
Someone attempted to retrieve an org unit object from the
system and the object was not found.
</desc>
</event>
- <event code='1508' textcode='STAT_CAT_NOT_FOUND'>
+ <event code='1510' textcode='STAT_CAT_NOT_FOUND'>
<desc> Stat cat object does not exist </desc>
</event>
- <event code='1509' textcode='STAT_CAT_ENTRY_NOT_FOUND'>
+ <event code='1511' textcode='STAT_CAT_ENTRY_NOT_FOUND'>
<desc> Stat cat entry object does not exist </desc>
</event>
- <event code='1510' textcode='STAT_CAT_ENTRY_MAP_NOT_FOUND'>
+ <event code='1512' textcode='STAT_CAT_ENTRY_MAP_NOT_FOUND'>
<desc> Stat cat entry map object does not exist </desc>
</event>
- <event code='1511' textcode='NON_CAT_TYPE_NOT_FOUND'>
+ <event code='1513' textcode='NON_CAT_TYPE_NOT_FOUND'>
<desc> The non cataloged type object does not exist </desc>
</event>
- <event code='1512' textcode='CIRC_DURATION_NOT_FOUND'>
+ <event code='1514' textcode='CIRC_DURATION_NOT_FOUND'>
<desc> The circ duration object does not exist </desc>
</event>
- <event code='1513' textcode='RECURRING_FINE_NOT_FOUND'>
+ <event code='1515' textcode='RECURRING_FINE_NOT_FOUND'>
<desc> The recurring fines object does not exist </desc>
</event>
- <event code='1514' textcode='MAX_FINE_NOT_FOUND'>
+ <event code='1516' textcode='MAX_FINE_NOT_FOUND'>
<desc> The max fines object does not exist </desc>
</event>
- <event code='1515' textcode='COPY_LOCATION_NOT_FOUND'>
+ <event code='1517' textcode='COPY_LOCATION_NOT_FOUND'>
<desc> The copy location object does not exist </desc>
</event>
+ <event code='1518' textcode='HOLD_TRANSIT_NOT_FOUND'>
+ <desc> The hold transit object does not exist </desc>
+ </event>
+
+
<event code='1700' textcode='NON_CAT_TYPE_EXISTS'>
<!-- ================================================================ -->
<!-- CIRC EVENTS -->
<event code='7000' textcode='ROUTE_ITEM'>
- <desc> A copy needs to be routed to a different location </desc>
+ <desc>
+ A copy needs to be routed to a different location
+ The destination location will be specified by an 'org' key
+ within the event object
+ </desc>
</event>
<event code='7001' textcode='PATRON_BAD_STANDING'>
<event code='7008' textcode='MAX_RENEWALS_REACHED'>
<desc> Circulation has no more renewals remaining </desc>
</event>
+
+ <event code='7009' textcode='ROUTE_TO_COPY_LOCATION'>
+ <desc>
+ A copy needs to be routed to a copy location. The location
+ should be specified within the event with a 'location' key
+ </desc>
+ </event>
+
<!-- ================================================================ -->
</ils_events>
my $cache_client = "OpenSRF::Utils::Cache";
+my $storage_session = undef;
+
# ---------------------------------------------------------------------------
# Pile of utilty methods used accross applications.
# ---------------------------------------------------------------------------
("Unable to Begin Transaction with database" );
}
$trans_req->finish();
+
+ $logger->debug("Setting global storage session to ".
+ "session: " . $session->session_id . " : " . $session->app );
+
+ $storage_session = $session;
return $session;
}
# returns the first failed perm on failure
sub check_user_perms {
my($self, $user_id, $org_id, @perm_types ) = @_;
-
$logger->debug("Checking perms with user : $user_id , org: $org_id, @perm_types");
-
- throw OpenSRF::EX::ERROR ("Invalid call to check_user_perms()")
- unless( defined($user_id) and defined($org_id) and @perm_types);
-
- my $session = OpenSRF::AppSession->create("open-ils.storage");
for my $type (@perm_types) {
- my $req = $session->request(
+ return $type unless ($self->storagereq(
"open-ils.storage.permission.user_has_perm",
- $user_id, $type, $org_id );
- my $resp = $req->gather(1);
- if(!$resp) {
- $session->disconnect();
- return $type;
- }
+ $user_id, $type, $org_id ));
}
-
- $session->disconnect();
return undef;
}
$session->finish();
$session->disconnect();
$session->kill_me();
+ $storage_session = undef;
}
sub rollback_db_session {
$session->finish();
$session->disconnect();
$session->kill_me();
+ $storage_session = undef;
}
return $self->simple_scalar_request($service, $method, @params);
}
+sub get_storage_session {
+ if( $storage_session and
+ $storage_session->connected and
+ $storage_session->app eq 'open-ils.storage' ) {
+ $logger->debug("get_storage_session(): returning existing session");
+ return $storage_session;
+ }
+ $logger->debug("get_storage_session(): returning undef");
+ $storage_session = undef;
+ return undef;
+}
+
sub simple_scalar_request {
my($self, $service, $method, @params) = @_;
- my $session = OpenSRF::AppSession->create( $service );
+ my $session = undef;
+ if( $service eq 'open-ils.storage' ) {
+ if( $session = get_storage_session() ) {
+ $logger->debug("simple request using existing storage session ".$session->session_id);
+ } else { $session = undef; }
+ }
+
+ if(!$session) {
+ $session = OpenSRF::AppSession->create( $service );
+ }
+
+ $logger->debug("simple request for service $service using session " .$session->app);
+
my $request = $session->request( $method, @params );
my $response = $request->recv(30);
$request->finish();
- $session->finish();
- $session->disconnect();
+
+ if($service ne 'open-ils.storage' or !get_storage_session() ) {
+ $session->finish();
+ $session->disconnect();
+ }
my $value;
'open-ils.storage',
'open-ils.storage.direct.action.hold_transit_copy.search.hold', $holdid );
- $evt = OpenILS::Event->new('TRANSIT_NOT_FOUND', holdid => $holdid) unless $transit;
+ $evt = OpenILS::Event->new('HOLD_TRANSIT_NOT_FOUND', holdid => $holdid) unless $transit;
return ($transit, $evt );
}
+sub fetch_hold_transit {
+ my( $self, $transid ) = @_;
+ my( $htransit, $evt );
+ $logger->debug("Fetching hold transit with hold id $transid");
+ $htransit = $self->storagereq(
+ 'open-ils.storage.direct.action.hold_transit_copy.retrieve', $transid );
+ $evt = OpenILS::Event->new('HOLD_TRANSIT_NOT_FOUND', id => $transid) unless $htransit;
+ return ($htransit, $evt);
+}
sub fetch_copy_by_barcode {
my( $self, $barcode ) = @_;
return ($circ, $evt);
}
+sub copy_status_from_name {
+ my( $self, $statuses, $name ) = @_;
+ for my $status (@$statuses) {
+ return $status if( $status->name =~ /$name/i );
+ }
+ return undef;
+}
+
+sub copy_status_to_name {
+ my( $self, $statuses, $sid ) = @_;
+ for my $status (@$statuses) {
+ return $status->name if( $status->id == $sid );
+ }
+ return undef;
+}
+
+sub fetch_open_transit_by_copy {
+ my( $self, $copyid ) = @_;
+ my($transit, $evt);
+ $transit = $self->storagereq(
+ 'open-ils.storage.direct.action.transit_copy.search_where',
+ { target_copy => $copyid, dest_recv_time => undef });
+ $evt = OpenILS::Event->new('TRANSIT_NOT_FOUND') unless $transit;
+ return ($transit, $evt);
+}
+
+
+# un-fleshes a copy and updates it in the DB
+# returns a DB_UPDATE_FAILED event on error
+# returns undef on success
+sub update_copy {
+ my( $self, %params ) = @_;
+
+ my $copy = $params{copy} || die "update_copy(): copy required";
+ my $editor = $params{editor} || die "update_copy(): copy editor required";
+ my $session = $params{session};
+
+ $logger->debug("Updating copy in the database: " . $copy->id);
+
+ $copy->status( $copy->status->id ) if ref($copy->status);
+ $copy->editor( $editor );
+ $copy->edit_date( 'now' );
+ $copy->location( $copy->location->id ) if ref($copy->location);
+ $copy->circ_lib( $copy->circ_lib->id ) if ref($copy->circ_lib);
+
+ my $s;
+ my $meth = 'open-ils.storage.direct.asset.copy.update';
+
+ $s = $session->request( $meth, $copy )->gather(1) if $session;
+ $s = $self->storagereq( $meth, $copy );
+
+ $logger->debug("Update of copy ".$copy->id." returned: $s");
+
+ return $self->DB_UPDATE_FAILED($copy) unless $s;
+ return undef;
+}
1;
# for security, this is a process-defined and not
# a client-defined variable
-my $__isrenewal = 0;
+my $__isrenewal = 0;
+my $__islost = 0;
# ------------------------------------------------------------------------------
# Load the circ script from the config
$requestor, $circlib, $params ) if $params->{precat};
return $evt if $evt;
- my $session = $U->start_db_session();
-
# fetch and build the circulation environment
if( !( $ctx = $params->{_ctx}) ) {
( $ctx, $evt ) = create_circ_ctx( %$params,
patron => $patron,
requestor => $requestor,
- session => $session,
+ session => $U->start_db_session(),
type => 'circ',
fetch_patron_circ_summary => 1,
fetch_copy_statuses => 1,
);
return $evt if $evt;
}
- $ctx->{session} = $session;
+ $ctx->{session} = $U->start_db_session() unless $ctx->{session};
my $cid = ($params->{precat}) ? -1 : $ctx->{copy}->id;
return OpenILS::Event->new('CIRC_PERMIT_BAD_KEY')
$evt = _commit_checkout_circ_object($ctx);
return $evt if $evt;
- _update_checkout_copy($ctx);
+ $evt = _update_checkout_copy($ctx);
+ return $evt if $evt;
$evt = _handle_related_holds($ctx);
return $evt if $evt;
- $U->commit_db_session($session);
+ $logger->debug("Checkin committing objects with session thread trace: ".$ctx->{session}->session_id);
+ $U->commit_db_session($ctx->{session});
my $record = $U->record_to_mvr($ctx->{title}) unless $ctx->{precat};
return OpenILS::Event->new('SUCCESS',
$U->logmark;
my $copy = $ctx->{copy};
- my $s;
- for my $status (@{$cache{copy_statuses}}) { #XXX Abstractify me
- $s = $status if( $status->name eq 'Checked out' );
- }
-
+ my $s = $U->copy_status_from_name($cache{copy_statuses}, 'checked out');
$copy->status( $s->id ) if $s;
- $copy->editor( $ctx->{requestor}->id );
- $copy->edit_date( 'now' );
- $copy->location( $copy->location->id );
- $copy->circ_lib( $copy->circ_lib->id );
- $logger->debug("Updating editor info on copy in checkout: " . $copy->id );
- $ctx->{session}->request(
- 'open-ils.storage.direct.asset.copy.update', $copy )->gather(1);
+ my $evt = $U->update_copy( session => $ctx->{session},
+ copy => $copy, editor => $ctx->{requestor}->id );
+ return (undef,$evt) if $evt;
+
+ return undef;
}
# commits the circ object to the db then fleshes the circ with rules objects
my( $self, $client, $authtoken, $params ) = @_;
$U->logmark;
- my( $ctx, $requestor, $evt, $patron, $circ, $copy );
+ my( $ctx, $requestor, $evt, $patron, $circ, $copy, $obt );
( $requestor, $evt ) = $U->checkses($authtoken) if $__isrenewal;
- ( $requestor, $evt ) = $U->checksesperm( $authtoken, 'COPY_CHECKIN' ) unless $__isrenewal;
+ ( $requestor, $evt ) = $U->checksesperm(
+ $authtoken, 'COPY_CHECKIN' ) unless $__isrenewal;
return $evt if $evt;
+
( $patron, $evt ) = $U->fetch_user($params->{patron});
return $evt if $evt;
-# if( !( $ctx = $params->{_ctx}) ) {
-# ( $ctx, $evt ) = create_circ_ctx( %$params,
-# patron => $patron,
-# requestor => $requestor,
-# #session => $session,
-# type => 'circ',
-# fetch_patron_circ_summary => 1,
-# fetch_copy_statuses => 1,
-# fetch_copy_locations => 1,
-# no_runner => 1,
-# );
-# return $evt if $evt;
-# }
-
- ($copy, $evt) = $U->fetch_copy_by_barcode($params->{barcode});
- return $evt if $evt;
+ if( !( $ctx = $params->{_ctx}) ) {
+ ( $ctx, $evt ) = create_circ_ctx( %$params,
+ patron => $patron,
+ requestor => $requestor,
+ session => $U->start_db_session(),
+ type => 'circ',
+ fetch_patron_circ_summary => 1,
+ fetch_copy_statuses => 1,
+ fetch_copy_locations => 1,
+ no_runner => 1,
+ );
+ return $evt if $evt;
+ }
+ $ctx->{session} = $U->start_db_session() unless $ctx->{session};
+
+ $copy = $ctx->{copy};
+ return OpenILS::Event->new('COPY_NOT_FOUND') unless $copy;
+
+# if( $copy->status ==
+# $U->copy_status_from_name($cache{copy_statuses}, 'lost')->id) {
+# $__islost = 1;
+# } else { $__islost = 0; }
+
+ my $status = $U->copy_status_from_name($cache{copy_statuses}, 'in transit');
+ if( $copy->status == $status->id ) {
+ # if this copy is in transit, send it to transit_receive.
+ $evt = transit_receive( $copy->id, $requestor, $ctx->{session} );
+ return $evt unless $U->event_equals($evt, 'SUCCESS');
+ $copy = $evt->{payload};
+ $evt = undef;
+ }
+
+ $copy->status( $U->copy_status_from_name(
+ $cache{copy_statuses}, 'available')->id );
+
-# return OpenILS::Event->new('COPY_NOT_FOUND') unless $ctx->{copy};
( $circ, $evt ) = $U->fetch_open_circulation($copy->id);
return $evt if $evt;
+ $ctx->{circ} = $circ;
+
+ return $evt if($evt = _update_checkin_circ_and_copy($ctx));
- # XXX Use the old checkin for now XXX
- my $checkin = $self->method_lookup("open-ils.circ.checkin.barcode");
- my ($status) = $checkin->run($authtoken, $copy->barcode, $__isrenewal);
+ $logger->debug("Checkin committing objects with ".
+ "session thread trace: ".$ctx->{session}->session_id);
+ $U->commit_db_session($ctx->{session});
- return OpenILS::Event->new('PERM_FAILURE')
- if ref($status) eq "Fieldmapper::perm_ex";
- return OpenILS::Event->new('ROUTE_ITEM', payload => $status->{route_to} )
- if( $status->{status} eq '3' );
- return OpenILS::Event->new('UNKNOWN',
- payload => $status ) if ($status->{status} ne "0");
+ return OpenILS::Event->new('ITEM_NOT_CATALOGED') if $copy->call_number == -1;
return OpenILS::Event->new('SUCCESS');
}
+
+sub _update_checkin_circ_and_copy {
+ my $ctx = shift;
+ $U->logmark;
+
+ my $circ = $ctx->{circ};
+ my $copy = $ctx->{copy};
+ my $requestor = $ctx->{requestor};
+ my $session = $ctx->{session};
+
+ my ( $obt, $evt ) = $U->fetch_open_billable_transaction($circ->id);
+ return $evt if $evt;
+
+ $circ->stop_fines('CHECKIN');
+ $circ->stop_fines('RENEW') if $__isrenewal;
+ $circ->stop_fines('LOST') if($__islost);
+ $circ->xact_finish('now') if($obt->balance_owed <= 0 and !$__islost);
+ $circ->stop_fines_time('now');
+ $circ->checkin_time('now');
+ $circ->checkin_staff($requestor->id);
+
+ # if the requestor set a backdate, void all the bills after
+ # the backdate time
+ if(my $backdate = $ctx->{backdate}) {
+
+ $logger->activity("User ".$requestor->id.
+ " backdating checkin copy [".$ctx->{barcode}."] to date: $backdate");
+
+ $circ->xact_finish($backdate);
+
+ my $bills = $session->request( # XXX what other search criteria??
+ "open-ils.storage.direct.money.billing.search_where.atomic",
+ billing_ts => { ">=" => $backdate })->gather(1);
+
+ if($bills) {
+ for my $bill (@$bills) {
+ $bill->voided('t');
+ my $s = $session->request(
+ "open-ils.storage.direct.money.billing.update", $bill)->gather(1);
+ return $U->DB_UPDATE_FAILED($bill) unless $s;
+ }
+ }
+ }
+
+ $logger->debug("Checkin committing copy and circ objects");
+ $evt = $U->update_copy( session => $session,
+ copy => $copy, editor => $requestor->id );
+ return $evt if $evt;
+
+ $ctx->{session}->request(
+ 'open-ils.storage.direct.action.circulation.update', $circ )->gather(1);
+
+ return undef;
+}
+
+
+
# ------------------------------------------------------------------------------
__PACKAGE__->register_method(
return $evt if( ($evt = _run_renew_scripts($ctx)) );
# checkin the cop
- $evt = $self->checkin($client, $authtoken,
- { barcode => $params->{barcode}, patron => $params->{patron}} );
+ $ctx->{patron} = $ctx->{patron}->id;
+ $evt = $self->checkin($client, $authtoken, $ctx );
+ #{ barcode => $params->{barcode}, patron => $params->{patron}} );
- return $evt unless $U->event_equals($evt, 'SUCCESS')
- or $U->event_equals($evt, 'ROUTE_ITEM');
+ return $evt unless $U->event_equals($evt, 'SUCCESS');
# re-fetch the context since objects have changed in the checkin
( $ctx, $evt ) = create_circ_ctx( %$params,
return undef;
}
+
+
+sub transit_receive {
+ my ( $copyid, $requestor, $session ) = @_;
+ $U->logmark;
+
+ my( $copy, $evt ) = $U->fetch_copy($copyid);
+ my( $transit, $hold_transit );
+ my $cstats = $cache{copy_statuses};
+
+ my $status_name = $U->copy_status_to_name($cstats, $copy->status );
+ $logger->debug("Attempting transit receive on copy $copyid. Copy status is $status_name");
+
+ # fetch the transit
+ ($transit, $evt) = $U->fetch_open_transit_by_copy($copyid);
+ return $evt if $evt;
+
+ if( $transit->dest != $requestor->home_ou ) {
+ $logger->activity("Fowarding transit on copy which is destined ".
+ "for a different location. copy=$copyid,current ".
+ "location=".$requestor->home_ou.",destination location=".$transit->dest);
+
+ return OpenILS::Event->new('ROUTE_ITEM', org => $transit->dest );
+ }
+
+ # The transit is received, set the receive time
+ $transit->dest_recv_time('now');
+ my $r = $session->request(
+ 'open-ils.storage.direct.action.transit_copy.update', $transit )->gather(1);
+ return $U->DB_UPDATE_FAILED($transit) unless $r;
+
+ # if this is a hold transit, finalize the hold transit
+ return $evt if( ($evt = _finish_hold_transit(
+ $session, $requestor, $copy, $transit->id )) );
+
+ $U->logmark;
+
+ #recover this copy's status from the transit
+ $copy->status( $transit->copy_status );
+ return OpenILS::Event->('SUCCESS', payload => $copy);
+
+}
+
+# ------------------------------------------------------------------------------
+# If we have a hold transit, set the copy's status to 'on holds shelf',
+# update the copy, and return the ROUTE_TO_COPY_LOATION event
+# ------------------------------------------------------------------------------
+sub _finish_hold_transit {
+ my( $session, $requestor, $copy, $transid ) = @_;
+ $U->logmark;
+ my ($hold_transit, $evt) = $U->fetch_hold_transit( $transid );
+ return undef unless $hold_transit;
+
+ my $cstats = $cache{copy_statuses};
+ my $s = $U->copy_status_from_name($cstats, 'on holds shelf');
+ $logger->info("Hold transit found: ".$hold_transit->id.". Routing to holds shelf");
+
+ $copy->status($s->id);
+ $copy->editor($requestor->id);
+ $copy->edit_date('now');
+
+ my $r = $session->request(
+ 'open-ils.storage.direct.asset.copy.update', $copy )->gather(1);
+ return $U->DB_UPDATE_FAILED($copy) unless $r;
+
+ return OpenILS::Event->new('ROUTE_TO_COPY_LOCATION', location => $s->id );
+}
+
+
+
+
+
+
+
+
-1;
+666;
+