added a container update method
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Actor / Container.pm
1 package OpenILS::Application::Actor::Container;
2 use base 'OpenSRF::Application';
3 use strict; use warnings;
4 use OpenILS::Application::AppUtils;
5 use OpenILS::Perm;
6 use Data::Dumper;
7 use OpenSRF::EX qw(:try);
8 use OpenILS::Utils::Fieldmapper;
9
10 my $apputils = "OpenILS::Application::AppUtils";
11 my $U = $apputils;
12 my $logger = "OpenSRF::Utils::Logger";
13
14 sub initialize { return 1; }
15
16 my $svc = 'open-ils.storage';
17 my $meth = 'open-ils.storage.direct.container';
18 my %types;
19 $types{'biblio'} = "$meth.biblio_record_entry_bucket";
20 $types{'callnumber'} = "$meth.call_number_bucket";
21 $types{'copy'} = "$meth.copy_bucket";
22 $types{'user'} = "$meth.user_bucket";
23 my $event;
24
25 sub _sort_buckets {
26         my $buckets = shift;
27         return $buckets unless ($buckets && $buckets->[0]);
28         return [ sort { $a->name cmp $b->name } @$buckets ];
29 }
30
31 __PACKAGE__->register_method(
32         method  => "bucket_retrieve_all",
33         api_name        => "open-ils.actor.container.all.retrieve_by_user",
34         notes           => <<"  NOTES");
35                 Retrieves all un-fleshed buckets assigned to given user 
36                 PARAMS(authtoken, bucketOwnerId)
37                 If requestor ID is different than bucketOwnerId, requestor must have
38                 VIEW_CONTAINER permissions.
39         NOTES
40
41 sub bucket_retrieve_all {
42         my($self, $client, $authtoken, $userid) = @_;
43
44         my( $staff, $evt ) = $apputils->checkses($authtoken);
45         return $evt if $evt;
46
47         my( $user, $e ) = $apputils->checkrequestor( $staff, $userid, 'VIEW_CONTAINER');
48         return $e if $e;
49
50         $logger->debug("User " . $staff->id . 
51                 " retrieving all buckets for user $userid");
52
53         my %buckets;
54
55         $buckets{$_} = $apputils->simplereq( 
56                 $svc, $types{$_} . ".search.owner.atomic", $userid ) for keys %types;
57
58         return \%buckets;
59 }
60
61 __PACKAGE__->register_method(
62         method  => "bucket_flesh",
63         api_name        => "open-ils.actor.container.flesh",
64         argc            => 3, 
65         notes           => <<"  NOTES");
66                 Fleshes a bucket by id
67                 PARAMS(authtoken, bucketClass, bucketId)
68                 bucketclasss include biblio, callnumber, copy, and user.  
69                 bucketclass defaults to biblio.
70                 If requestor ID is different than bucketOwnerId, requestor must have
71                 VIEW_CONTAINER permissions.
72         NOTES
73
74 sub bucket_flesh {
75
76         my($self, $client, $authtoken, $class, $bucket) = @_;
77
78         my( $staff, $evt ) = $apputils->checkses($authtoken);
79         return $evt if $evt;
80
81         $logger->debug("User " . $staff->id . " retrieving bucket $bucket");
82
83         my $meth = $types{$class};
84
85         my $bkt = $apputils->simplereq( $svc, "$meth.retrieve", $bucket );
86         if(!$bkt) {return undef};
87
88         if(!$bkt->pub) {
89                 my( $user, $e ) = $apputils->checkrequestor( $staff, $bkt->owner, 'VIEW_CONTAINER' );
90                 return $e if $e;
91         }
92
93         $bkt->items( $apputils->simplereq( $svc,
94                 "$meth"."_item.search.bucket.atomic", $bucket ) );
95
96         return $bkt;
97 }
98
99
100 __PACKAGE__->register_method(
101         method  => "bucket_flesh_public",
102         api_name        => "open-ils.actor.container.public.flesh",
103         argc            => 3, 
104         notes           => <<"  NOTES");
105                 Fleshes a bucket by id
106                 PARAMS(authtoken, bucketClass, bucketId)
107                 bucketclasss include biblio, callnumber, copy, and user.  
108                 bucketclass defaults to biblio.
109                 If requestor ID is different than bucketOwnerId, requestor must have
110                 VIEW_CONTAINER permissions.
111         NOTES
112
113 sub bucket_flesh_public {
114
115         my($self, $client, $class, $bucket) = @_;
116
117         my $meth = $types{$class};
118         my $bkt = $apputils->simplereq( $svc, "$meth.retrieve", $bucket );
119         return undef unless ($bkt and $bkt->pub);
120
121         $bkt->items( $apputils->simplereq( $svc,
122                 "$meth"."_item.search.bucket.atomic", $bucket ) );
123
124         return $bkt;
125 }
126
127
128 __PACKAGE__->register_method(
129         method  => "bucket_retrieve_class",
130         api_name        => "open-ils.actor.container.retrieve_by_class",
131         argc            => 3, 
132         notes           => <<"  NOTES");
133                 Retrieves all un-fleshed buckets by class assigned to given user 
134                 PARAMS(authtoken, bucketOwnerId, class [, type])
135                 class can be one of "biblio", "callnumber", "copy", "user"
136                 The optional "type" parameter allows you to limit the search by 
137                 bucket type.  
138                 If bucketOwnerId is not defined, the authtoken is used as the
139                 bucket owner.
140                 If requestor ID is different than bucketOwnerId, requestor must have
141                 VIEW_CONTAINER permissions.
142         NOTES
143
144 sub bucket_retrieve_class {
145         my( $self, $client, $authtoken, $userid, $class, $type ) = @_;
146
147         my( $staff, $user, $evt ) = 
148                 $apputils->checkses_requestor( $authtoken, $userid, 'VIEW_CONTAINER' );
149         return $evt if $evt;
150
151         $logger->debug("User " . $staff->id . 
152                 " retrieving buckets for user $userid [class=$class, type=$type]");
153
154         my $meth = $types{$class} . ".search_where.atomic";
155         my $buckets;
156
157         if( $type ) {
158                 $buckets = $apputils->simplereq( $svc, 
159                         $meth, { owner => $userid, btype => $type } );
160         } else {
161                 $logger->debug("Grabbing buckets by class $class: $svc : $meth :  {owner => $userid}");
162                 $buckets = $apputils->simplereq( $svc, $meth, { owner => $userid } );
163         }
164
165         return _sort_buckets($buckets);
166 }
167
168 __PACKAGE__->register_method(
169         method  => "bucket_create",
170         api_name        => "open-ils.actor.container.create",
171         notes           => <<"  NOTES");
172                 Creates a new bucket object.  If requestor is different from
173                 bucketOwner, requestor needs CREATE_CONTAINER permissions
174                 PARAMS(authtoken, bucketObject);
175                 Returns the new bucket object
176         NOTES
177
178 sub bucket_create {
179         my( $self, $client, $authtoken, $class, $bucket ) = @_;
180
181         my( $staff, $target, $evt ) = 
182                 $apputils->checkses_requestor( 
183                         $authtoken, $bucket->owner, 'CREATE_CONTAINER' );
184         return $evt if $evt;
185
186         $logger->activity( "User " . $staff->id . 
187                 " creating a new container for user " . $bucket->owner );
188
189         $bucket->clear_id;
190         $logger->debug("Creating new container object: " . Dumper($bucket));
191
192         my $method = $types{$class} . ".create";
193         my $id = $apputils->simplereq( $svc, $method, $bucket );
194
195         $logger->debug("Creatined new container with id $id");
196
197         if(!$id) { throw OpenSRF::EX 
198                 ("Unable to create new bucket object"); }
199
200         return $id;
201 }
202
203
204 __PACKAGE__->register_method(
205         method  => "bucket_delete",
206         api_name        => "open-ils.actor.container.delete",
207         notes           => <<"  NOTES");
208                 Deletes a bucket object.  If requestor is different from
209                 bucketOwner, requestor needs DELETE_CONTAINER permissions
210                 PARAMS(authtoken, class, bucketId);
211                 Returns the new bucket object
212         NOTES
213
214 sub bucket_delete {
215         my( $self, $client, $authtoken, $class, $bucketid ) = @_;
216
217         my( $bucket, $staff, $target, $evt );
218
219         ( $bucket, $evt ) = $apputils->fetch_container($bucketid, $class);
220         return $evt if $evt;
221
222         ( $staff, $target, $evt ) = $apputils->checkses_requestor( 
223                 $authtoken, $bucket->owner, 'DELETE_CONTAINER' );
224         return $evt if $evt;
225
226         $logger->activity( "User " . $staff->id . 
227                 " deleting container $bucketid for user " . $bucket->owner );
228
229         my $method = $types{$class} . ".delete";
230         my $resp = $apputils->simplereq( $svc, $method, $bucketid );
231
232         throw OpenSRF::EX ("Unable to create new bucket object") unless $resp;
233         return $resp;
234 }
235
236
237 __PACKAGE__->register_method(
238         method  => "item_create",
239         api_name        => "open-ils.actor.container.item.create",
240         notes           => <<"  NOTES");
241                 PARAMS(authtoken, class, item)
242         NOTES
243
244 sub item_create {
245         my( $self, $client, $authtoken, $class, $item ) = @_;
246         my( $bucket, $staff, $target, $evt);
247
248         ( $bucket, $evt ) = $apputils->fetch_container($item->bucket, $class);
249         return $evt if $evt;
250
251         ( $staff, $target, $evt ) = $apputils->checkses_requestor( 
252                 $authtoken, $bucket->owner, 'CREATE_CONTAINER_ITEM' );
253         return $evt if $evt;
254
255         $logger->activity( "User " . $staff->id . 
256                 " creating container item for bucket " . $item->bucket . " and user " . $bucket->owner );
257
258         my $method = $types{$class} . "_item.create";
259         my $resp = $apputils->simplereq( $svc, $method, $item );
260
261         return $U->DB_UPDATE_FAILED($item) unless $resp;
262         return $resp;
263 }
264
265
266
267 __PACKAGE__->register_method(
268         method  => "item_delete",
269         api_name        => "open-ils.actor.container.item.delete",
270         notes           => <<"  NOTES");
271                 PARAMS(authtoken, class, itemId)
272         NOTES
273
274 sub item_delete {
275         my( $self, $client, $authtoken, $class, $itemid ) = @_;
276         my( $bucket, $item, $staff, $target, $evt);
277
278         
279         ( $item, $evt ) = $apputils->fetch_container_item( $itemid, $class );
280         return $evt if $evt;
281
282         ( $bucket, $evt ) = $apputils->fetch_container($item->bucket, $class);
283         return $evt if $evt;
284
285         ( $staff, $target, $evt ) = $apputils->checkses_requestor( 
286                 $authtoken, $bucket->owner, 'DELETE_CONTAINER_ITEM' );
287         return $evt if $evt;
288
289         $logger->activity( "User " . $staff->id . 
290                 " deleting continer item  $itemid for user " . $bucket->owner );
291
292         my $method = $types{$class} . "_item.delete";
293         my $resp = $apputils->simplereq( $svc, $method, $itemid );
294
295         throw OpenSRF::EX ("Unable to delete container item") unless $resp;
296         return $resp;
297 }
298
299 __PACKAGE__->register_method(
300         method  => 'full_delete',
301         api_name        => 'open-ils.actor.container.full_delete',
302         notes           => "Complety removes a container including all attached items",
303 );      
304
305 sub full_delete {
306         my( $self, $client, $authtoken, $class, $containerId ) = @_;
307         my( $staff, $target, $container, $evt);
308
309         ( $container, $evt ) = $apputils->fetch_container($containerId, $class);
310         return $evt if $evt;
311
312         ( $staff, $target, $evt ) = $apputils->checkses_requestor( 
313                 $authtoken, $container->owner, 'DELETE_CONTAINER' );
314         return $evt if $evt;
315
316         $logger->activity("User " . $staff->id . " deleting full container $containerId");
317
318         my $meth = $types{$class};
319         my $items = $apputils->simplereq( $svc, "$meth"."_item.search.bucket.atomic", $containerId );
320
321         $self->item_delete( $client, $authtoken, $class, $_->id ) for @$items;
322
323         $meth = $types{$class} . ".delete";
324         return $apputils->simplereq( $svc, $meth, $containerId );
325 }
326
327 __PACKAGE__->register_method(
328         method          => 'container_update',
329         api_name                => 'open-ils.actor.container.update',
330         signature       => q/
331                 Updates the given container item.
332                 @param authtoken The login session key
333                 @param class The container class
334                 @param container The container item
335                 @return true on success, 0 on no update, Event on error
336                 /
337 );
338
339 sub container_update {
340         my( $self, $conn, $authtoken, $class, $container )  = @_;
341
342         my( $staff, $target, $dbcontainer, $evt);
343
344         ( $dbcontainer, $evt ) = $apputils->fetch_container($container->id, $class);
345         return $evt if $evt;
346
347         ( $staff, $target, $evt ) = $apputils->checkses_requestor( 
348                 $authtoken, $dbcontainer->owner, 'UPDATE_CONTAINER' );
349         return $evt if $evt;
350
351         $logger->activity("User " . $staff->id . " updating container ". $container->id);
352
353         my $meth = $types{$class}.".update";
354         return $U->storagereq($meth, $container);
355 }
356
357
358
359
360 1;
361
362