From: Bill Erickson Date: Wed, 29 Oct 2014 21:05:08 +0000 (-0400) Subject: Ports KCLSUPGRAD-6 - Creating PO from Acq brief record X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=208f6eb124dabb439f8320a5217085976d1716bf;p=working%2FEvergreen.git Ports KCLSUPGRAD-6 - Creating PO from Acq brief record Cross-port: 219b41c --- diff --git a/KCLS/openils/var/templates_kcls/acq/common/li_table.tt2 b/KCLS/openils/var/templates_kcls/acq/common/li_table.tt2 new file mode 100644 index 0000000000..3e213f672d --- /dev/null +++ b/KCLS/openils/var/templates_kcls/acq/common/li_table.tt2 @@ -0,0 +1,579 @@ + + + + +
+ + + + [% INCLUDE "acq/common/info.tt2" which = "Lit" %] + + + [% INCLUDE "acq/common/notes.tt2" which = "Lit" %] + + + + + + + + + + + + [% PROCESS 'acq/common/vlagent.tt2' %] + + + + + + + + +
+ + + + + + + +
+ + + + +
+ + +
+
+ + + + +
+ diff --git a/KCLS/openils/var/templates_kcls/acq/po/view.tt2 b/KCLS/openils/var/templates_kcls/acq/po/view.tt2 new file mode 100644 index 0000000000..9e15172b87 --- /dev/null +++ b/KCLS/openils/var/templates_kcls/acq/po/view.tt2 @@ -0,0 +1,160 @@ +[% WRAPPER 'base.tt2' %] +[% ctx.page_title = l("Purchase Order") %] +
+
+
+
+ + [% l('Purchase Order ([_1])', '') %] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
[% l('ID') %][% l('Prepayment Required?') %]
[% l('Name') %][% l('Activatable?') %] + + +
[% l('Provider') %][% l('Notes') %] + +
[% l('Total Lineitems') %][% l('EDI Messages') %] + +
[% l('Total Estimated') %][% l('$[_1]', '') %][% l('History') %] + +
[% l('Total Encumbered') %][% l('$[_1]', '') %]
[% l('Total Spent') %][% l('$[_1]', '') %] + + +
+ + +
+ +
+
+
+ + + + + [% INCLUDE 'acq/common/li_table.tt2' %] + [% INCLUDE "acq/common/notes.tt2" which = "Po" %] + + [% INCLUDE "acq/po/item_table.tt2" %] +
+[% END %] diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm index 331baf2dc1..decc68ecb9 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm @@ -343,6 +343,7 @@ sub delete_lineitem { sub create_lineitem_list_assets { my($mgr, $li_ids, $vandelay, $bib_only) = @_; + my $noVl = $vandelay->{noVl}; # Do not create line items if none are specified return {} unless (scalar(@$li_ids)); @@ -351,19 +352,33 @@ sub create_lineitem_list_assets { return undef; } - my $res = import_li_bibs_via_vandelay($mgr, $li_ids, $vandelay); - return undef unless $res; - return $res if $bib_only; - - # create the bibs/volumes/copies for the successfully imported records - for my $li_id (@{$res->{li_ids}}) { - $mgr->editor->xact_begin; - my $data = create_lineitem_assets($mgr, $li_id) or return undef; - $mgr->editor->xact_commit; - $mgr->respond; + if ($noVl) + { + # No Vandelay, From EG 2_1 + # create the bibs/volumes/copies and ingest the records + for my $li_id (@$li_ids) { + $mgr->editor->xact_begin; + my $data = create_lineitem_assets($mgr, $li_id, $noVl) or return undef; + $mgr->editor->xact_commit; + $mgr->respond; + } + return $li_ids; + } + else + { + my $res = import_li_bibs_via_vandelay($mgr, $li_ids, $vandelay); + return undef unless $res; + return $res if $bib_only; + + # create the bibs/volumes/copies for the successfully imported records + for my $li_id (@{$res->{li_ids}}) { + $mgr->editor->xact_begin; + my $data = create_lineitem_assets($mgr, $li_id) or return undef; + $mgr->editor->xact_commit; + $mgr->respond; + } + return $res; } - - return $res; } sub test_vandelay_import_args { @@ -1255,7 +1270,7 @@ sub check_purchase_order_received { # ---------------------------------------------------------------------------- sub create_lineitem_assets { - my($mgr, $li_id) = @_; + my($mgr, $li_id, $noVl) = @_; my $evt; my $li = $mgr->editor->retrieve_acq_lineitem([ @@ -1264,6 +1279,15 @@ sub create_lineitem_assets { flesh_fields => {jub => ['purchase_order', 'attributes']} } ]) or return 0; + # ----------------------------------------------------------------- + # If not using Vandelay, create the bib record if necessary + # ----------------------------------------------------------------- + if ($noVl) { + unless($li->eg_bib_id) { + create_bib($mgr, $li) or return 0; + $logger->info("acq-noVl: created bib for acq lineitem $li"); + } + } # note: at this point, the bib record this LI links to should already be created @@ -1307,6 +1331,28 @@ sub create_lineitem_assets { return { li => $li }; } +sub create_bib { + my($mgr, $li) = @_; + + my $record = OpenILS::Application::Cat::BibCommon->biblio_record_xml_import( + $mgr->editor, + $li->marc, + undef, # bib source + undef, + 1, # override tcn collisions + ); + + if($U->event_code($record)) { + $mgr->editor->event($record); + $mgr->editor->rollback; + return 0; + } + + $li->eg_bib_id($record->id); + $mgr->add_bib; + return update_lineitem($mgr, $li); +} + sub create_volume { my($mgr, $li, $lid) = @_; diff --git a/Open-ILS/web/js/ui/kcls/acq/common/li_table.js b/Open-ILS/web/js/ui/kcls/acq/common/li_table.js new file mode 100644 index 0000000000..d299ef44aa --- /dev/null +++ b/Open-ILS/web/js/ui/kcls/acq/common/li_table.js @@ -0,0 +1,3489 @@ +dojo.require('dojo.date.locale'); +dojo.require('dojo.date.stamp'); +dojo.require('dijit.form.Button'); +dojo.require('dijit.form.TextBox'); +dojo.require('dijit.form.FilteringSelect'); +dojo.require('dijit.form.Textarea'); +dojo.require('dijit.Tooltip'); +dojo.require('dijit.ProgressBar'); +dojo.require('dojox.timing.doLater'); +dojo.require('openils.acq.Lineitem'); +dojo.require('openils.acq.PO'); +dojo.require('openils.acq.Picklist'); +dojo.require('openils.widget.AutoFieldWidget'); +dojo.require('dojo.data.ItemFileReadStore'); +dojo.require('openils.widget.ProgressDialog'); +dojo.require('openils.PermaCrud'); +dojo.require("openils.widget.PCrudAutocompleteBox"); +dojo.require('dijit.form.ComboBox'); +dojo.require('openils.CGI'); + +if (!localeStrings) { /* we can do this because javascript doesn't have block scope */ + dojo.requireLocalization('openils.acq', 'acq'); + var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq'); +} +const XUL_OPAC_WRAPPER = 'chrome://open_ils_staff_client/content/cat/opac.xul'; +var li_exportable_attrs = ["issn", "isbn", "upc"]; + +var fundLabelFormat = [ + '${1} (${2})', 'id', 'code', 'year' +]; +var fundSearchFormat = ['${0} (${1})', 'code', 'year']; + +function nodeByName(name, context) { + return dojo.query('[name='+name+']', context)[0]; +} + +// for caching linked users. e.g. lineitem_detail.receiver +var userCache = {}; + +var liDetailBatchFields = ['fund', 'owning_lib', 'location', 'collection_code', 'circ_modifier', 'cn_label']; +var liDetailFields = liDetailBatchFields.concat(['barcode', 'note']); +var fundStyles = { + "stop": "color: #c00; font-weight: bold;", + "warning": "color: #c93;" +}; + +function AcqLiTable() { + + var self = this; + this.liCache = {}; + this.plCache = {}; + this.poCache = {}; + this.relCache = {}; + this.haveFundClass = {} + this.fundBalanceState = {}; + this.realDfaCache = {}; + this.virtDfaCounts = {}; + this.virtDfaId = -1; + this.dfeOffset = 0; + this.claimEligibleLidByLi = {}; + this.claimEligibleLid = {}; + this.toggleState = false; + this.tbody = dojo.byId('acq-lit-tbody'); + this.selectors = []; + this.noteAcks = {}; + this.authtoken = openils.User.authtoken; + this.pcrud = new openils.PermaCrud(); + this.rowTemplate = this.tbody.removeChild(dojo.byId('acq-lit-row')); + this.copyTbody = dojo.byId('acq-lit-li-details-tbody'); + this.copyRow = this.copyTbody.removeChild(dojo.byId('acq-lit-li-details-row')); + this.copyBatchRow = dojo.byId('acq-lit-li-details-batch-row'); + this.copyBatchWidgets = {}; + this.liNotesTbody = dojo.byId('acq-lit-notes-tbody'); + this.liNotesRow = this.liNotesTbody.removeChild(dojo.byId('acq-lit-notes-row')); + this.realCopiesTbody = dojo.byId('acq-lit-real-copies-tbody'); + this.realCopiesRow = this.realCopiesTbody.removeChild(dojo.byId('acq-lit-real-copies-row')); + this._copy_fields_for_acqdf = ['owning_lib', 'location']; + this.skipInitialEligibilityCheck = false; + this.claimDialog = new ClaimDialogManager( + liClaimDialog, finalClaimDialog, this.claimEligibleLidByLi, + function(li) { /* callback that fires when claims are made */ + self.fetchClaimInfo(li.id(), /* force update */ true); + } + ); + this.vlAgent = new VLAgent(); + + if (dojo.byId('acq-lit-apply-idents')) { + dojo.byId('acq-lit-apply-idents').onclick = function() { + self.applyOrderIdentValues(); + }; + } + + this.focusLineitem = new openils.CGI().param('focus_li'); + + // capture the inline copy display wrapper and row template + this.inlineCopyContainer = + this.tbody.removeChild(dojo.byId('acq-inline-copies-row')); + var tb = dojo.query( + '[name=acq-li-inline-copies-tbody]', this.inlineCopyContainer)[0]; + this.inlineCopyTemplate = tb.removeChild( + dojo.query('[name=acq-li-inline-copies-template]', tb)[0]); + this.inlineNoCopies = tb.removeChild( + dojo.query('[name=acq-li-inline-copies-none]', tb)[0]); + + // list of LI IDs that should be refreshed at next display time + this.inlineCopiesNeedingRefresh = []; + + dojo.byId("acq-lit-li-actions-selector").onchange = function() { + self.applySelectedLiAction(this.options[this.selectedIndex].value); + this.selectedIndex = 0; + }; + + acqLitCreatePoSubmit.onClick = function() { + if (!self.createPoProviderSelector.attr("value") || + !self.createPoAgencySelector.attr("value")) { + alert(localeStrings.CREATE_PO_INVALID); + return false; + } else if (self._confirmPoPrepaySituation()) { + acqLitPoCreateDialog.hide(); + self._createPO(acqLitPoCreateDialog.getValues()); + } else { + return false; + } + } + + acqLitSavePlButton.onClick = function() { + acqLitSavePlDialog.hide(); + self._savePl(acqLitSavePlDialog.getValues()); + } + + acqLitCancelLiStateButton.onClick = function() { + acqLitChangeLiStateDialog.hide(); + } + acqLitSaveLiStateButton.onClick = function() { + acqLitChangeLiStateDialog.hide(); + self._updateLiState(acqLitChangeLiStateDialog.getValues(), acqLitChangeLiStateDialog.attr('state')); + } + + + dojo.byId('acq-lit-select-toggle').onclick = function(){self.toggleSelect()}; + dojo.byId('acq-inline-copies-toggle').onclick = function(){self.toggleInlineCopies()}; + dojo.byId('acq-lit-info-back-button').onclick = function(){self.show('list')}; + dojo.byId('acq-lit-copies-back-button').onclick = function(){self.show('list')}; + dojo.byId('acq-lit-notes-back-button').onclick = function(){self.show('list')}; + dojo.byId('acq-lit-real-copies-back-button').onclick = function(){self.show('list')}; + + this.afwCopyFieldArgs = function(field, perms) { + return { + "fmField" : field, + "fmClass": 'acqlid', + "labelFormat": (field == 'fund') ? fundLabelFormat : null, + "searchFormat": (field == 'fund') ? fundSearchFormat : null, + "searchFilter": (field == 'fund') ? {"active": "t"} : null, + "orgLimitPerms": [perms], + "dijitArgs": { + "required": false, + "labelType": (field == "fund") ? "html" : null + }, + "noCache": (field == "fund"), + "forceSync": true + }; + }; + + /* This is the "new" batch updater that sits atop all lineitems. It does + * use this.afwCopyFieldArgs() to borrow a little common code from the + * "old" batch updater atop the copy details view. */ + this.initBatchUpdater = function(disabled_fields) { + openils.Util.show("acq-batch-update", "table"); + + if (!dojo.isArray(disabled_fields)) disabled_fields = []; + + /* Note that this will directly contain dijits, not the AutoWidget + * wrapper object. */ + this.batchUpdateWidgets = {}; + + this.batchUpdateWidgets.item_count = new dijit.form.TextBox( + { + "style": {"width": "3em"}, + "disabled": Boolean( + dojo.indexOf(disabled_fields, "item_count") != -1 + ) + }, + "acq-bu-item_count" + ); + + (new openils.widget.AutoFieldWidget({ + "fmClass": "acqdf", + "selfReference": true, + "dijitArgs": { "required": false }, + "forceSync": true, + "parentNode": "acq-bu-distribution_formula" + })).build( + function(w) { + dojo.style(w.domNode, {"width": "12em"}); + /* dijitArgs to AutoFieldWidget won't work for 'disabled' */ + w.attr( + "disabled", + dojo.indexOf(disabled_fields, "distribution_formula") != -1 + ); + self.batchUpdateWidgets.distribution_formula = w; + } + ); + + dojo.forEach( + ["owning_lib","location","collection_code","circ_modifier","fund"], + function(field) { + var args = self.afwCopyFieldArgs(field,"CREATE_PURCHASE_ORDER"); + args.parentNode = dojo.byId("acq-bu-" + field); + + (new openils.widget.AutoFieldWidget(args)).build( + function(w, aw) { + if (field == "fund") { + dojo.connect( + w, "onChange", function(val) { + self._updateFundSelectorStyle(aw, val); + } + ); + if (w.store) + self._ensureCSSFundClasses(w.store); + } + + dojo.style(w.domNode, {"width": "10em"}); + w.attr( + "disabled", + dojo.indexOf(disabled_fields, field) != -1 + ); + self.batchUpdateWidgets[field] = w; + } + ); + } + ); + + acqBatchUpdateApply.onClick = function() { + var li_id_list = self.getSelected(false, null, true /* id list */); + if (!li_id_list.length) { + alert(localeStrings.NO_LI_TO_UPDATE); + return; + } + + progressDialog.show(true); + progressDialog.attr("title", localeStrings.LI_BATCH_UPDATE); + progressDialog.update({"maximum": li_id_list.length,"progress": 0}); + + var count = 0; + + var params = [ self.authtoken, {"lineitems": li_id_list}, + self.batchUpdateChanges(), self.batchUpdateFormula() ]; + console.log("batch update params: " + dojo.toJson(params)); + + fieldmapper.standardRequest( + ["open-ils.acq", "open-ils.acq.lineitem.batch_update"], { + "async": true, + "params": params, + "onresponse": function(r) { + if ((r = openils.Util.readResponse(r))) { // assignment + progressDialog.update({"progress": ++count}); + } else { + progressDialog.hide(); + progressDialog.attr("title", ""); + } + }, + "oncomplete": function() { + /* XXX Is the last call to onresponse guaranteed to + * finish before oncomplete is fired? */ + if (count != li_id_list.length) { + console.error("lineitem batch update operation failed"); + progressDialog.hide(); + progressDialog.attr("title", ""); + } else { + location.href = location.href; + } + } + } + ); + }; + }; + + this.batchUpdateChanges = function() { + var o = {}; + + dojo.forEach( + openils.Util.objectProperties(this.batchUpdateWidgets), + function(k) { + if (k == "distribution_formula") return; /* handled elsewhere */ + if (self.batchUpdateWidgets[k].attr("disabled")) return; + + /* It's important that a value of "" should mean that a field + * doesn't get used in the arguments to the batch updater API, + * but 0 should mean an actual 0. */ + var value = self.batchUpdateWidgets[k].attr("value"); + if (value !== "") + o[k] = value; + } + ); + + return o; + }; + + this.batchUpdateFormula = function() { + if (this.batchUpdateWidgets.distribution_formula.attr("disabled")) { + return null; + } else { + return ( + this.batchUpdateWidgets.distribution_formula.attr("value") || + null + ); + } + }; + + this.reset = function(keep_selectors) { + while(self.tbody.childNodes[0]) + self.tbody.removeChild(self.tbody.childNodes[0]); + self.noteAcks = {}; + self.relCache = {}; + + if (!keep_selectors) + self.selectors = []; + }; + + this.setNext = function(handler) { + var link = dojo.byId('acq-lit-next'); + if(handler) { + dojo.style(link, 'visibility', 'visible'); + link.onclick = handler; + } else { + dojo.style(link, 'visibility', 'hidden'); + } + }; + + this.setPrev = function(handler) { + var link = dojo.byId('acq-lit-prev'); + if(handler) { + dojo.style(link, 'visibility', 'visible'); + link.onclick = handler; + } else { + dojo.style(link, 'visibility', 'hidden'); + } + }; + + this.enableActionsDropdownOptions = function(mask) { + /* 'mask' is probably a misnomer the way I'm using it, but it needs to + * be one of pl,po,ao,gs,vp, or fs. */ + dojo.query("option", "acq-lit-li-actions-selector").forEach( + function(option) { + var opt_mask = dojo.attr(option, "mask"); + + /* For each