]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Actor/Container.pm
making OpenILS::Application the base app so that authoritative works
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Actor / Container.pm
1 package OpenILS::Application::Actor::Container;
2 use base 'OpenILS::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 use OpenILS::Utils::CStoreEditor qw/:funcs/;
10
11 my $apputils = "OpenILS::Application::AppUtils";
12 my $U = $apputils;
13 my $logger = "OpenSRF::Utils::Logger";
14
15 sub initialize { return 1; }
16
17 my $svc = 'open-ils.cstore';
18 my $meth = 'open-ils.cstore.direct.container';
19 my %types;
20 $types{'biblio'} = "$meth.biblio_record_entry_bucket";
21 $types{'callnumber'} = "$meth.call_number_bucket";
22 $types{'copy'} = "$meth.copy_bucket";
23 $types{'user'} = "$meth.user_bucket";
24 my $event;
25
26 sub _sort_buckets {
27         my $buckets = shift;
28         return $buckets unless ($buckets && $buckets->[0]);
29         return [ sort { $a->name cmp $b->name } @$buckets ];
30 }
31
32 __PACKAGE__->register_method(
33         method  => "bucket_retrieve_all",
34         api_name        => "open-ils.actor.container.all.retrieve_by_user",
35         notes           => <<"  NOTES");
36                 Retrieves all un-fleshed buckets assigned to given user 
37                 PARAMS(authtoken, bucketOwnerId)
38                 If requestor ID is different than bucketOwnerId, requestor must have
39                 VIEW_CONTAINER permissions.
40         NOTES
41
42 sub bucket_retrieve_all {
43         my($self, $client, $authtoken, $userid) = @_;
44
45         my( $staff, $evt ) = $apputils->checkses($authtoken);
46         return $evt if $evt;
47
48         my( $user, $e ) = $apputils->checkrequestor( $staff, $userid, 'VIEW_CONTAINER');
49         return $e if $e;
50
51         $logger->debug("User " . $staff->id . 
52                 " retrieving all buckets for user $userid");
53
54         my %buckets;
55
56         $buckets{$_} = $apputils->simplereq( 
57                 $svc, $types{$_} . ".search.atomic", { owner => $userid } ) for keys %types;
58
59         return \%buckets;
60 }
61
62 __PACKAGE__->register_method(
63         method  => "bucket_flesh",
64         api_name        => "open-ils.actor.container.flesh",
65         argc            => 3, 
66         notes           => <<"  NOTES");
67                 Fleshes a bucket by id
68                 PARAMS(authtoken, bucketClass, bucketId)
69                 bucketclasss include biblio, callnumber, copy, and user.  
70                 bucketclass defaults to biblio.
71                 If requestor ID is different than bucketOwnerId, requestor must have
72                 VIEW_CONTAINER permissions.
73         NOTES
74
75 sub bucket_flesh {
76
77         my($self, $client, $authtoken, $class, $bucket) = @_;
78
79         my( $staff, $evt ) = $apputils->checkses($authtoken);
80         return $evt if $evt;
81
82         $logger->debug("User " . $staff->id . " retrieving bucket $bucket");
83
84         my $meth = $types{$class};
85
86         my $bkt = $apputils->simplereq( $svc, "$meth.retrieve", $bucket );
87         #if(!$bkt) {return undef};
88         return OpenILS::Event->new('CONTAINER_NOT_FOUND', payload=>$bucket) unless $bkt;
89
90         if(!$bkt->pub) {
91                 my( $user, $e ) = $apputils->checkrequestor( $staff, $bkt->owner, 'VIEW_CONTAINER' );
92                 return $e if $e;
93         }
94
95         $bkt->items( $apputils->simplereq( $svc,
96                 "$meth"."_item.search.atomic", { bucket => $bucket } ) );
97
98         return $bkt;
99 }
100
101
102 __PACKAGE__->register_method(
103         method  => "bucket_flesh_public",
104         api_name        => "open-ils.actor.container.public.flesh",
105         argc            => 3, 
106         notes           => <<"  NOTES");
107                 Fleshes a bucket by id
108                 PARAMS(authtoken, bucketClass, bucketId)
109                 bucketclasss include biblio, callnumber, copy, and user.  
110                 bucketclass defaults to biblio.
111                 If requestor ID is different than bucketOwnerId, requestor must have
112                 VIEW_CONTAINER permissions.
113         NOTES
114
115 sub bucket_flesh_public {
116
117         my($self, $client, $class, $bucket) = @_;
118
119         my $meth = $types{$class};
120         my $bkt = $apputils->simplereq( $svc, "$meth.retrieve", $bucket );
121         return undef unless ($bkt and $bkt->pub);
122
123         $bkt->items( $apputils->simplereq( $svc,
124                 "$meth"."_item.search.atomic", { bucket => $bucket } ) );
125
126         return $bkt;
127 }
128
129
130 __PACKAGE__->register_method(
131         method  => "bucket_retrieve_class",
132         api_name        => "open-ils.actor.container.retrieve_by_class",
133         argc            => 3, 
134         notes           => <<"  NOTES");
135                 Retrieves all un-fleshed buckets by class assigned to given user 
136                 PARAMS(authtoken, bucketOwnerId, class [, type])
137                 class can be one of "biblio", "callnumber", "copy", "user"
138                 The optional "type" parameter allows you to limit the search by 
139                 bucket type.  
140                 If bucketOwnerId is not defined, the authtoken is used as the
141                 bucket owner.
142                 If requestor ID is different than bucketOwnerId, requestor must have
143                 VIEW_CONTAINER permissions.
144         NOTES
145
146 sub bucket_retrieve_class {
147         my( $self, $client, $authtoken, $userid, $class, $type ) = @_;
148
149         my( $staff, $user, $evt ) = 
150                 $apputils->checkses_requestor( $authtoken, $userid, 'VIEW_CONTAINER' );
151         return $evt if $evt;
152
153         $logger->debug("User " . $staff->id . 
154                 " retrieving buckets for user $userid [class=$class, type=$type]");
155
156         my $meth = $types{$class} . ".search.atomic";
157         my $buckets;
158
159         if( $type ) {
160                 $buckets = $apputils->simplereq( $svc, 
161                         $meth, { owner => $userid, btype => $type } );
162         } else {
163                 $logger->debug("Grabbing buckets by class $class: $svc : $meth :  {owner => $userid}");
164                 $buckets = $apputils->simplereq( $svc, $meth, { owner => $userid } );
165         }
166
167         return _sort_buckets($buckets);
168 }
169
170 __PACKAGE__->register_method(
171         method  => "bucket_create",
172         api_name        => "open-ils.actor.container.create",
173         notes           => <<"  NOTES");
174                 Creates a new bucket object.  If requestor is different from
175                 bucketOwner, requestor needs CREATE_CONTAINER permissions
176                 PARAMS(authtoken, bucketObject);
177                 Returns the new bucket object
178         NOTES
179
180 sub bucket_create {
181         my( $self, $client, $authtoken, $class, $bucket ) = @_;
182
183         my $e = new_editor(xact=>1, authtoken=>$authtoken);
184         return $e->event unless $e->checkauth;
185
186         if( $bucket->owner ne $e->requestor->id ) {
187                 return $e->event unless
188                         $e->allowed('CREATE_CONTAINER');
189
190         } else {
191                 return $e->event unless
192                         $e->allowed('CREATE_MY_CONTAINER');
193         }
194                 
195         $bucket->clear_id;
196
197     my $evt = OpenILS::Event->new('CONTAINER_EXISTS', 
198         payload => [$class, $bucket->owner, $bucket->btype, $bucket->name]);
199     my $search = {name => $bucket->name, owner => $bucket->owner, btype => $bucket->btype};
200
201         my $obj;
202         if( $class eq 'copy' ) {
203         return $evt if $e->search_container_copy_bucket($search)->[0];
204                 return $e->event unless
205                         $obj = $e->create_container_copy_bucket($bucket);
206         }
207
208         if( $class eq 'callnumber' ) {
209         return $evt if $e->search_container_call_number_bucket($search)->[0];
210                 return $e->event unless
211                         $obj = $e->create_container_call_number_bucket($bucket);
212         }
213
214         if( $class eq 'biblio' ) {
215         return $evt if $e->search_container_biblio_record_entry_bucket($search)->[0];
216                 return $e->event unless
217                         $obj = $e->create_container_biblio_record_entry_bucket($bucket);
218         }
219
220         if( $class eq 'user') {
221         return $evt if $e->search_container_user_bucket($search)->[0];
222                 return $e->event unless
223                         $obj = $e->create_container_user_bucket($bucket);
224         }
225
226         $e->commit;
227         return $obj->id;
228 }
229
230
231 __PACKAGE__->register_method(
232         method  => "item_create",
233         api_name        => "open-ils.actor.container.item.create",
234         notes           => <<"  NOTES");
235                 PARAMS(authtoken, class, item)
236         NOTES
237
238 sub item_create {
239         my( $self, $client, $authtoken, $class, $item ) = @_;
240
241         my $e = new_editor(xact=>1, authtoken=>$authtoken);
242         return $e->event unless $e->checkauth;
243
244         my ( $bucket, $evt ) = $apputils->fetch_container_e($e, $item->bucket, $class);
245         return $evt if $evt;
246
247         if( $bucket->owner ne $e->requestor->id ) {
248                 return $e->event unless
249                         $e->allowed('CREATE_CONTAINER_ITEM');
250
251         } else {
252 #               return $e->event unless
253 #                       $e->allowed('CREATE_CONTAINER_ITEM'); # new perm here?
254         }
255                 
256         $item->clear_id;
257
258         my $stat;
259         if( $class eq 'copy' ) {
260                 return $e->event unless
261                         $stat = $e->create_container_copy_bucket_item($item);
262         }
263
264         if( $class eq 'callnumber' ) {
265                 return $e->event unless
266                         $stat = $e->create_container_call_number_bucket_item($item);
267         }
268
269         if( $class eq 'biblio' ) {
270                 return $e->event unless
271                         $stat = $e->create_container_biblio_record_entry_bucket_item($item);
272         }
273
274         if( $class eq 'user') {
275                 return $e->event unless
276                         $stat = $e->create_container_user_bucket_item($item);
277         }
278
279         $e->commit;
280         return $stat->id;
281 }
282
283
284
285 __PACKAGE__->register_method(
286         method  => "item_delete",
287         api_name        => "open-ils.actor.container.item.delete",
288         notes           => <<"  NOTES");
289                 PARAMS(authtoken, class, itemId)
290         NOTES
291
292 sub item_delete {
293         my( $self, $client, $authtoken, $class, $itemid ) = @_;
294
295         my $e = new_editor(xact=>1, authtoken=>$authtoken);
296         return $e->event unless $e->checkauth;
297
298         my $ret = __item_delete($e, $class, $itemid);
299         $e->commit unless $U->event_code($ret);
300         return $ret;
301 }
302
303 sub __item_delete {
304         my( $e, $class, $itemid ) = @_;
305         my( $bucket, $item, $evt);
306
307         ( $item, $evt ) = $U->fetch_container_item_e( $e, $itemid, $class );
308         return $evt if $evt;
309
310         ( $bucket, $evt ) = $U->fetch_container_e($e, $item->bucket, $class);
311         return $evt if $evt;
312
313         if( $bucket->owner ne $e->requestor->id ) {
314       my $owner = $e->retrieve_actor_user($bucket->owner)
315          or return $e->die_event;
316                 return $e->event unless $e->allowed('DELETE_CONTAINER_ITEM', $owner->home_ou);
317         }
318
319         my $stat;
320         if( $class eq 'copy' ) {
321                 return $e->event unless
322                         $stat = $e->delete_container_copy_bucket_item($item);
323         }
324
325         if( $class eq 'callnumber' ) {
326                 return $e->event unless
327                         $stat = $e->delete_container_call_number_bucket_item($item);
328         }
329
330         if( $class eq 'biblio' ) {
331                 return $e->event unless
332                         $stat = $e->delete_container_biblio_record_entry_bucket_item($item);
333         }
334
335         if( $class eq 'user') {
336                 return $e->event unless
337                         $stat = $e->delete_container_user_bucket_item($item);
338         }
339
340         return $stat;
341 }
342
343
344 __PACKAGE__->register_method(
345         method  => 'full_delete',
346         api_name        => 'open-ils.actor.container.full_delete',
347         notes           => "Complety removes a container including all attached items",
348 );      
349
350 sub full_delete {
351         my( $self, $client, $authtoken, $class, $containerId ) = @_;
352         my( $container, $evt);
353
354         my $e = new_editor(xact=>1, authtoken=>$authtoken);
355         return $e->event unless $e->checkauth;
356
357         ( $container, $evt ) = $apputils->fetch_container_e($e, $containerId, $class);
358         return $evt if $evt;
359
360         if( $container->owner ne $e->requestor->id ) {
361       my $owner = $e->retrieve_actor_user($container->owner)
362          or return $e->die_event;
363                 return $e->event unless $e->allowed('DELETE_CONTAINER', $owner->home_ou);
364         }
365
366         my $items; 
367
368         my @s = ({bucket => $containerId}, {idlist=>1});
369
370         if( $class eq 'copy' ) {
371                 $items = $e->search_container_copy_bucket_item(@s);
372         }
373
374         if( $class eq 'callnumber' ) {
375                 $items = $e->search_container_call_number_bucket_item(@s);
376         }
377
378         if( $class eq 'biblio' ) {
379                 $items = $e->search_container_biblio_record_entry_bucket_item(@s);
380         }
381
382         if( $class eq 'user') {
383                 $items = $e->search_container_user_bucket_item(@s);
384         }
385
386         __item_delete($e, $class, $_) for @$items;
387
388         my $stat;
389         if( $class eq 'copy' ) {
390                 return $e->event unless
391                         $stat = $e->delete_container_copy_bucket($container);
392         }
393
394         if( $class eq 'callnumber' ) {
395                 return $e->event unless
396                         $stat = $e->delete_container_call_number_bucket($container);
397         }
398
399         if( $class eq 'biblio' ) {
400                 return $e->event unless
401                         $stat = $e->delete_container_biblio_record_entry_bucket($container);
402         }
403
404         if( $class eq 'user') {
405                 return $e->event unless
406                         $stat = $e->delete_container_user_bucket($container);
407         }
408
409         $e->commit;
410         return $stat;
411 }
412
413 __PACKAGE__->register_method(
414         method          => 'container_update',
415         api_name                => 'open-ils.actor.container.update',
416         signature       => q/
417                 Updates the given container item.
418                 @param authtoken The login session key
419                 @param class The container class
420                 @param container The container item
421                 @return true on success, 0 on no update, Event on error
422                 /
423 );
424
425 sub container_update {
426         my( $self, $conn, $authtoken, $class, $container )  = @_;
427
428         my $e = new_editor(xact=>1, authtoken=>$authtoken);
429         return $e->event unless $e->checkauth;
430
431         my ( $dbcontainer, $evt ) = $U->fetch_container_e($e, $container->id, $class);
432         return $evt if $evt;
433
434         if( $e->requestor->id ne $container->owner ) {
435                 return $e->event unless $e->allowed('UPDATE_CONTAINER');
436         }
437
438         my $stat;
439         if( $class eq 'copy' ) {
440                 return $e->event unless
441                         $stat = $e->update_container_copy_bucket($container);
442         }
443
444         if( $class eq 'callnumber' ) {
445                 return $e->event unless
446                         $stat = $e->update_container_call_number_bucket($container);
447         }
448
449         if( $class eq 'biblio' ) {
450                 return $e->event unless
451                         $stat = $e->update_container_biblio_record_entry_bucket($container);
452         }
453
454         if( $class eq 'user') {
455                 return $e->event unless
456                         $stat = $e->update_container_user_bucket($container);
457         }
458
459         $e->commit;
460         return $stat;
461 }
462
463
464
465
466 1;
467
468