]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/lib/OpenILS/Application/Actor/Carousel.pm
LP 2061136 follow-up: ng lint --fix
[working/Evergreen.git] / Open-ILS / src / perlmods / lib / OpenILS / Application / Actor / Carousel.pm
1 package OpenILS::Application::Actor::Carousel;
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 use OpenSRF::Utils::SettingsClient;
11 use OpenSRF::Utils::Cache;
12 use Digest::MD5 qw(md5_hex);
13 use OpenSRF::Utils::JSON;
14
15 my $apputils = "OpenILS::Application::AppUtils";
16 my $U = $apputils;
17 my $logger = "OpenSRF::Utils::Logger";
18
19 sub initialize { return 1; }
20
21 __PACKAGE__->register_method(
22     method  => "get_carousel_contents",
23     api_name    => "open-ils.actor.carousel.get_contents",
24     authoritative => 1,
25     notes        => <<"    NOTES");
26         Given a carousel ID, returns the carousel name and any publicly-visible
27         bibs from the associated bucket
28         PARAMS(carousel_id)
29     NOTES
30
31 sub get_carousel_contents {
32     my($self, $client, $id) = @_;
33     my $e = new_editor();
34     my $carousel = $e->retrieve_container_carousel($id);
35     my $ret = {
36         id   => $id,
37         name => $carousel->name
38     };
39     my $q = {
40         select => { bre => ['id'], rmsr => ['title','author'] },
41         from   => {
42             cbrebi => {
43                 cbreb => {
44                     join => { cc => {} }
45                 },
46                 bre => {
47                     join => { rmsr => { fkey => 'id', field => 'id' } }
48                 }
49             }
50         },
51         where  => {
52             '+cc' => { id => $id },
53             '+bre' => { deleted => 'f' }
54         },
55         order_by => {cbrebi => ['pos','create_time']}
56     };
57     my $r = $e->json_query($q);
58     $ret->{bibs} = $r;
59     return $ret;
60 }
61
62 __PACKAGE__->register_method(
63     method  => "retrieve_carousels_at_org",
64     api_name    => "open-ils.actor.carousel.retrieve_by_org",
65     authoritative => 1,
66     notes        => <<"    NOTES");
67         Retrieves the IDs and override names of all carousels visible
68         at the specified org unit sorted by their sequence number at
69         that library
70         PARAMS(OrgId)
71     NOTES
72
73 sub retrieve_carousels_at_org {
74     my($self, $client, $org_id) = @_;
75     my $e = new_editor();
76
77     my $carousels = $e->json_query({
78         select => { ccou => ['carousel','override_name','seq'], cc => ['name'] },
79         distinct => 'true',
80         from => { ccou => 'cc' } ,
81         where => {
82             '+ccou' => { org_unit => $org_id },
83             '+cc'   => { active => 't' }
84         },
85         order_by => {
86             'ccou' => ['seq']
87         }
88     });
89
90     return $carousels;
91 }
92
93 __PACKAGE__->register_method(
94     method  => "retrieve_manual_carousels_for_staff",
95     api_name    => "open-ils.actor.carousel.retrieve_manual_by_staff",
96     authoritative => 1,
97     notes        => <<"    NOTES");
98         Retrieves the IDs, buckets, and names of all manually-maintained
99         carousels visible at any of the staff members working
100         locations.
101         PARAMS(authtoken)
102     NOTES
103
104 sub retrieve_manual_carousels_for_staff {
105     my($self, $client, $auth) = @_;
106     my $e = new_editor(authtoken => $auth);
107     return $e->die_event unless $e->checkauth;
108
109     my $orgs = [];
110     if ($e->requestor->super_user eq 't') {
111         # super users can act/see at all OUs
112         my $ous = $e->json_query({
113             select => { aou => ['id'] },
114             from => 'aou'
115         });
116         $orgs = [ map { $_->{id} } @$ous ];
117     } else {
118         my $ous = $e->json_query({
119             select => { puwoum => ['work_ou'] },
120             from => 'puwoum',
121             where => {
122                 '+puwoum' => { usr => $e->requestor->id }
123             }
124         });
125         $orgs = [ map { $_->{work_ou} } @$ous ];
126     }
127
128     my $carousels = $e->json_query({
129         select => { cc => ['id','name','bucket'] },
130         distinct => 'true',
131         from => { cc => 'ccou' },
132         where => {
133             '+ccou' => { org_unit => $orgs },
134             '+cc'   => { type => 1, active => 't' }, # FIXME
135         },
136         order_by => {
137             'cc' => ['name']
138         }
139     });
140
141     return $carousels;
142 }
143
144 __PACKAGE__->register_method(
145     method  => "refresh_carousel",
146     api_name    => "open-ils.actor.carousel.refresh",
147     authoritative => 1,
148     notes        => <<"    NOTES");
149         Refreshes the specified carousel
150         PARAMS(authtoken, carousel_id)
151     NOTES
152
153 sub refresh_carousel {
154     my ($self, $client, $auth, $carousel_id) = @_;
155
156     my $e = new_editor(authtoken => $auth);
157     return $e->event unless $e->checkauth;
158     return $e->event unless $e->allowed('REFRESH_CAROUSEL');
159
160     my $carousel;
161     $carousel = $e->retrieve_container_carousel($carousel_id) or return $e->event;
162
163     return $e->event unless $e->allowed('REFRESH_CAROUSEL', $carousel->owner, $carousel);
164
165     my $ctype;
166     $ctype = $e->retrieve_config_carousel_type($carousel->type) or return $e->event;
167     return new OpenILS::Event('CANNOT_REFRESH_MANUAL_CAROUSEL') unless $ctype->automatic eq 't';
168
169     my $orgs = [];
170     my $locs = [];
171     if (defined($carousel->owning_lib_filter)) {
172         my $ou_filter = $carousel->owning_lib_filter;
173         $ou_filter =~ s/[{}]//g;
174         @$orgs = split /,/, $ou_filter;
175     }
176     if (defined($carousel->copy_location_filter)) {
177         my $loc_filter = $carousel->copy_location_filter;
178         $loc_filter =~ s/[{}]//g;
179         @$locs = split /,/, $loc_filter;
180     }
181
182     my $num_updated = $U->simplereq(
183         'open-ils.storage',
184         'open-ils.storage.container.refresh_from_carousel',
185         $carousel->bucket,
186         $carousel->type,
187         $carousel->age_filter,
188         $orgs,
189         $locs,
190         $carousel->max_items,
191     );
192
193     $carousel->last_refresh_time('now');
194     $e->xact_begin;
195     $e->update_container_carousel($carousel) or return $e->event;
196     $e->xact_commit or return $e->event;
197
198     return $num_updated;
199 }
200
201 __PACKAGE__->register_method(
202     method  => "add_carousel_from_bucket",
203     api_name    => "open-ils.actor.carousel.create.from_bucket",
204     authoritative => 1,
205     notes        => <<"    NOTES");
206         Creates new carousel and its container by copying the
207         contents of an existing bucket.
208         PARAMS(authtoken, carousel_name, bucket_id)
209     NOTES
210
211 sub add_carousel_from_bucket {
212     my ($self, $client, $auth, $carousel_name, $bucket_id) = @_;
213
214     my $e = new_editor(authtoken => $auth);
215     return $e->event unless $e->checkauth;
216     return $e->event unless $e->allowed('ADMIN_CAROUSEL');
217
218     $e->xact_begin;
219
220     # gather old entries to get a count and set max_items appropriately
221     my $entries = $e->search_container_biblio_record_entry_bucket_item({ bucket => $bucket_id });
222
223     my $carousel = Fieldmapper::container::carousel->new;
224     $carousel->name($carousel_name);
225     $carousel->type(1); # manual
226     $carousel->owner($e->requestor->ws_ou);
227     $carousel->creator($e->requestor->id);
228     $carousel->editor($e->requestor->id);
229     $carousel->max_items(scalar(@$entries));
230     $carousel->bucket($bucket_id);
231     $e->create_container_carousel($carousel) or return $e->event;
232
233     $e->xact_commit or return $e->event;
234
235     return $carousel->id;
236 }
237
238 __PACKAGE__->register_method(
239     method => "create_carousel_from_items",
240     api_name => "open-ils.actor.carousel.create_carousel_from_items",
241     signature => {
242         desc => q/Create a new carousel populated with the records connected to the requested items/,
243         params => [
244             { name => 'authtoken',
245               desc => 'A user authtoken',
246               type => 'string' },
247             { name => 'carousel_name',
248               desc => 'A name for the new carousel',
249               type => 'string' },
250             { name => 'items',
251               desc => 'Array of copy locations to filter copies by, optional and can be undef.',
252               type => 'array' }
253         ],
254         return => {
255             type => 'int',
256             desc => q/The id of the new carousel/
257         }
258     }
259 );
260
261 sub create_carousel_from_items {
262     my ($self, $client, $auth, $carousel_name, $item_ids) = @_;
263
264     my $e = new_editor(authtoken => $auth);
265     return $e->event unless $e->checkauth;
266     return $e->event unless $e->allowed('ADMIN_CAROUSEL');
267
268     $e->xact_begin;
269     my $bucket = Fieldmapper::container::biblio_record_entry_bucket->new;
270     $bucket->owner($e->requestor->id);
271     $bucket->name('New bucket created from items by ' . $e->requestor->id . ' on ' . localtime());
272     $bucket->btype('carousel');
273     $bucket->pub('t');
274     $bucket->owning_lib($e->requestor->ws_ou);
275     $e->create_container_biblio_record_entry_bucket($bucket) or return $e->event;
276
277     my $bre_ids = _acp_ids_to_bre_ids($e, $item_ids);
278
279     my $carousel = Fieldmapper::container::carousel->new;
280     $carousel->name($carousel_name);
281     $carousel->type(1); # manual
282     $carousel->owner($e->requestor->ws_ou);
283     $carousel->creator($e->requestor->id);
284     $carousel->editor($e->requestor->id);
285     $carousel->max_items(scalar(@$bre_ids));
286     $carousel->bucket($bucket->id);
287     $e->create_container_carousel($carousel) or return $e->event;
288
289     foreach my $bre_id (@$bre_ids) {
290         my $entry = Fieldmapper::container::biblio_record_entry_bucket_item->new;
291         $entry->target_biblio_record_entry($bre_id);
292         $entry->bucket($bucket->id);
293         $entry->create_time('now');
294         $e->create_container_biblio_record_entry_bucket_item($entry) or return $e->event;
295     }
296
297     $e->xact_commit or return $e->event;
298
299     return $carousel->id;
300 }
301
302 sub _acp_ids_to_bre_ids {
303     my ($e, $item_ids) = @_;
304     my $items = $e->search_asset_copy([
305         {id => $item_ids},
306         {flesh => 1, flesh_fields => {acp => ['call_number']}}
307     ]);
308     my @bre_ids = map { $_->call_number->record } @$items;
309     return \@bre_ids;
310 }
311
312 1;