1 package OpenILS::Application::Actor::Carousel;
2 use base 'OpenILS::Application';
3 use strict; use warnings;
4 use OpenILS::Application::AppUtils;
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;
15 my $apputils = "OpenILS::Application::AppUtils";
17 my $logger = "OpenSRF::Utils::Logger";
19 sub initialize { return 1; }
21 __PACKAGE__->register_method(
22 method => "get_carousel_contents",
23 api_name => "open-ils.actor.carousel.get_contents",
26 Given a carousel ID, returns the carousel name and any publicly-visible
27 bibs from the associated bucket
31 sub get_carousel_contents {
32 my($self, $client, $id) = @_;
34 my $carousel = $e->retrieve_container_carousel($id);
37 name => $carousel->name
40 select => { bre => ['id'], rmsr => ['title','author'] },
47 join => { rmsr => { fkey => 'id', field => 'id' } }
52 '+cc' => { id => $id },
53 '+bre' => { deleted => 'f' }
55 order_by => {cbrebi => ['pos','create_time']}
57 my $r = $e->json_query($q);
62 __PACKAGE__->register_method(
63 method => "retrieve_carousels_at_org",
64 api_name => "open-ils.actor.carousel.retrieve_by_org",
67 Retrieves the IDs and override names of all carousels visible
68 at the specified org unit sorted by their sequence number at
73 sub retrieve_carousels_at_org {
74 my($self, $client, $org_id) = @_;
77 my $carousels = $e->json_query({
78 select => { ccou => ['carousel','override_name','seq'], cc => ['name'] },
80 from => { ccou => 'cc' } ,
82 '+ccou' => { org_unit => $org_id },
83 '+cc' => { active => 't' }
93 __PACKAGE__->register_method(
94 method => "retrieve_manual_carousels_for_staff",
95 api_name => "open-ils.actor.carousel.retrieve_manual_by_staff",
98 Retrieves the IDs, buckets, and names of all manually-maintained
99 carousels visible at any of the staff members working
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;
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'] },
116 $orgs = [ map { $_->{id} } @$ous ];
118 my $ous = $e->json_query({
119 select => { puwoum => ['work_ou'] },
122 '+puwoum' => { usr => $e->requestor->id }
125 $orgs = [ map { $_->{work_ou} } @$ous ];
128 my $carousels = $e->json_query({
129 select => { cc => ['id','name','bucket'] },
131 from => { cc => 'ccou' },
133 '+ccou' => { org_unit => $orgs },
134 '+cc' => { type => 1, active => 't' }, # FIXME
144 __PACKAGE__->register_method(
145 method => "refresh_carousel",
146 api_name => "open-ils.actor.carousel.refresh",
148 notes => <<" NOTES");
149 Refreshes the specified carousel
150 PARAMS(authtoken, carousel_id)
153 sub refresh_carousel {
154 my ($self, $client, $auth, $carousel_id) = @_;
156 my $e = new_editor(authtoken => $auth);
157 return $e->event unless $e->checkauth;
158 return $e->event unless $e->allowed('REFRESH_CAROUSEL');
161 $carousel = $e->retrieve_container_carousel($carousel_id) or return $e->event;
163 return $e->event unless $e->allowed('REFRESH_CAROUSEL', $carousel->owner, $carousel);
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';
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;
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;
182 my $num_updated = $U->simplereq(
184 'open-ils.storage.container.refresh_from_carousel',
187 $carousel->age_filter,
190 $carousel->max_items,
193 $carousel->last_refresh_time('now');
195 $e->update_container_carousel($carousel) or return $e->event;
196 $e->xact_commit or return $e->event;
201 __PACKAGE__->register_method(
202 method => "add_carousel_from_bucket",
203 api_name => "open-ils.actor.carousel.create.from_bucket",
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)
211 sub add_carousel_from_bucket {
212 my ($self, $client, $auth, $carousel_name, $bucket_id) = @_;
214 my $e = new_editor(authtoken => $auth);
215 return $e->event unless $e->checkauth;
216 return $e->event unless $e->allowed('ADMIN_CAROUSEL');
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 });
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;
233 $e->xact_commit or return $e->event;
235 return $carousel->id;
238 __PACKAGE__->register_method(
239 method => "create_carousel_from_items",
240 api_name => "open-ils.actor.carousel.create_carousel_from_items",
242 desc => q/Create a new carousel populated with the records connected to the requested items/,
244 { name => 'authtoken',
245 desc => 'A user authtoken',
247 { name => 'carousel_name',
248 desc => 'A name for the new carousel',
251 desc => 'Array of copy locations to filter copies by, optional and can be undef.',
256 desc => q/The id of the new carousel/
261 sub create_carousel_from_items {
262 my ($self, $client, $auth, $carousel_name, $item_ids) = @_;
264 my $e = new_editor(authtoken => $auth);
265 return $e->event unless $e->checkauth;
266 return $e->event unless $e->allowed('ADMIN_CAROUSEL');
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');
274 $bucket->owning_lib($e->requestor->ws_ou);
275 $e->create_container_biblio_record_entry_bucket($bucket) or return $e->event;
277 my $bre_ids = _acp_ids_to_bre_ids($e, $item_ids);
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;
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;
297 $e->xact_commit or return $e->event;
299 return $carousel->id;
302 sub _acp_ids_to_bre_ids {
303 my ($e, $item_ids) = @_;
304 my $items = $e->search_asset_copy([
306 {flesh => 1, flesh_fields => {acp => ['call_number']}}
308 my @bre_ids = map { $_->call_number->record } @$items;