return $item->id;
}
+__PACKAGE__->register_method(
+ method => 'batch_add_items',
+ api_name => 'open-ils.actor.container.item.create.batch',
+ stream => 1,
+ max_bundle_count => 1,
+ signature => {
+ desc => 'Add items to a bucket',
+ params => [
+ {desc => 'Auth token', type => 'string'},
+ {desc => q/
+ Container class.
+ Can be "copy", "call_number", "biblio_record_entry", or "user"'/,
+ type => 'string'},
+ {desc => 'Bucket ID', type => 'number'},
+ {desc => q/
+ Item target identifiers. E.g. for record buckets,
+ the identifier would be the bib record id/,
+ type => 'array'
+ },
+ ],
+ return => {
+ desc => 'Stream of new item Identifiers',
+ type => 'number'
+ }
+ }
+);
+
+sub batch_add_items {
+ my ($self, $client, $auth, $bucket_class, $bucket_id, $target_ids) = @_;
+
+ my $e = new_editor(authtoken => $auth, xact => 1);
+ return $e->die_event unless $e->checkauth;
+
+ my $constructor = "Fieldmapper::container::${bucket_class}_bucket_item";
+ my $create = "create_container_${bucket_class}_bucket_item";
+ my $retrieve = "retrieve_container_${bucket_class}_bucket";
+ my $column = "target_${bucket_class}";
+
+ my $bucket = $e->$retrieve($bucket_id) or return $e->die_event;
+
+ if ($bucket->owner ne $e->requestor->id) {
+ return $e->die_event unless $e->allowed('CREATE_CONTAINER_ITEM');
+ }
+
+ for my $target_id (@$target_ids) {
+
+ my $item = $constructor->new;
+ $item->bucket($bucket_id);
+ $item->$column($target_id);
+
+ return $e->die_event unless $e->$create($item);
+ $client->respond($target_id);
+ }
+
+ $e->commit;
+ return undef;
+}
+
+__PACKAGE__->register_method(
+ method => 'batch_delete_items',
+ api_name => 'open-ils.actor.container.item.delete.batch',
+ stream => 1,
+ max_bundle_count => 1,
+ signature => {
+ desc => 'Remove items from a bucket',
+ params => [
+ {desc => 'Auth token', type => 'string'},
+ {desc => q/
+ Container class.
+ Can be "copy", "call_number", "biblio_record_entry", or "user"'/,
+ type => 'string'},
+ {desc => q/
+ Item target identifiers. E.g. for record buckets,
+ the identifier would be the bib record id/,
+ type => 'array'
+ }
+ ],
+ return => {
+ desc => 'Stream of new removed target IDs',
+ type => 'number'
+ }
+ }
+);
+
+sub batch_delete_items {
+ my ($self, $client, $auth, $bucket_class, $bucket_id, $target_ids) = @_;
+
+ my $e = new_editor(authtoken => $auth, xact => 1);
+ return $e->die_event unless $e->checkauth;
+
+ my $delete = "delete_container_${bucket_class}_bucket_item";
+ my $search = "search_container_${bucket_class}_bucket_item";
+ my $retrieve = "retrieve_container_${bucket_class}_bucket";
+ my $column = "target_${bucket_class}";
+
+ my $bucket = $e->$retrieve($bucket_id) or return $e->die_event;
+
+ if ($bucket->owner ne $e->requestor->id) {
+ return $e->die_event unless $e->allowed('DELETE_CONTAINER_ITEM');
+ }
+
+ for my $target_id (@$target_ids) {
+
+ my $item = $e->$search({bucket => $bucket_id, $column => $target_id})->[0];
+ next unless $item;
+
+ return $e->die_event unless $e->$delete($item);
+ $client->respond($target_id);
+ }
+
+ $e->commit;
+ return undef;
+}
+
+
__PACKAGE__->register_method(
if (recs.length == 0) return;
bucketSvc.bucketNeedsRefresh = true;
- angular.forEach(recs,
- function(rec) {
- var item = new egCore.idl.cbrebi();
- item.bucket(bucketSvc.currentBucket.id());
- item.target_biblio_record_entry(rec.id);
- egCore.net.request(
- 'open-ils.actor',
- 'open-ils.actor.container.item.create',
- egCore.auth.token(), 'biblio', item
- ).then(function(resp) {
-
- // HACK: add the IDs of the added items so that the size
- // of the view list will grow (and update any UI looking at
- // the list size). The data stored is inconsistent, but since
- // we are forcing a bucket refresh on the next rendering of
- // the view pane, the list will be repaired.
- bucketSvc.currentBucket.items().push(resp);
- });
+ var ids = recs.map(function(rec) { return rec.id; });
+
+ egCore.net.request(
+ 'open-ils.actor',
+ 'open-ils.actor.container.item.create.batch',
+ egCore.auth.token(), 'biblio_record_entry',
+ bucketSvc.currentBucket.id(), ids
+
+ ).then(
+ null, // complete
+ null, // error
+ function(resp) {
+ // HACK: add the IDs of the added items so that the size
+ // of the view list will grow (and update any UI looking at
+ // the list size). The data stored is inconsistent, but since
+ // we are forcing a bucket refresh on the next rendering of
+ // the view pane, the list will be repaired.
+ bucketSvc.currentBucket.items().push(resp);
}
- );
+ )
}
$scope.openCreateBucketDialog = function() {
}
$scope.detachRecords = function(records) {
- var promises = [];
- angular.forEach(records, function(rec) {
- var item = bucketSvc.currentBucket.items().filter(
- function(i) {
- return (i.target_biblio_record_entry() == rec.id)
- }
- );
- if (item.length)
- promises.push(bucketSvc.detachRecord(item[0].id()));
- });
-
bucketSvc.bucketNeedsRefresh = true;
- return $q.all(promises).then(drawBucket);
+
+ var ids = records.map(function(rec) { return rec.id; });
+
+ return egCore.net.request(
+ 'open-ils.actor',
+ 'open-ils.actor.container.item.delete.batch',
+ egCore.auth.token(), 'biblio_record_entry',
+ bucketSvc.currentBucket.id(), ids
+
+ ).then(
+ null, // complete
+ null, // error
+ function(resp) {
+ // Remove the items as the API responds so the UI can show
+ // the count of items decreasing.
+ bucketSvc.currentBucket.items(
+ bucketSvc.currentBucket.items().filter(function(item) {
+ return item.target_biblio_record_entry() != resp;
+ })
+ );
+ }
+ ).then(drawBucket);
}
$scope.moveToPending = function(records) {