"params" => [
{"desc" => "Search token", "type" => "string"},
{"desc" => "Options: require_subscriptions, add_mvr, is_actual_id" .
- " (all boolean)", "type" => "object"}
+ ", id_list (all boolean)", "type" => "object"}
],
"return" => {
"desc" => "Any matching BREs, or if the add_mvr option is true, " .
$e->disconnect;
return undef;
}
+
+ if ($options->{"id_list"}) {
+ $e->disconnect;
+ $client->respond($_) foreach (@ids);
+ return undef;
+ }
}
my $bre = $e->search_biblio_record_entry([
undef;
}
+# All these _clone_foo() functions could possibly have been consolidated into
+# one clever function, but it's faster to get things working this way.
+sub _clone_subscription {
+ my ($sub, $bib_id, $e) = @_;
+
+ # clone sub itself
+ my $new_sub = $sub->clone;
+ $new_sub->record_entry(int $bib_id) if $bib_id;
+ $new_sub->clear_id;
+ $new_sub->clear_distributions;
+ $new_sub->clear_notes;
+ $new_sub->clear_scaps;
+
+ $e->create_serial_subscription($new_sub) or return $e->die_event;
+
+ my $new_sub_id = $e->data->id;
+ # clone dists
+ foreach my $dist (@{$sub->distributions}) {
+ my $r = _clone_distribution($dist, $new_sub_id, $e);
+ return $r if $U->event_code($r);
+ }
+
+ # clone sub notes
+ foreach my $note (@{$sub->notes}) {
+ my $r = _clone_subscription_note($note, $new_sub_id, $e);
+ return $r if $U->event_code($r);
+ }
+
+ # clone scaps
+ foreach my $scap (@{$sub->scaps}) {
+ my $r = _clone_caption_and_pattern($scap, $new_sub_id, $e);
+ return $r if $U->event_code($r);
+ }
+
+ return $new_sub_id;
+}
+
+sub _clone_distribution {
+ my ($dist, $sub_id, $e) = @_;
+
+ my $new_dist = $dist->clone;
+ $new_dist->clear_id;
+ $new_dist->clear_notes;
+ $new_dist->clear_streams;
+ $new_dist->subscription($sub_id);
+
+ $e->create_serial_distribution($new_dist) or return $e->die_event;
+ my $new_dist_id = $e->data->id;
+
+ # clone streams
+ foreach my $stream (@{$dist->streams}) {
+ my $r = _clone_stream($stream, $new_dist_id, $e);
+ return $r if $U->event_code($r);
+ }
+
+ # clone distribution notes
+ foreach my $note (@{$dist->notes}) {
+ my $r = _clone_distribution_note($note, $new_dist_id, $e);
+ return $r if $U->event_code($r);
+ }
+
+ return $new_dist_id;
+}
+
+sub _clone_subscription_note {
+ my ($note, $sub_id, $e) = @_;
+
+ my $new_note = $note->clone;
+ $new_note->clear_id;
+ $new_note->creator($e->requestor->id);
+ $new_note->create_date("now");
+ $new_note->subscription($sub_id);
+
+ $e->create_serial_subscription_note($new_note) or return $e->die_event;
+ return $e->data->id;
+}
+
+sub _clone_caption_and_pattern {
+ my ($scap, $sub_id, $e) = @_;
+
+ my $new_scap = $scap->clone;
+ $new_scap->clear_id;
+ $new_scap->subscription($sub_id);
+
+ $e->create_serial_caption_and_pattern($new_scap) or return $e->die_event;
+ return $e->data->id;
+}
+
+sub _clone_distribution_note {
+ my ($note, $dist_id, $e) = @_;
+
+ my $new_note = $note->clone;
+ $new_note->clear_id;
+ $new_note->creator($e->requestor->id);
+ $new_note->create_date("now");
+ $new_note->distribution($dist_id);
+
+ $e->create_serial_distribution_note($new_note) or return $e->die_event;
+ return $e->data->id;
+}
+
+sub _clone_stream {
+ my ($stream, $dist_id, $e) = @_;
+
+ my $new_stream = $stream->clone;
+ $new_stream->clear_id;
+ $new_stream->clear_routing_list_users;
+ $new_stream->distribution($dist_id);
+
+ $e->create_serial_stream($new_stream) or return $e->die_event;
+ my $new_stream_id = $e->data->id;
+
+ # clone routing list users
+ foreach my $user (@{$stream->routing_list_users}) {
+ my $r = _clone_routing_list_user($user, $new_stream_id, $e);
+ return $r if $U->event_code($r);
+ }
+
+ return $new_stream_id;
+}
+
+sub _clone_routing_list_user {
+ my ($user, $stream_id, $e) = @_;
+
+ my $new_user = $user->clone;
+ $new_user->clear_id;
+ $new_user->stream($stream_id);
+
+ $e->create_serial_routing_list_user($new_user) or return $e->die_event;
+ return $e->data->id;
+}
+
+__PACKAGE__->register_method(
+ "method" => "clone_subscription",
+ "api_name" => "open-ils.serial.subscription.clone",
+ "signature" => {
+ "desc" => q{Clone a subscription, including its attending distributions,
+ streams, captions and patterns, routing list users, distribution
+ notes and subscription notes. Do not include holdings-specific
+ things, like issuances, items, units, summaries. Attach the
+ clone either to the same bib record as the original, or to one
+ specified by ID.},
+ "params" => [
+ {"desc" => "Authtoken", "type" => "string"},
+ {"desc" => "Subscription ID", "type" => "number"},
+ {"desc" => "Bib Record ID (optional)", "type" => "number"}
+ ],
+ "return" => {
+ "desc" => "ID of the new subscription", "type" => "number"
+ }
+ }
+);
+
+sub clone_subscription {
+ my ($self, $client, $auth, $sub_id, $bib_id) = @_;
+
+ my $e = new_editor("authtoken" => $auth, "xact" => 1);
+ return $e->die_event unless $e->checkauth;
+
+ my $sub = $e->retrieve_serial_subscription([
+ int $sub_id, {
+ "flesh" => 3,
+ "flesh_fields" => {
+ "ssub" => [qw/distributions notes scaps/],
+ "sdist" => [qw/streams notes/],
+ "sstr" => ["routing_list_users"]
+ }
+ }
+ ]) or return $e->die_event;
+
+ # ADMIN_SERIAL_SUBSCRIPTION will have to be good enough as a
+ # catch-all permisison for this operation.
+ return $e->die_event unless
+ $e->allowed("ADMIN_SERIAL_SUBSCRIPTION", $sub->owning_lib);
+
+ my $result = _clone_subscription($sub, $bib_id, $e);
+
+ return $e->die_event($result) if $U->event_code($result);
+
+ $e->commit or return $e->die_event;
+ return $result;
+}
+
1;
}
}
+function toggle_clone_ident_field(dij) {
+ setTimeout(
+ function() {
+ var disabled = !dij.attr("checked");
+ clone_ident.attr("disabled", disabled);
+ if (!disabled) clone_ident.focus();
+ }, 175
+ );
+}
+
+function clone_subscription(form) {
+ if (form.use_ident == "yes") {
+ fieldmapper.standardRequest(
+ ["open-ils.serial",
+ "open-ils.serial.biblio.record_entry.by_identifier.atomic"], {
+ "params": [form.ident, {"id_list": true}],
+ "async": true,
+ "oncomplete": function(r) {
+ r = openils.Util.readResponse(r);
+ if (!r || !r.length) {
+ alert("No matches for that indentifier."); /*XXX i18n*/
+ } else if (r.length != 1) {
+ alert("Too many matches for that identifier. Use a " +
+ "unique identifier."); /* XXX i18n */
+ } else {
+ _clone_subscription(r[0]);
+ }
+ }
+ }
+ );
+ } else {
+ _clone_subscription();
+ }
+}
+
+function _clone_subscription(bre_id) {
+ progress_dialog.show(true);
+
+ fieldmapper.standardRequest(
+ ["open-ils.serial", "open-ils.serial.subscription.clone"], {
+ "params": [openils.User.authtoken, sub_id, bre_id],
+ "async": false,
+ "oncomplete": function(r) {
+ progress_dialog.hide();
+ if (!(r = openils.Util.readResponse(r))) {
+ alert("Error cloning subscription."); /* XXX i18n */
+ } else {
+ location.href =
+ oilsBasePath + "/serial/subscription?id=" + r;
+ }
+ }
+ }
+ );
+}
+
openils.Util.addOnLoad(
function() {
var tab_dispatch = {
<div dojoType="dijit.layout.ContentPane" layout="top" class="oils-header-panel">
<div>Subscription Details</div>
<div>
+ <span dojoType="dijit.form.Button" onClick="clone_dialog.show();">
+ Clone Subscription
+ </span>
<span dojoType="dijit.form.Button" onClick="open_batch_receive();">
Batch Item Receive
</span>
</div>
<div class="hidden">
<div dojoType="openils.widget.ProgressDialog" jsId="progress_dialog"></div>
+ <div dojoType="dijit.Dialog" jsId="clone_dialog" title="Clone Subscription"
+ style="width: 460px;" execute="clone_subscription(arguments[0]);">
+ <div style="margin-bottom: 0.5em;">
+ This feature will clone a subscription and all of its subscription
+ notes, distributions, distribution notes, captions and patterns,
+ streams, and routing list users.</div>
+ <div style="margin-bottom: 0.5em;">
+ Holdings-related objects, like issuances, items, units, and
+ summaries will <em>not</em> be cloned.
+ </div>
+ <div style="margin-bottom: 0.5em;">
+ To what bibliographic record should the new subscription be
+ attached?
+ </div>
+ <table width="100%">
+ <tr>
+ <td style="padding-right: 0.5em; vertical-align: top;">
+ <input dojoType="dijit.form.RadioButton"
+ id="use_ident_no" name="use_ident" value="no"
+ checked="checked" />
+ </td>
+ <td>
+ <label for="use_ident_no">
+ Same record as the existing subscription
+ </label>
+ </td>
+ </tr>
+ <tr>
+ <td style="padding-right: 0.5em; vertical-align: top;">
+ <input dojoType="dijit.form.RadioButton"
+ onChange="toggle_clone_ident_field(this);"
+ id="use_ident_yes" name="use_ident" value="yes" />
+ </td>
+ <td>
+ <label for="use_ident_yes">
+ Record specified by this unique identifier:
+ </label>
+ <input dojoType="dijit.form.TextBox" name="ident"
+ jsId="clone_ident" disabled="true"
+ style="margin-left: 0.5em; width: 10em;" />
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" align="center">
+ <span dojoType="dijit.form.Button" type="submit">
+ Clone!
+ </span>
+ </td>
+ </tr>
+ </table>
+ </div>
</div>
[% END %]