params => [
{desc => 'Authentication token', type => 'string'},
{desc => 'lineitem ID to delete', type => 'number'},
+ {desc => 'Even delete associated copies', type => 'boolean'}
],
return => {desc => '1 on success, Event on error'}
}
params => [
{desc => 'Authentication token', type => 'string'},
{desc => 'lineitem ID to delete', type => 'number'},
+ {desc => 'Even delete associated copies', type => 'boolean'}
],
return => {desc => '1 on success, Event on error'}
}
);
+
+# Deletes one fund debit given its ID ($debit_id) *iff* it's an orphan
+# (i.e., it's not related to any of the tables that can point to a fund_debit,
+# not including the lineitem detail with ID $lid_id).
+#
+# Returns nothing on success, event on failure.
+sub delete_orphan_fund_debit {
+ my ($e, $debit_id, $lid_id) = @_;
+
+ # Make sure the debit is orphaned first.
+ my $rows = $e->json_query({
+ select => {acqfdeb => ["id"]},
+ from => {
+ acqfdeb => {
+ acqii => {
+ type => "left", field => "fund_debit", fkey => "id"
+ },
+ acqpoi => {
+ type => "left", field => "fund_debit", fkey => "id"
+ },
+ acqlid => {
+ type => "left", field => "fund_debit", fkey => "id"
+ },
+ acqda => {
+ type => "left", field => "fund_debit", fkey => "id"
+ }
+ }
+ },
+ where => {
+ "+acqfdeb" => {id => $debit_id},
+ "+acqii" => {id => undef},
+ "+acqpoi" => {id => undef},
+ "+acqda" => {id => undef},
+ "+acqlid" => {id => $lid_id},
+ }
+ }) or return $e->die_event;
+
+ if (@$rows) {
+ $e->delete_acq_fund_debit(
+ $e->retrieve_acq_fund_debit($rows->[0]->{id})
+ ) or return $e->die_event;
+ }
+
+ return; # success
+}
+
+
__PACKAGE__->register_method(
method => 'delete_lineitem',
api_name => 'open-ils.acq.picklist.lineitem.delete',
params => [
{desc => 'Authentication token', type => 'string'},
{desc => 'lineitem ID to delete', type => 'number'},
+ {desc => 'Even delete associated copies', type => 'boolean'}
],
return => {desc => '1 on success, Event on error'}
}
);
sub delete_lineitem {
- my($self, $conn, $auth, $li_id) = @_;
+ my($self, $conn, $auth, $li_id, $even_copies) = @_;
my $e = new_editor(xact=>1, authtoken=>$auth);
return $e->die_event unless $e->checkauth;
{lineitem => $li_id}, {idlist=>1});
for my $lid_id (@$lid_ids) {
- $e->delete_acq_lineitem_detail(
- $e->retrieve_acq_lineitem_detail($lid_id))
- or return $e->die_event;
+ # Be careful not to leave orphaned fund debits hanging around when
+ # lineitems are deleted.
+
+ my $lid = $e->retrieve_acq_lineitem_detail($lid_id);
+
+ if ($lid->fund_debit) {
+ my $evt = delete_orphan_fund_debit($e, $lid->fund_debit, $lid->id);
+ return $evt if $evt;
+ }
+
+ if ($lid->eg_copy_id) {
+ my $copies = $e->search_asset_copy([
+ {id => $lid->eg_copy_id, deleted => 'f'},
+ {flesh => 1, flesh_fields => {"acp" => ["call_number"]}}
+ ]) or return $e->die_event;
+
+ if (@$copies) {
+ my $copy = $copies->[0];
+
+ if (not defined $even_copies) {
+ $e->rollback;
+ return new OpenILS::Event("NO_CHANGE", payload => $copy);
+ } elsif ($even_copies) {
+ $e->allowed("DELETE_COPY", $copy->call_number->owning_lib) or
+ return $e->die_event;
+
+ $e->delete_asset_copy($copy) or return $e->die_event;
+ } # else just leave the copy alone
+ }
+ }
+
+ $e->delete_acq_lineitem_detail($lid) or return $e->die_event;
}
$e->delete_acq_lineitem($li) or return $e->die_event;
* false, the response content will be null when an event is encountered.
* @param isList If true, assume the response will be a list of data and
* check the 1st item in the list for event-ness instead of the list itself.
+ * @param eventDispatch optional dispatch table indexed by event textcode,
+ * with methods taking 1) event and 2) raw value as args.
*/
openils.Util.alertEvent = true;
- openils.Util.readResponse = function(r, eventOk, isList) {
+ openils.Util.readResponse = function(r, eventOk, isList, eventDispatch) {
var msg = r.recv();
- if(msg == null) return msg;
+ if (msg == null) return msg;
var val = msg.content();
var testval = val;
- if(isList && dojo.isArray(val))
+ if (isList && dojo.isArray(val))
testval = val[0];
- if(e = openils.Event.parse(testval)) {
- if(eventOk || e.textcode == 'SUCCESS') return e;
- console.log(e.toString());
+ if (e = openils.Event.parse(testval)) {
+ if (e.textcode != "NO_SESSION") {
+ if (eventOk || e.textcode == 'SUCCESS') {
+ return e;
+ } else if (eventDispatch && e.textcode in eventDispatch) {
+ return eventDispatch[e.textcode](e, val);
+ }
+ console.log(e.toString());
+ } else {
// session timed out. Stop propagation of requests queued by Util.onload
// and launch the XUL login dialog if possible
- var retryLogin = false;
- if(e.textcode == 'NO_SESSION') {
+ var retryLogin = false;
openils.User.authtoken = null;
if(openils.XUL.isXUL()) {
retryLogin = true;
}
}
- if(openils.Util.alertEvent && !retryLogin)
+ if (openils.Util.alertEvent && !retryLogin)
alert(e);
return null;
}
var result = openils.Util.objectProperties(indices);
+ result = result.filter(function(liId) { return typeof self.liCache[liId] != "undefined"; });
+
if (!id_only)
result = result.map(function(liId) { return self.liCache[liId]; });
);
}
- this._deleteLiList = function(list, idx) {
+ this._deleteLiList = function(list, idx, even_copies) {
if(idx == null) idx = 0;
if(idx >= list.length) return;
* confirm dialog for each one.
*/
- if (!confirm(localeStrings.DEL_LI_FROM_PO)) {
+ var preConfirmOnce = self.preConfirmLiDelete;
+ self.preConfirmLiDelete = false;
+
+ if (!preConfirmOnce && !confirm(localeStrings.DEL_LI_FROM_PO)) {
self._deleteLiList(list, ++idx); /* move on to next in list */
return;
}
fieldmapper.standardRequest(
['open-ils.acq',
- this.isPO ? 'open-ils.acq.purchase_order.lineitem.delete' : 'open-ils.acq.picklist.lineitem.delete'],
+ this.isPO ? 'open-ils.acq.purchase_order.lineitem.delete' :
+ 'open-ils.acq.picklist.lineitem.delete'],
{ async: true,
- params: [openils.User.authtoken, liId],
+ params: [openils.User.authtoken, liId, even_copies],
oncomplete: function(r) {
- self.removeLineitem(liId);
- self._deleteLiList(list, ++idx);
+ r = openils.Util.readResponse(
+ r, false, false, {
+ "NO_CHANGE": function(e, val) {
+ acqConfirmDeleteCopiesDialog.execute =
+ function(o) {
+ self.preConfirmLiDelete = true;
+ self._deleteLiList(list, idx, o.decision);
+ };
+ acqConfirmDeleteCopiesDialog.show();
+ }
+ }
+ );
+ if (r) { /* worked fine, didn't get NO_CHANGE */
+ self.removeLineitem(liId);
+ self._deleteLiList(list, ++idx, even_copies);
+ }
}
}
);