install_date TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
-INSERT INTO config.upgrade_log (version) VALUES ('0232'); -- Scott McKellar
+INSERT INTO config.upgrade_log (version) VALUES ('0233'); -- senator
CREATE TABLE config.bib_source (
id SERIAL PRIMARY KEY,
payment_auth TEXT,
payment_method TEXT REFERENCES acq.invoice_payment_method (code)
DEFERRABLE INITIALLY DEFERRED,
- note TEXT
+ note TEXT,
+ CONSTRAINT inv_ident_once_per_provider UNIQUE(provider, inv_ident)
);
CREATE TABLE acq.invoice_entry (
--- /dev/null
+BEGIN;
+
+INSERT INTO config.upgrade_log (version) VALUES ('0233'); -- senator
+
+ALTER TABLE acq.invoice
+ ADD CONSTRAINT inv_ident_once_per_provider UNIQUE(provider, inv_ident);
+
+COMMIT;
.acq-inoice-item-info { font-weight: bold; }
.acq-invoice-row td { border-bottom: 1px solid #e0e0e0; }
.acq-invoice-invalid-amount input { color: red; font-weight: bold; }
-
+.acq-link-invoice-dialog td,.acq-link-invoice-dialog th {padding-top: 10px;}
'INVOICE_CONFIRM_ENTRY_DETACH' : "Remove $${0} charge for item '${1}, ${2} [${3}] from the invoice?",
'INVOICE_TITLE_DETAILS' : "<div class='acq-inoice-item-info'>${0}, by ${1} (${2})</div><div class='acq-inoice-item-extra-info'><a style='padding-right: 10px;' href='${9}/acq/po/view/${10}'>PO: ${11}</a>${3} Ordered, ${4} Received, ${7} Invoiced</div><div class='acq-inoice-item-extra-info'> Estimated Cost Per Item $${5} / Total Estimated Cost $${6}</div>",
'INVOICE_CONFIRM_PRORATE' : "Prorate charges?\n\nAny subsequent changes to the invoice that would affect prorated amounts should be resolved manually.",
- 'UNNAMED': "Unnamed"
+ 'UNNAMED': "Unnamed",
+ 'NO_FIND_INVOICE': "Could not find that invoice.\nNote that the Invoice # field is case-sensitive."
}
--- /dev/null
+function InvoiceLinkDialogManager(which, target) {
+ var self = this;
+ this.inv = null;
+
+ this.linkFoundInvoice = function(r) {
+ self.inv = openils.Util.readResponse(r);
+ location.href = oilsBasePath + "/acq/invoice/view/" + self.inv.id() +
+ "?attach_" + self.which + "=" + self.target.id();
+ };
+
+ this.which = which;
+ if (target)
+ this.target = target;
+
+ new openils.widget.AutoFieldWidget({
+ "fmField": "provider",
+ "fmClass": "acqinv",
+ "parentNode": dojo.byId("acq-" + this.which + "-link-invoice-provider"),
+ "orgLimitPerms": ["VIEW_INVOICE"],
+ "forceSync": true
+ }).build();
+
+ dijit.byId("acq-" + this.which + "-link-invoice-link").onClick =
+ function() {
+ self.inv = null;
+ pcrud.search(
+ "acqinv", {
+ "provider": dijit.byId(
+ "acq-" + self.which + "-link-invoice-provider"
+ ).attr("value"),
+ "inv_ident":
+ dijit.byId(
+ "acq-" + self.which + "-link-invoice-inv_ident"
+ ).attr("value")
+ }, {
+ "async": true,
+ "streaming": true,
+ "onresponse": self.linkFoundInvoice,
+ "oncomplete": function() {
+ if (!self.inv)
+ alert(localeStrings.NO_FIND_INVOICE);
+ }
+ }
+ );
+ };
+}
dojo.require('dijit.form.Textarea');
dojo.require('dijit.Tooltip');
dojo.require('dijit.ProgressBar');
-dojo.require('openils.User');
-dojo.require('openils.Util');
dojo.require('openils.acq.Lineitem');
dojo.require('openils.acq.PO');
dojo.require('openils.acq.Picklist');
dojo.require('dojo.data.ItemFileReadStore');
dojo.require('openils.widget.ProgressDialog');
dojo.require('openils.PermaCrud');
-dojo.require('openils.XUL');
dojo.requireLocalization('openils.acq', 'acq');
var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
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.invoiceLinkDialogManager = new InvoiceLinkDialogManager("li");
dojo.connect(acqLitLiActionsSelector, 'onChange',
function() {
nodeByName("action_none", row).selected = true;
};
actLinkInvoice.onclick = function() {
- // TODO: show inv #/vendor entry then relocate to invoice attach page
+ self.invoiceLinkDialogManager.target = li;
+ acqLitLinkInvoiceDialog.show();
nodeByName("action_none", row).selected = true;
};
actViewInvoice.onclick = function() {
- // TODO: go to invoice search page, with lineitem filter = li.id()
+ location.href = oilsBasePath +
+ "/acq/search/unified?so=" +
+ base64Encode({"jub":[{"id": li.id()}]}) +
+ "&rt=invoice";
nodeByName("action_none", row).selected = true;
};
dojo.require("dojo.string");
dojo.require('dijit.layout.ContentPane');
-dojo.require('openils.User');
-dojo.require('openils.Util');
dojo.require('openils.PermaCrud');
var pcrud = new openils.PermaCrud();
var PO = null;
var liTable;
var poNoteTable;
+var invoiceLinkDialogManager;
function AcqPoNoteTable() {
var self = this;
}
}
+function prepareInvoiceFeatures() {
+ /* show the count of related invoices on the "view invoices" button */
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.invoice.unified_search.atomic"], {
+ "params": [
+ openils.User.authtoken,
+ {"acqpo":[{"id": PO.id()}]},
+ null,
+ null,
+ {"id_list": true}
+ ],
+ "async": true,
+ "oncomplete": function(r) {
+ dojo.byId("acq-po-view-invoice-count").innerHTML =
+ openils.Util.readResponse(r).length;
+ }
+ }
+ );
+
+ /* view invoices button */
+ dijit.byId("acq-po-view-invoice-link").onClick = function() {
+ location.href = oilsBasePath + "/acq/search/unified?so=" +
+ base64Encode({"jub":[{"purchase_order": PO.id()}]}) +
+ "&rt=invoice";
+ };
+
+ /* create invoice button */
+ dijit.byId("acq-po-create-invoice-link").onClick = function() {
+ location.href = oilsBasePath +
+ "/acq/invoice/view?create=1&attach_po=" + PO.id();
+ };
+
+ if (!invoiceLinkDialogManager)
+ invoiceLinkDialogManager = new InvoiceLinkDialogManager("po", PO);
+
+ openils.Util.show("acq-po-view-invoices", "table-row");
+}
+
function renderPo() {
dojo.byId("acq-po-view-id").innerHTML = PO.id();
dojo.byId("acq-po-view-name").innerHTML = PO.name();
openils.Util.show("acq-po-split");
}
- dojo.byId('acq-po-create-invoice-link').onclick =
- function() {
- location.href = oilsBasePath + '/acq/invoice/view?create=1&attach_po=' + poId;
- };
-
- dojo.byId("acq-po-view-invoice-link").onclick =
- function() {
- location.href = oilsBasePath + "/acq/search/unified?so=" +
- base64Encode({"jub":[{"purchase_order": PO.id()}]}) +
- "&rt=invoice";
- };
+ prepareInvoiceFeatures();
}
var selector = this.selectorFactory.make(uniq);
dojo.attr(
- selector,
- "onchange",
- function() { self.updateRowWidget(uniq); }
+ selector, "onchange", function() { self.updateRowWidget(uniq); }
);
var match_how = dojo.query("select", nodeByName("match", row))[0];
dojo.attr(match_how, "id", "term-match-" + uniq);
dojo.attr(match_how, "selectedIndex", 0);
+ dojo.attr(
+ match_how, "onchange",
+ function() {
+ if (self.widgets[uniq]) self.widgets[uniq].focus();
+ }
+ );
nodeByName("selector", row).appendChild(selector);
nodeByName("remove", row).appendChild(this.removerButton(uniq));
dijit.byId("acq-unified-inv-grid")
);
- openils.Util.show("acq-unified-body");
-
uriManager = new URIManager();
if (uriManager.search_object) {
+ hideForm();
+ openils.Util.show("acq-unified-body");
termManager.reflect(uriManager.search_object);
resultManager.search(uriManager.search_object);
} else {
termManager.addRow();
+ openils.Util.show("acq-unified-body");
}
}
);
<!ENTITY staff.main.menu.acq.picklist.accesskey "L">
<!ENTITY staff.main.menu.acq.bib_search.label "Title Search">
<!ENTITY staff.main.menu.acq.bib_search.accesskey "T">
-<!ENTITY staff.main.menu.acq.li_search.label "Lineitem Search">
-<!ENTITY staff.main.menu.acq.li_search.accesskey "I">
<!ENTITY staff.main.menu.acq.unified_search.label "Acquisitions Search">
<!ENTITY staff.main.menu.acq.unified_search.accesskey "A">
<!ENTITY staff.main.menu.acq.brief_record.label "New Brief Record">
--- /dev/null
+<script src="[% ctx.media_prefix %]/js/ui/default/acq/common/inv_dialog.js">
+</script>
+<big><strong>Choose invoice</big></strong>
+<table class="acq-link-invoice-dialog">
+ <tr>
+ <th>
+ <label for="acq-[% which %]-link-invoice-provider">Provider</label>
+ </th>
+ <td>
+ <span id="acq-[% which %]-link-invoice-provider"></span>
+ </td>
+ </tr>
+ <tr>
+ <th>
+ <label for="acq-[% which %]-link-invoice-inv_ident">
+ Invoice #
+ </label>
+ </th>
+ <td>
+ <input id="acq-[% which %]-link-invoice-inv_ident"
+ dojoType="dijit.form.TextBox" />
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" style="text-align: center;">
+ <button id="acq-[% which %]-link-invoice-link"
+ dojoType="dijit.form.Button" type="submit">Link</button>
+ </td>
+ </tr>
+</table>
+<script src="[% ctx.media_prefix %]/js/ui/default/acq/common/base64.js"> </script>
<script src='[% ctx.media_prefix %]/js/ui/default/acq/common/li_table.js'> </script>
<div id='acq-lit-table-container'>
<div id='acq-lit-table-div' class='hidden'>
<table id='acq-lit-li-details-table'>
<tbody style='background-color:#ddd;'>
<tr id='acq-lit-li-details-batch-row'>
- <td><div name='owning_lib'/></td>
- <td><div name='location'/></td>
- <td><div name='collection_code'/></td>
- <td><div name='fund'/></td>
- <td><div name='circ_modifier'/></td>
- <td><div name='cn_label'/></td>
+ <td><div name='owning_lib'></div></td>
+ <td><div name='location'></div></td>
+ <td><div name='collection_code'></div></td>
+ <td><div name='fund'></div></td>
+ <td><div name='circ_modifier'></div></td>
+ <td><div name='cn_label'></div></td>
<td colspan='3' style='text-align:left;'>
<div dojoType='dijit.form.Button' jsId='acqLitBatchUpdateCopies'>Batch Update</div>
</td>
</tbody>
<tbody id='acq-lit-li-details-tbody' class='oils-generic-table'>
<tr id='acq-lit-li-details-row'>
- <td><div name='owning_lib'/></td>
- <td><div name='location'/></td>
- <td><div name='collection_code'/></td>
- <td><div name='fund'/></td>
- <td><div name='circ_modifier'/></td>
- <td><div name='cn_label'/></td>
- <td><div name='barcode'/></td>
- <td><div name='note'/></td>
+ <td><div name='owning_lib'></div></td>
+ <td><div name='location'></div></td>
+ <td><div name='collection_code'></div></td>
+ <td><div name='fund'></div></td>
+ <td><div name='circ_modifier'></div></td>
+ <td><div name='cn_label'></div></td>
+ <td><div name='barcode'></div></td>
+ <td><div name='note'></div></td>
<td><a href='javascript:void(0);' name='receive'>Mark Received</a><a href='javascript:void(0);' name='unreceive'>Un-Receive</a> <a href="javascript:void(0);" name='cancel'>Cancel</a><span class="hidden" name='cancel_reason'></span></td>
<td><div name='delete' dojoType='dijit.form.Button' style='color:red;'>X</div></td>
</tr>
</tbody>
<tbody id='acq-lit-real-copies-tbody' class='oils-generic-table'>
<tr id='acq-lit-real-copies-row'>
- <td><div name='owning_lib'/></td>
- <td><div name='location'/></td>
- <td><div name='circ_modifier'/></td>
- <td><div name='label'/></td>
- <td><div name='barcode'/></td>
+ <td><div name='owning_lib'></div></td>
+ <td><div name='location'></div></td>
+ <td><div name='circ_modifier'></div></td>
+ <td><div name='label'></div></td>
+ <td><div name='barcode'></div></td>
</tr>
</tbody>
</table>
</div>
+ <div jsId="acqLitLinkInvoiceDialog" dojoType="dijit.Dialog">
+ [% INCLUDE "default/acq/common/inv_dialog.tt2" which = "li" %]
+ </div>
+
<div class='hidden' id='acq-lit-progress-numbers'>
<table class='oils-generic-table'>
<tbody>
<table class='oils-generic-table'>
<tr>
<td>Ordering Agency</td>
- <td><div name='ordering_agency' id='acq-lit-po-agency'/></td>
+ <td><div name='ordering_agency' id='acq-lit-po-agency'></div></td>
</tr>
<tr>
<td>Provider</td>
- <td><div name='provider' id='acq-lit-po-provider'/></td>
+ <td><div name='provider' id='acq-lit-po-provider'></div></td>
</tr>
<tr>
<td>Prepayment Required</td>
<div class='hidden'>
- <div dojoType='openils.widget.ProgressDialog' jsId='progressDialog'/>
+ <div dojoType='openils.widget.ProgressDialog' jsId='progressDialog'></div>
</div>
</div>
</td>
</tr>
<tr><td><a class="hidden" id="acq-po-split" href="javascript:void(0);" onclick="if (confirm(localeStrings.CONFIRM_SPLIT_PO)) splitPo();">Split Order by Lineitems</a></td></tr>
- <tr id='acq-po-view-invoices'> <!-- TODO: hidden until applicable -->
+ <tr id="acq-po-view-invoices" class="hidden"><!-- TODO: only reveal when really applicable -->
<td>Invoicing</td>
<td>
- <a href="javascript:void(0);" id="acq-po-view-invoice-link">View Invoices</a> /
- <a href="javascript:void(0);" id="acq-po-create-invoice-link">Create Invoice</a> /
- <a href="javascript:void(0);" id="acq-po-link-invoice-link">Link Invoice</a>
+ <button dojoType="dijit.form.Button"
+ id="acq-po-view-invoice-link">
+ View Invoices
+ (<span id="acq-po-view-invoice-count"></span>)
+ </button>
+ <button dojoType="dijit.form.Button"
+ id="acq-po-create-invoice-link">
+ Create Invoice
+ </button>
+ <button dojoType="dijit.form.DropDownButton">
+ <span>Link Invoice</span>
+ <div dojoType="dijit.TooltipDialog"
+ id="acq-po-link-invoice">
+ [% INCLUDE "default/acq/common/inv_dialog.tt2"
+ which = "po" %]
+ </div>
+ </button>
</td>
</tr>
</table>
</select>
<label for="acq-unified-conjunction">matching</label>
<select id="acq-unified-conjunction">
- <option value="or">any</option>
<option value="and">all</option>
+ <option value="or">any</option>
</select>
<label for="acq-unified-conjunction">
of the following terms:
['oncommand'],
function() { open_eg_web_page('acq/search/unified', 'menu.cmd_acq_unified_search.tab'); }
],
- 'cmd_acq_li_search' : [
- ['oncommand'],
- function() { open_eg_web_page('acq/lineitem/search', 'menu.cmd_acq_li_search.tab'); }
- ],
'cmd_acq_new_brief_record' : [
['oncommand'],
function() { open_eg_web_page('acq/picklist/brief_record', 'menu.cmd_acq_new_brief_record.tab'); }
<command id="cmd_acq_view_po_events" />
<command id="cmd_acq_user_requests" />
<command id="cmd_acq_bib_search" />
- <command id="cmd_acq_li_search" />
<command id="cmd_acq_unified_search" />
<command id="cmd_acq_new_brief_record" />
<command id="cmd_acq_view_fund" />
<menupopup id="main.menu.acq.popup">
<menuitem label="&staff.main.menu.acq.unified_search.label;" accesskey="&staff.main.menu.acq.unified_search.accesskey;" command="cmd_acq_unified_search"/>
<menuitem label="&staff.main.menu.acq.bib_search.label;" accesskey="&staff.main.menu.acq.bib_search.accesskey;" command="cmd_acq_bib_search"/>
- <menuitem label="&staff.main.menu.acq.li_search.label;" accesskey="&staff.main.menu.acq.li_search.accesskey;" command="cmd_acq_li_search"/>
<menuitem label="&staff.main.menu.acq.po.label;" accesskey="&staff.main.menu.acq.po.accesskey;" command="cmd_acq_view_po" />
<menuitem label="&staff.main.menu.acq.picklist.label;" accesskey="&staff.main.menu.acq.picklist.accesskey;" command="cmd_acq_view_picklist"/>
<menuseparator />
menu.cmd_acq_view_picklist.tab=Selection Lists
menu.cmd_acq_bib_search.tab=Title Search
menu.cmd_acq_unified_search.tab=Acquisitions Search
-menu.cmd_acq_li_search.tab=Lineitem Search
menu.cmd_acq_upload.tab=Load Order Record
menu.cmd_acq_new_brief_record.tab=New Brief Record
menu.cmd_acq_view_po.tab=Purchase Orders