$li->edit_time('now');
$li->editor($mgr->editor->requestor->id);
$mgr->add_li;
- return $li if $mgr->editor->update_acq_lineitem($li);
+ return $mgr->editor->retrieve_acq_lineitem($mgr->editor->data) if
+ $mgr->editor->update_acq_lineitem($li);
return undef;
}
$mgr->add_li;
$li->state('received');
- update_lineitem($mgr, $li) or return 0;
+ $li = update_lineitem($mgr, $li) or return 0;
$mgr->post_process( sub { create_lineitem_status_events($mgr, $li_id, 'aur.received'); });
- return 1 if $skip_complete_check;
+ my $po;
+ my $result = {"li" => {$li->id => {"state" => $li->state}}};
+ return 0 unless
+ $skip_complete_check or (
+ $po = check_purchase_order_received($mgr, $li->purchase_order)
+ );
- return check_purchase_order_received($mgr, $li->purchase_order);
+ if (ref $po) {
+ $result->{"po"} = {$po->id => {"state" => $li->state}};
+ }
+ return $result;
}
sub rollback_receive_lineitem {
my $li = check_lineitem_received($mgr, $lid->lineitem) or return 0;
return 1 if $li == 1; # li not received
- return check_purchase_order_received($mgr, $li->purchase_order);
+ my $po = check_purchase_order_received($mgr, $li->purchase_order) or return 0;
+ return $li if $po == 1;
+ return $po;
}
$po->editor($mgr->editor->requestor->id);
$po->edit_time('now');
$mgr->purchase_order($po);
- return $po if $mgr->editor->update_acq_purchase_order($po);
+ return $mgr->editor->retrieve_acq_purchase_order($mgr->editor->data)
+ if $mgr->editor->update_acq_purchase_order($po);
return undef;
}
return $e->die_event unless $e->allowed(
'RECEIVE_PURCHASE_ORDER', $lid->lineitem->purchase_order->ordering_agency);
- receive_lineitem_detail($mgr, $lid_id) or return $e->die_event;
+ my $recvd = receive_lineitem_detail($mgr, $lid_id) or return $e->die_event;
+
+ # What's this business, you ask? We basically want to return a minimal
+ # set of information about what has changed as a result of the "receive
+ # lineitem detail" operation; remember: not only does the lineitem detail
+ # change state, but so might an LI and even a PO, and a good UI will want
+ # to reflect those changes.
+ $lid = $e->retrieve_acq_lineitem_detail(
+ [$lid_id, {"flesh" => 1, "flesh_fields" => {"acqlid" => ["lineitem"]}}]
+ );
+ my $result = {"lid" => {$lid->id => {"recv_time" => $lid->recv_time}}};
+
+ if (ref $recvd) {
+ if ($recvd->class_name =~ /::purchase_order/) {
+ $result->{"po"} = {"id" => $recvd->id, "state" => $recvd->state};
+ $result->{"li"} = {
+ $lid->lineitem->id => {"state" => $lid->lineitem->state}
+ };
+ } elsif ($recvd->class_name =~ /::lineitem/) {
+ $result->{"li"} = {$recvd->id => {"state" => $recvd->state}};
+ }
+ }
+
$e->commit;
- return 1;
+ return $result;
}
__PACKAGE__->register_method(
{desc => 'Authentication token', type => 'string'},
{desc => 'lineitem detail ID', type => 'number'}
],
- return => {desc => '1 on success, Event on error'}
+ return => {desc =>
+ "on success, object containing an LI and possibly a PO; " .
+ "on error, event"
+ }
}
);
return $e->die_event unless $e->allowed(
'RECEIVE_PURCHASE_ORDER', $li->purchase_order->ordering_agency);
- receive_lineitem($mgr, $li_id) or return $e->die_event;
-
+ my $res = receive_lineitem($mgr, $li_id) or return $e->die_event;
$e->commit;
- $conn->respond_complete(1);
+ $conn->respond_complete($res);
$mgr->run_post_response_hooks;
- return undef;
}
method => 'rollback_receive_lineitem_detail_api',
api_name => 'open-ils.acq.lineitem_detail.receive.rollback',
signature => {
- desc => 'Mark a lineitem_detail as received',
+ desc => 'Mark a lineitem_detail as Un-received',
params => [
{desc => 'Authentication token', type => 'string'},
{desc => 'lineitem detail ID', type => 'number'}
my $po = $li->purchase_order;
return $e->die_event unless $e->allowed('RECEIVE_PURCHASE_ORDER', $po->ordering_agency);
- rollback_receive_lineitem_detail($mgr, $lid_id) or return $e->die_event;
- $li->state('on-order');
- $po->state('on-order');
- udpate_lineitem($mgr, $li) or return $e->die_event;
- udpate_purchase_order($mgr, $po) or return $e->die_event;
+ my $result = {};
- $e->commit;
- return 1;
+ my $recvd = rollback_receive_lineitem_detail($mgr, $lid_id)
+ or return $e->die_event;
+
+ if (ref $recvd) {
+ $result->{"lid"} = {$recvd->id => {"recv_time" => $recvd->recv_time}};
+ } else {
+ $result->{"lid"} = {$lid->id => {"recv_time" => $lid->recv_time}};
+ }
+
+ if ($li->state eq "received") {
+ $li->state("on-order");
+ $li = update_lineitem($mgr, $li) or return $e->die_event;
+ $result->{"li"} = {$li->id => {"state" => $li->state}};
+ }
+
+ if ($po->state eq "received") {
+ $po->state("on-order");
+ $po = update_purchase_order($mgr, $po) or return $e->die_event;
+ $result->{"po"} = {$po->id => {"state" => $po->state}};
+ }
+
+ $e->commit and return $result or return $e->die_event;
}
__PACKAGE__->register_method(
{desc => 'Authentication token', type => 'string'},
{desc => 'lineitem detail ID', type => 'number'}
],
- return => {desc => '1 on success, Event on error'}
+ return => {desc => 'altered objects on success, event on error'}
}
);
return $e->die_event unless $e->checkauth;
my $mgr = OpenILS::Application::Acq::BatchManager->new(editor => $e, conn => $conn);
- my $li = $e->retrieve_acq_lineitem_detail([
+ my $li = $e->retrieve_acq_lineitem([
$li_id, {
- flesh => 1,
- flesh_fields => {
- jub => ['purchase_order']
- }
+ "flesh" => 1, "flesh_fields" => {"jub" => ["purchase_order"]}
}
]);
my $po = $li->purchase_order;
return $e->die_event unless $e->allowed('RECEIVE_PURCHASE_ORDER', $po->ordering_agency);
- rollback_receive_lineitem($mgr, $li_id) or return $e->die_event;
+ $li = rollback_receive_lineitem($mgr, $li_id) or return $e->die_event;
- $po->state('on-order');
- update_purchase_order($mgr, $po) or return $e->die_event;
+ my $result = {"li" => {$li->id => {"state" => $li->state}}};
+ if ($po->state eq "received") {
+ $po->state("on-order");
+ $po = update_purchase_order($mgr, $po) or return $e->die_event;
+ $result->{"po"} = {$po->id => {"state" => $po->state}};
+ }
- $e->commit;
- return 1;
+ $e->commit and return $result or return $e->die_event;
}
var classList = node.className.split(/\s+/);
var className = '';
for(var i = 0; i < classList.length; i++) {
- if (classList[i] != cls) {
- if(i == 0)
- className = classList[i];
- else
- className += ' ' + classList[i];
+ if (typeof(cls) == "object") { /* assume regex */
+ if (!cls.test(classList[i])) {
+ if(i == 0)
+ className = classList[i];
+ else
+ className += ' ' + classList[i];
+ }
+ } else {
+ if (classList[i] != cls) {
+ if(i == 0)
+ className = classList[i];
+ else
+ className += ' ' + classList[i];
+ }
}
}
node.className = className;
document.body.removeChild(audio);
}
+ /**
+ * Return the properties of an object as a list. Saves typing.
+ */
+ openils.Util.objectProperties = function(obj) {
+ var K = [];
+ for (var k in obj) K.push(k);
+ return K;
+ }
+
}
'NO_RESULTS': "No results.",
'EXPORT_SAVE_DIALOG_TITLE': "Save field values to a file",
'EXPORT_SHORT_LIST': "Not all of the selected items had the attribute '${0}'.\nChoose OK to save those values that could be found.",
- 'EXPORT_EMPTY_LIST': "No values for attribute '${0}' found."
+ 'EXPORT_EMPTY_LIST': "No values for attribute '${0}' found.",
+ 'UNRECEIVE_LI': "Are you sure you want to mark this lineitem as UN-received?"
}
// lineitem state
nodeByName('li_state', row).innerHTML = li.state(); // TODO i18n state labels
- openils.Util.addCSSClass(row, 'oils-acq-li-state-' + li.state());
-
// lineitem price
var priceInput = dojo.query('[name=price]', row)[0];
var priceData = liWrapper.getPrice();
priceInput.value = (priceData) ? priceData.price : '';
priceInput.onchange = function() { self.updateLiPrice(priceInput, li) };
- var recv_link = dojo.query('[name=receive_link]', row)[0];
-
- if(li.state() == 'on-order') {
- recv_link.onclick = function() {
- self.receiveLi(li);
- openils.Util.hide(recv_link)
- }
- } else {
- openils.Util.hide(recv_link);
- }
-
- // TODO we should allow editing before receipt, in which case the
- // test should be "if 1 or more real (acp) copies exist
- if(li.state() == 'received') {
- var real_copies_link = dojo.query('[name=real_copies_link]', row)[0];
- openils.Util.show(real_copies_link);
- real_copies_link.onclick = function() {
- self.showRealCopies(li);
- }
- }
+ // show either "mark received" or "unreceive" as appropriate
+ this.updateReceivedness(li, row);
if (!skip_final_placement) {
self.tbody.appendChild(row);
}
};
+ this.updateReceivedness = function(li, row) {
+ if (typeof(row) == "undefined")
+ row = dojo.query('tr[li="' + li.id() + '"]', "acq-lit-tbody")[0];
+
+ var recv_link = nodeByName("receive_link", row);
+ var unrecv_link = nodeByName("unreceive_link", row);
+ var real_copies_link = nodeByName("real_copies_link", row);
+
+ /* handle row coloring for based on LI state */
+ openils.Util.removeCSSClass(row, /^oils-acq-li-state-/);
+ openils.Util.addCSSClass(row, "oils-acq-li-state-" + li.state());
+
+ /* handle links that appear/disappear based on whether LI is received */
+ if (this.isPO) {
+ var self = this;
+ switch(li.state()) {
+ case "on-order":
+ openils.Util.hide(real_copies_link);
+ openils.Util.hide(unrecv_link);
+ openils.Util.show(recv_link, "inline");
+ if (typeof(recv_link.onclick) != "function")
+ recv_link.onclick = function() { self.receiveLi(li); };
+ return;
+ case "received":
+ openils.Util.hide(recv_link);
+ openils.Util.show(unrecv_link, "inline");
+ if (typeof(unrecv_link.onclick) != "function") {
+ unrecv_link.onclick = function() {
+ if (confirm(localeStrings.UNRECEIVE_LI))
+ self.unReceiveLi(li);
+ };
+ }
+ // TODO we should allow editing before receipt, in which case the
+ // test should be "if 1 or more real (acp) copies exist
+ openils.Util.show(real_copies_link);
+ real_copies_link.onclick = function() {
+ self.showRealCopies(li);
+ }
+ return;
+ }
+ }
+
+ openils.Util.hide(recv_link);
+ openils.Util.hide(unrecv_link);
+ openils.Util.hide(real_copies_link);
+ };
+
+
/**
* Draws and shows the lineitem notes pane
*/
}
this.receiveLi = function(li) {
- if(!this.isPO) return;
+ /* (For now) there shall be no marking LIs received except from the
+ * actual "view PO" interface. */
+ if (!this.isPO) return;
+
+ var self = this;
progressDialog.show(true);
fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem.receive'],
- { async: true,
- params: [this.authtoken, li.id()],
- onresponse : function(r) {
- var resp = openils.Util.readResponse(r);
+ ["open-ils.acq", "open-ils.acq.lineitem.receive"], {
+ "async": true,
+ "params": [this.authtoken, li.id()],
+ "onresponse": function(r) {
+ self.handleReceiveOrRollback(openils.Util.readResponse(r));
+ },
+ "oncomplete": function() {
progressDialog.hide();
+ }
+ }
+ );
+ }
+
+ this.handleReceiveOrRollback = function(resp) {
+ if (resp) {
+ if (resp.li) {
+ for (var li_id in resp.li) {
+ for (var key in resp.li[li_id])
+ self.liCache[li_id][key](resp.li[li_id][key]);
+ self.updateReceivedness(self.liCache[li_id]);
+ }
+ }
+ if (resp.po) {
+ if (typeof(self.poUpdateCallback) == "function")
+ self.poUpdateCallback(resp.po);
+ }
+ }
+ }
+
+ this.unReceiveLi = function(li) {
+ /* (For now) there shall be no marking LIs un-received except from the
+ * actual "view PO" interface. */
+ if (!this.isPO) return;
+
+ var self = this;
+ progressDialog.show(true);
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.lineitem.receive.rollback"], {
+ "async": true,
+ "params": [this.authtoken, li.id()],
+ "onresponse": function(r) {
+ self.handleReceiveOrRollback(openils.Util.readResponse(r));
},
+ "oncomplete": function() {
+ progressDialog.hide();
+ }
}
);
}
var PO = null;
var liTable;
+function updatePoState(po_info) {
+ var data = po_info[PO.id()];
+ if (data && data.state) {
+ PO.state(data.state);
+ dojo.byId("acq-po-view-state").innerHTML = PO.state(); // TODO i18n
+ }
+}
+
function init() {
liTable = new AcqLiTable();
liTable.reset();
liTable.isPO = poId;
+ liTable.poUpdateCallback = updatePoState;
fieldmapper.standardRequest(
['open-ils.acq', 'open-ils.acq.purchase_order.retrieve'],
</table>
</td>
<td><a class='hidden' name='real_copies_link' href='javascript:void(0);'>Update Barcodes</a></td>
- <td><a name='receive_link' href='javascript:void(0);'>Mark Received</a></td>
+ <td><a name='receive_link' href='javascript:void(0);'>Mark Received</a><a name='unreceive_link' href='javascript:void(0);'>Unreceive</a></td>
+ </td>
<td><a name='copieslink' href='javascript:void(0);'>Copies(<span name='count'>0</span>)</a></td>
<td>
<a name='noteslink' href='javascript:void(0);'