use OpenSRF::EX qw/:try/;
use strict; use warnings;
+# empirically derived number of responses we can
+# stream back before the XUL client has indigestion
+use constant MAX_RESPONSES => 20;
+
sub new {
my($class, %args) = @_;
my $self = bless(\%args, $class);
};
$self->{cache} = {};
$self->throttle(4) unless $self->throttle;
+ $self->exponential_falloff(1) unless $self->exponential_falloff;
$self->{post_proc_queue} = [];
$self->{last_respond_progress} = 0;
return $self;
$self->{throttle} = $val if $val;
return $self->{throttle};
}
+sub exponential_falloff {
+ my($self, $val) = @_;
+ $self->{exponential_falloff} = $val if defined $val;
+ return $self->{exponential_falloff};
+}
sub respond {
my($self, %other_args) = @_;
if($self->throttle and not %other_args) {
}
$self->conn->respond({ %{$self->{args}}, %other_args });
$self->{last_respond_progress} = $self->{args}->{progress};
- $self->throttle($self->throttle * 2) unless $self->throttle >= 256;
+ $self->throttle($self->throttle * 2) if ($self->exponential_falloff() and $self->throttle < 256);
}
sub respond_complete {
my($self, %other_args) = @_;
my($self, $val) = @_;
$self->{args}->{total} = $val if defined $val;
$self->{args}->{maximum} = $self->{args}->{total};
+ if ($self->{args}->{maximum}) {
+ # if a total has been set, space responses linearly
+ $self->exponential_falloff(0);
+ $self->throttle(int($self->{args}->{maximum} / MAX_RESPONSES));
+ $self->throttle(4) if $self->throttle < 4;
+ }
return $self->{args}->{total};
}
sub purchase_order {
where => {'+acqpo' => {id => $po_id}}
})->[0]->{id};
- $mgr->total(scalar(@$li_ids) + $lid_total);
+ # maximum number of Vandelay bib actions is twice
+ # the number line items (queue bib, then create it)
+ $mgr->total(scalar(@$li_ids) * 2 + $lid_total);
create_lineitem_list_assets($mgr, $li_ids, $args->{vandelay})
or return $e->die_event;
"DUPE_PO_NAME_MSG" : "This name is already in use by another PO",
"DUPE_PO_NAME_LINK" : "View PO",
"PO_NAME_OPTIONAL" : "${0} (optional)",
- "LI_EXISTING_COPIES" : "There are ${0} existing copies for this bibliographic record at this location"
+ "LI_EXISTING_COPIES" : "There are ${0} existing copies for this bibliographic record at this location",
+ "LI_CREATING_ASSETS" : "Creating bib, call number, and copy records...",
+ "PO_ACTIVATING" : "Activating purchase order...",
+ "ACTIVATE_LI_PROCESSED" : "Lineitems Processed: ${0}",
+ "ACTIVATE_VQBR_PROCESSED" : "Vandelay Records Processed: ${0}",
+ "ACTIVATE_BIBS_PROCESSED" : "Bib Records Merged/Imported: ${0}",
+ "ACTIVATE_LID_PROCESSED" : "ACQ Copies Processed: ${0}",
+ "ACTIVATE_DEBITS_ACCRUED_PROCESSED" : "Debits Encumbered: ${0}",
+ "ACTIVATE_COPIES_PROCESSED" : "Real Copies Processed: ${0}"
}
}
this.inherited(arguments);
+ },
+
+ update_message : function(msg) {
+ if(msg || (msg = this.message) ) {
+ if(!this.msgDiv) {
+ this.msgDiv = dojo.create('div', {innerHTML : msg});
+ this.containerNode.insertBefore(this.msgDiv, this.progress.domNode);
+ } else {
+ this.msgDiv.innerHTML = msg;
+ }
+ } else {
+ if(this.msgDiv) {
+ this.containerNode.removeChild(this.msgDiv);
+ this.msgDiv = null;
+ }
+ }
}
}
);
}
);
this.vlAgent = new VLAgent();
+ this.batchProgress = {};
if (dojo.byId('acq-lit-apply-idents')) {
dojo.byId('acq-lit-apply-idents').onclick = function() {
this.show('acq-lit-progress-numbers');
var self = this;
var vlArgs = (noVl) ? {} : {vandelay : this.vlAgent.values()};
+ this.batchProgress = {};
+ progressDialog.show(false);
+ progressDialog.attr("title", localeStrings.LI_CREATING_ASSETS);
fieldmapper.standardRequest(
['open-ils.acq', 'open-ils.acq.purchase_order.assets.create'],
{ async: true,
params: [this.authtoken, this.isPO, vlArgs],
onresponse: function(r) {
var resp = openils.Util.readResponse(r);
- self._updateProgressNumbers(resp, !Boolean(onAssetsCreated), onAssetsCreated);
+ self._updateProgressNumbers(resp, !Boolean(onAssetsCreated), onAssetsCreated, true);
}
}
);
);
};
- this._updateProgressNumbers = function(resp, reloadOnComplete, onComplete) {
+ this._updateProgressNumbers = function(resp, reloadOnComplete, onComplete, clearProgressDialog) {
+ this._updateProgressDialog(resp);
this.vlAgent.handleResponse(resp,
function(resp, res) {
+ if (clearProgressDialog) {
+ progressDialog.update({ "progress": 100});
+ progressDialog.update_message();
+ progressDialog.hide();
+ progressDialog.attr("title", "");
+ }
if(reloadOnComplete)
location.href = location.href;
if (onComplete)
);
}
+ this._updateProgressDialog = function(resp) {
+ progressDialog.update({ "progress": (resp.progress / resp.total) * 100 });
+ var keys = ['li', 'vqbr', 'bibs', 'lid', 'debits_accrued', 'copies'];
+ for (var i = 0; i < keys.length; i++) {
+ if (resp[keys[i]] > (this.batchProgress[keys[i]] || 0)) {
+ progressDialog.update_message(
+ dojo.string.substitute(
+ localeStrings["ACTIVATE_" + keys[i].toUpperCase() + "_PROCESSED"],
+ [ resp[keys[i]] ]
+ )
+ );
+ }
+ }
+ this.batchProgress = resp;
+ }
this._createPO = function(fields) {
var wantall = (fields.create_from == "all");
var want_refresh = false;
progressDialog.show(true);
+ progressDialog.attr("title", localeStrings.PO_ACTIVATING);
fieldmapper.standardRequest(
["open-ils.acq", "open-ils.acq.purchase_order.activate"], {
"async": true,
}
],
"onresponse": function(r) {
- progressDialog.hide();
activatePoButton.attr("disabled", false);
want_refresh = Boolean(openils.Util.readResponse(r));
},
"oncomplete": function() {
+ progressDialog.hide();
+ progressDialog.attr("title", "");
if (want_refresh)
location.href = location.href;
}