]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Circ/Transit.pm
f937be4df79ee5e979eab0bb4fad37744908673f
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Circ / Transit.pm
1 package OpenILS::Application::Circ::Transit;
2 use base 'OpenSRF::Application';
3 use strict; use warnings;
4 use OpenSRF::EX qw(:try);
5 use Data::Dumper;
6 use OpenSRF::Utils;
7 use OpenSRF::Utils::Cache;
8 use Digest::MD5 qw(md5_hex);
9 use OpenILS::Utils::CStoreEditor qw/:funcs/;
10 use OpenILS::Application::AppUtils;
11 use OpenILS::Application::Circ::Holds;
12 use OpenSRF::Utils::Logger qw(:logger);
13 use OpenSRF::AppSession;
14
15 my $U                                                   = "OpenILS::Application::AppUtils";
16 my $holdcode                            = "OpenILS::Application::Circ::Holds";
17 $Data::Dumper::Indent   = 0;
18
19
20
21 __PACKAGE__->register_method(
22         method  => "copy_transit_receive",
23         api_name        => "open-ils.circ.copy_transit.receive",
24         notes           => q/
25                 Closes out a copy transit
26                 Requestor needs the COPY_TRANSIT_RECEIVE permission
27                 @param authtoken The login session key
28                 @param params An object of named params including
29                         copyid - the id of the copy in quest
30                         barcode - the barcode of the copy in question 
31                                 If copyid is not sent, this is used.
32                 @return A ROUTE_ITEM if the copy is destined for a different location.
33                         A SUCCESS event on success. Other events on error.
34         /);
35
36 sub copy_transit_receive {
37         my( $self, $client, $authtoken, $params ) = @_;
38         my %params = %$params;
39         my( $evt, $copy, $requestor );
40         ($requestor, $evt) = $U->checksesperm($authtoken, 'COPY_TRANSIT_RECEIVE');
41         return $evt if $evt;
42         ($copy, $evt) = $U->fetch_copy($params{copyid});
43         ($copy, $evt) = $U->fetch_copy_by_barcode($params{barcode}) unless $copy;
44         return $evt if $evt;
45         my $session = $U->start_db_session();
46         $evt = $self->transit_receive( $copy, $requestor, $session );
47         $U->commit_db_session($session) if $U->event_equals($evt,'SUCCESS');
48         return $evt;
49 }
50
51 # ------------------------------------------------------------------------------
52 # If the transit destination is different than the requestor's lib,
53 # a ROUTE_TO event is returned with the org set.
54 # If 
55 # ------------------------------------------------------------------------------
56 sub transit_receive {
57         my ( $class, $copy, $requestor, $session ) = @_;
58         $U->logmark;
59
60         my( $transit, $evt );
61         my $copyid = $copy->id;
62
63         my $status_name = $U->copy_status_to_name($copy->status);
64         $logger->debug("Attempting transit receive on copy $copyid. Copy status is $status_name");
65
66         # fetch the transit
67         ($transit, $evt) = $U->fetch_open_transit_by_copy($copyid);
68         return $evt if $evt;
69
70         if( $transit->dest != $requestor->home_ou ) {
71                 $logger->activity("Fowarding transit on copy which is destined ".
72                         "for a different location. copy=$copyid,current ".
73                         "location=".$requestor->home_ou.",destination location=".$transit->dest);
74
75                 return OpenILS::Event->new('ROUTE_ITEM', org => $transit->dest );
76         }
77
78         # The transit is received, set the receive time
79         $transit->dest_recv_time('now');
80         my $r = $session->request(
81                 'open-ils.storage.direct.action.transit_copy.update', $transit )->gather(1);
82         return $U->DB_UPDATE_FAILED($transit) unless $r;
83
84         my $ishold      = 0;
85         my ($ht)                = $U->fetch_hold_transit( $transit->id );
86         if($ht) {
87                 $logger->info("Hold transit found in transit receive...");
88                 $ishold = 1;
89         }
90
91         $logger->info("Recovering original copy status in transit: ".$transit->copy_status);
92         $copy->status( $transit->copy_status );
93         return $evt if ( $evt = 
94                 $U->update_copy( copy => $copy, editor => $requestor->id, session => $session ));
95
96         return OpenILS::Event->new('SUCCESS', ishold => $ishold, 
97                 payload => { transit => $transit, holdtransit => $ht } );
98 }
99
100
101
102
103
104 __PACKAGE__->register_method(
105         method  => "copy_transit_create",
106         api_name        => "open-ils.circ.copy_transit.create",
107         notes           => q/
108                 Creates a new copy transit.  Requestor must have the 
109                 CREATE_COPY_TRANSIT permission.
110                 @param authtoken The login session key
111                 @param params A param object containing the following keys:
112                         copyid          - the copy id
113                         destination     - the id of the org destination.  If not defined,
114                                 defaults to the copy's circ_lib
115                 @return SUCCESS event on success, other event on error
116         /);
117
118 sub copy_transit_create {
119
120         my( $self, $client, $authtoken, $params ) = @_;
121         my %params = %$params;
122
123         my( $requestor, $evt ) = 
124                 $U->checksesperm( $authtoken, 'CREATE_COPY_TRANSIT' );
125         return $evt if $evt;
126
127         my $copy;
128         ($copy,$evt) = $U->fetch_copy($params{copyid});
129         return $evt if $evt;
130
131         my $session             = $params{session} || $U->start_db_session();
132         my $source              = $requestor->home_ou;
133         my $dest                        = $params{destination} || $copy->circ_lib;
134         my $transit             = Fieldmapper::action::transit_copy->new;
135
136         $logger->activity("User ". $requestor->id ." creating a ".
137                 " new copy transit for copy ".$copy->id." to org $dest");
138
139         $transit->source($source);
140         $transit->dest($dest);
141         $transit->target_copy($copy->id);
142         $transit->source_send_time("now");
143         $transit->copy_status($copy->status);
144         
145         $logger->debug("Creating new copy_transit in DB");
146
147         my $s = $session->request(
148                 "open-ils.storage.direct.action.transit_copy.create", $transit )->gather(1);
149         return $U->DB_UPDATE_FAILED($transit) unless $s;
150         
151         my $stat = $U->copy_status_from_name('in transit');
152
153         $copy->status($stat->id); 
154         return $evt if ($evt = $U->update_copy(
155                 copy => $copy, editor => $requestor->id, session => $session ));
156
157         $U->commit_db_session($session) unless $params{session};
158
159         return OpenILS::Event->new('SUCCESS', 
160                 payload => { copy => $copy, transit => $transit } );
161 }
162
163
164 __PACKAGE__->register_method(
165         method => 'abort_transit',
166         api_name        => 'open-ils.circ.transit.abort',
167         signature       => q/
168                 Deletes a cleans up a transit
169         /
170 );
171
172 sub abort_transit {
173         my( $self, $conn, $authtoken, $params ) = @_;
174
175         my $copyid              = $$params{copyid};
176         my $barcode             = $$params{barcode};
177         my $transitid   = $$params{transitid};
178
179         my $copy;
180         my $transit;
181         my $hold;
182         my $evt;
183
184         my $e = new_editor(xact => 1, authtoken => $authtoken);
185         return $e->event unless $e->checkauth;
186         return $e->event unless $e->allowed('ABORT_TRANSIT');
187
188         # ---------------------------------------------------------------------
189         # Find the related copy and/or transit based on whatever data we have
190         if( $barcode ) {
191                 $copy = $e->search_asset_copy({barcode=>$barcode})->[0];
192                 return $e->event unless $copy;
193
194         } elsif( $copyid ) {
195                 $copy = $e->retrieve_asset_copy($copyid) or return $e->event;
196         }
197
198         if( $transitid ) {
199                 $transit = $e->retrieve_action_transit_copy($transitid)
200                         or return $e->event;
201
202         } elsif( $copy ) {
203
204                 $transit = $e->search_action_transit_copy(
205                         { target_copy => $copy->id, dest_recv_time => undef })->[0];
206                 return $e->event unless $transit;
207         }
208
209         if($transit and !$copy) {
210                 $copy = $e->retrieve_asset_copy($transit->target_copy)
211                         or return $e->event;
212         }
213         # ---------------------------------------------------------------------
214
215
216         if( $transit->dest != $e->requestor->ws_ou 
217                 and $transit->source != $e->requestor->ws_ou ) {
218                 return $e->event unless $e->allowed('ABORT_REMOTE_TRANIST', $e->requestor->ws_ou);
219         }
220
221         # recover the copy status
222         $copy->status( $transit->copy_status );
223         $copy->editor( $e->requestor->id );
224         $copy->edit_date('now');
225
226         my $holdtransit = $e->retrieve_action_hold_transit_copy($transit->id);
227
228         return $e->event unless $e->delete_action_transit_copy($transit);
229         return $e->event unless $e->update_asset_copy($copy);
230
231         $e->commit;
232
233         # if this is a hold transit, un-capture/un-target the hold
234         if($holdtransit) {
235                 $hold = $e->retrieve_action_hold_request($holdtransit->hold)
236                         or return $e->event;
237                 $evt = $holdcode->_reset_hold( $e->requestor, $hold );
238                 return $evt if $evt;
239         }
240
241         return 1;
242 }
243
244
245 __PACKAGE__->register_method(
246         method          => 'get_open_copy_transit',
247         api_name                => 'open-ils.circ.open_copy_transit.retrieve',
248         signature       => q/
249                 Retrieves the open transit object for a given copy
250                 @param auth The login session key
251                 @param copyid The id of the copy
252                 @return Transit object
253  /
254 );
255
256 sub get_open_copy_transit {
257         my( $self, $conn, $auth, $copyid ) = @_;        
258         my $e = new_editor(authtoken=>$auth);
259         return $e->event unless $e->checkauth;
260         return $e->event unless $e->allowed('VIEW_USER'); # XXX rely on editor perms
261         my $t = $e->search_action_transit_copy(
262                 { target_copy => $copyid, dest_recv_time => undef });
263         return $e->event unless @$t;
264         return $$t[0];
265 }
266
267
268
269 __PACKAGE__->register_method(
270         method => 'fetch_transit_by_copy',
271         api_name => 'open-ils.circ.fetch_transit_by_copy',
272 );
273
274 sub fetch_transit_by_copy {
275         my( $self, $conn, $auth, $copyid ) = @_;
276         my $e = new_editor(authtoken=>$auth);
277         return $e->event unless $e->checkauth;
278         my $t = $e->search_action_transit_copy(
279                 {
280                         target_copy => $copyid,
281                         dest_recv_time => undef
282                 }
283         )->[0];
284         return $e->event unless $t;
285         my $ht = $e->retrieve_action_hold_transit_copy($t->id);
286         return { atc => $t, ahtc => $ht };
287 }
288
289
290         
291
292
293
294
295 1;