]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/SIP/Transaction/Checkin.pm
honor SIP return date as the circ backdate
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / SIP / Transaction / Checkin.pm
1 #
2 # An object to handle checkin status
3 #
4
5 package OpenILS::SIP::Transaction::Checkin;
6
7 use warnings;
8 use strict;
9
10 use POSIX qw(strftime);
11 use Sys::Syslog qw(syslog);
12 use Data::Dumper;
13
14 use OpenILS::SIP;
15 use OpenILS::SIP::Transaction;
16 use OpenILS::Const qw/:const/;
17 use OpenILS::Application::AppUtils;
18 my $U = 'OpenILS::Application::AppUtils';
19
20 use base qw(OpenILS::SIP::Transaction);
21
22 my $debug = 0;
23
24 my %fields = (
25     magnetic => 0,
26     sort_bin => undef,
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 => "",
34 #   hold             => undef,
35 );
36
37 sub new {
38     my $class = shift;;
39     my $self = $class->SUPER::new(@_);              # start with an Transaction object
40
41     foreach (keys %fields) {
42         $self->{_permitted}->{$_} = $fields{$_};    # overlaying _permitted
43     }
44
45     @{$self}{keys %fields} = values %fields;        # copying defaults into object
46
47     return bless $self, $class;
48 }
49
50 sub resensitize {
51     my $self = shift;
52     return 0 if !$self->{item};
53     return !$self->{item}->magnetic;
54 }
55
56 my %org_sn_cache;
57 sub do_checkin {
58     my $self = shift;
59     my ($sip_handler, $inst_id, $trans_date, $return_date, $current_loc, $item_props) = @_; # most unused
60
61     unless($self->{item}) {
62         $self->ok(0);
63         return undef;
64     }
65
66     $inst_id ||= '';
67
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;
71
72     my $args = {barcode => $self->{item}->id};
73
74     if($return_date) {
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;
79     }
80
81     if($current_loc) { # SIP client specified a physical location
82
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];
86
87         $org_sn_cache{$current_loc} = $org_id;
88
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;
91     }
92
93     my $resp = $U->simplereq(
94         'open-ils.circ',
95         'open-ils.circ.checkin',
96         $self->{authtoken}, $args
97     );
98
99     if ($debug) {
100         my $s = Dumper($resp);
101         $s =~ s/\n//mog;
102         syslog('LOG_INFO', "OILS: Checkin response: $s");
103     }
104
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';
108
109     my $code = $U->event_code($resp);
110     my $txt  = (defined $code) ? $resp->{textcode} : '';
111
112     syslog('LOG_INFO', "OILS: Checkin resulted in event: $txt, phys_location: $phys_location");
113
114     $resp->{org} &&= OpenILS::SIP::shortname_from_id($resp->{org}); # Convert id to shortname
115
116     $self->destination_loc($resp->{org}) if $resp->{org};
117
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
121
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
125     }
126     
127     my $payload = $resp->{payload} || {};
128
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});     
133
134     } elsif ($payload->{hold}) {
135         $self->item->hold($payload->{hold});
136     }
137
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 . "'");
141
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
145
146         my $atype = ($self->item->hold->pickup_lib == $phys_location) ? '01' : '02';
147         $self->alert_type($atype);
148     }
149
150     $self->alert(1) if defined $self->alert_type;  # alert_type could be "00", hypothetically
151
152     my $circ = $resp->{payload}->{circ} || '';
153     my $copy = $resp->{payload}->{copy} || '';
154
155     if ( $circ ) {
156         $self->ok(1);
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
159     } else {
160         $self->alert(1);
161         $self->alert_type('00') unless $self->alert_type; # wasn't checked out, but *something* changed
162         # $self->ok(0); # maybe still ok?
163     }
164 }
165
166 1;
167 __END__
168
169 Successful Checkin event payload includes:
170     $payload->{copy}   (unfleshed)
171     $payload->{record} 
172     $payload->{circ}   
173     $payload->{transit}
174     $payload->{cancelled_hold_transit}
175     $payload->{hold}   
176     $payload->{patron} 
177
178 Some EVENT strings:
179     SUCCESS                => ,
180     ASSET_COPY_NOT_FOUND   => ,
181     NO_CHANGE              => ,
182     PERM_FAILURE           => ,
183     CIRC_CLAIMS_RETURNED   => ,
184     COPY_ALERT_MESSAGE     => ,
185     COPY_STATUS_LOST       => ,
186     COPY_STATUS_MISSING    => ,
187     COPY_BAD_STATUS        => ,
188     ITEM_DEPOSIT_PAID      => ,
189     ROUTE_ITEM             => ,
190     DATABASE_UPDATE_FAILED => ,
191     DATABASE_QUERY_FAILED  => ,
192
193 # alert_type:
194 #   00 - Unknown
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)
199 #   99 - Other