2 # An object to handle checkin status
5 package OpenILS::SIP::Transaction::Checkin;
10 use POSIX qw(strftime);
11 use Sys::Syslog qw(syslog);
15 use OpenILS::SIP::Transaction;
16 use OpenILS::Const qw/:const/;
17 use OpenILS::Application::AppUtils;
18 my $U = 'OpenILS::Application::AppUtils';
20 use base qw(OpenILS::SIP::Transaction);
27 # 3M extensions: (most of the data is stored under Item)
28 # collection_code => undef,
29 # call_number => undef,
30 destination_loc => undef,
31 alert_type => undef, # 00,01,02,03,04 or 99
32 # hold_patron_id => undef,
33 # hold_patron_name => "",
39 my $self = $class->SUPER::new(@_); # start with an Transaction object
41 foreach (keys %fields) {
42 $self->{_permitted}->{$_} = $fields{$_}; # overlaying _permitted
45 @{$self}{keys %fields} = values %fields; # copying defaults into object
47 return bless $self, $class;
52 return 0 if !$self->{item};
53 return !$self->{item}->magnetic;
59 my ($sip_handler, $inst_id, $trans_date, $return_date, $current_loc, $item_props) = @_; # most unused
61 unless($self->{item}) {
68 # physical location defaults to ws ou of the logged in sip user,
69 # which currently defaults to home_ou, since ws's aren't used.
70 my $phys_location = $sip_handler->{login_session}->ws_ou;
72 my $args = {barcode => $self->{item}->id};
75 # SIP date format is YYYYMMDD. Translate to ISO8601
76 $return_date =~ s/(\d{4})(\d{2})(\d{2}).*/$1-$2-$3/;
77 syslog('LOG_INFO', "Checking in with backdate $return_date");
78 $args->{backdate} = $return_date;
81 if($current_loc) { # SIP client specified a physical location
83 my $org_id = (defined $org_sn_cache{$current_loc}) ?
84 $org_sn_cache{$current_loc} :
85 OpenILS::SIP->editor()->search_actor_org_unit({shortname => $current_loc}, {idlist => 1})->[0];
87 $org_sn_cache{$current_loc} = $org_id;
89 # if the caller specifies a physical location, use it as the checkin circ lib
90 $args->{circ_lib} = $phys_location = $org_id if defined $org_id;
93 my $resp = $U->simplereq(
95 'open-ils.circ.checkin',
96 $self->{authtoken}, $args
100 my $s = Dumper($resp);
102 syslog('LOG_INFO', "OILS: Checkin response: $s");
105 # In oddball cases, we can receive an array of events.
106 # The first event received should be treated as the main result.
107 $resp = $$resp[0] if ref($resp) eq 'ARRAY';
109 my $code = $U->event_code($resp);
110 my $txt = (defined $code) ? $resp->{textcode} : '';
112 syslog('LOG_INFO', "OILS: Checkin resulted in event: $txt, phys_location: $phys_location");
114 $resp->{org} &&= OpenILS::SIP::shortname_from_id($resp->{org}); # Convert id to shortname
116 $self->destination_loc($resp->{org}) if $resp->{org};
118 if ($txt eq 'ROUTE_ITEM') {
119 # Note, this alert_type will be overridden below if this is a hold transit
120 $self->alert_type('04'); # send to other branch
122 } elsif ($txt and $txt ne 'NO_CHANGE' and $txt ne 'SUCCESS') {
123 syslog('LOG_WARNING', "OILS: Checkin returned unexpected event $code : $txt");
124 $self->alert_type('00'); # unknown
127 my $payload = $resp->{payload} || {};
129 # Two places to look for hold data. These are more important and more definitive than above.
130 if ($payload->{remote_hold}) {
131 # actually only used for checkin at non-owning branch w/ hold at same branch
132 $self->item->hold($payload->{remote_hold});
134 } elsif ($payload->{hold}) {
135 $self->item->hold($payload->{hold});
138 if ($self->item->hold) {
139 my $holder = OpenILS::SIP->find_patron('usr' => $self->item->hold->usr) or
140 syslog('LOG_WARNING', "OpenILS::SIP->find_patron cannot find hold usr => '" . $self->item->hold->usr . "'");
142 $self->item->hold_patron_bcode( $holder->id );
143 $self->item->hold_patron_name( $holder->name ); # Item already had the holder ID, we really just needed the name
144 $self->item->destination_loc( OpenILS::SIP::shortname_from_id($self->item->hold->pickup_lib) ); # must use pickup_lib as method
146 my $atype = ($self->item->hold->pickup_lib == $phys_location) ? '01' : '02';
147 $self->alert_type($atype);
150 $self->alert(1) if defined $self->alert_type; # alert_type could be "00", hypothetically
152 my $circ = $resp->{payload}->{circ} || '';
153 my $copy = $resp->{payload}->{copy} || '';
157 } elsif ($txt eq 'NO_CHANGE' or $txt eq 'SUCCESS' or $txt eq 'ROUTE_ITEM') {
158 $self->ok(1); # NO_CHANGE means it wasn't checked out anyway, no problem
161 $self->alert_type('00') unless $self->alert_type; # wasn't checked out, but *something* changed
162 # $self->ok(0); # maybe still ok?
169 Successful Checkin event payload includes:
170 $payload->{copy} (unfleshed)
174 $payload->{cancelled_hold_transit}
180 ASSET_COPY_NOT_FOUND => ,
183 CIRC_CLAIMS_RETURNED => ,
184 COPY_ALERT_MESSAGE => ,
185 COPY_STATUS_LOST => ,
186 COPY_STATUS_MISSING => ,
188 ITEM_DEPOSIT_PAID => ,
190 DATABASE_UPDATE_FAILED => ,
191 DATABASE_QUERY_FAILED => ,
195 # 01 - hold in local library
196 # 02 - hold for other branch
197 # 03 - hold for ILL (not used in EG)
198 # 04 - send to other branch (no hold)