Acq: PO items i'face (acq.po_item is a peer of acq.lineitem for non-bib stuff)
authorsenator <senator@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Tue, 4 May 2010 21:24:30 +0000 (21:24 +0000)
committersenator <senator@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Tue, 4 May 2010 21:24:30 +0000 (21:24 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@16388 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/web/css/skin/default/acq.css
Open-ILS/web/js/ui/default/acq/po/item_table.js [new file with mode: 0644]
Open-ILS/web/js/ui/default/acq/po/view_po.js
Open-ILS/web/templates/default/acq/po/item_table.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/acq/po/view.tt2

index f55da56..01c5c57 100644 (file)
@@ -236,3 +236,9 @@ option[disabled="disabled"] { font-style: italic; }
 #acq-eligible-li-table th { background-color: #ccc; border: 1px #333 inset; font-weight: bold; padding: 6px; }
 #acq-eligible-li-table td { padding: 2px 6px; border: 1px #333 inset; }
 #acq-eligible-li-table div[name="lid_link_holder"] { margin-left: 10px; }
+
+#acq-po-item-table th { font-weight: bold; padding: 2px 6px; }
+#acq-po-item-table-items tr td { padding: 2px 6px; }
+#acq-po-item-table-items tr td button[name="delete"] { color: #c00; }
+#acq-po-item-table-items tr { margin: 6px 0; }
+#acq-po-item-table-controls { margin-top: 8px; }
diff --git a/Open-ILS/web/js/ui/default/acq/po/item_table.js b/Open-ILS/web/js/ui/default/acq/po/item_table.js
new file mode 100644 (file)
index 0000000..3c1f9a5
--- /dev/null
@@ -0,0 +1,175 @@
+function PoItemTable() {
+    var self = this;
+
+    this.init = function(po, pcrud) {
+        this.po = po;
+        this.pcrud = pcrud || new openils.PermaCrud();
+
+        this.tHead = dojo.byId("acq-po-item-table-headings");
+        this.tBody = dojo.byId("acq-po-item-table-items");
+        this.template = this.tBody.removeChild(dojo.query("tr", this.tBody)[0]);
+        dojo.byId("acq-po-item-table-new-charge").onclick = function() {
+            self.addItem();
+        };
+        dojo.byId("acq-po-item-table-save-new").onclick = function() {
+            self.saveNew();
+        };
+
+        this.fundAWArgs = {
+            "searchFilter": {"active": "t"},
+            "searchFormat": ["${0} (${1})", "code", "year"],
+            "labelFormat": [
+                "<span class='fund_${0}'>${1} (${2})</span>",
+                "id", "code", "year"
+            ],
+            "dijitArgs": {"labelType": "html"},
+            "noCache": true
+        };
+
+        this.reset();
+    };
+
+    this.empty = function(which) {
+        if (this._empty == which) return; /* nothing to do */
+
+        openils.Util[which ? "show" : "hide"]("acq-po-item-table-i-am-empty");
+        openils.Util[which ? "hide" : "show"](this.tHead, "table-header-group");
+        this._empty = which;
+    };
+
+    this.reset = function() {
+        this.rowId = -1;
+        this.rows = {};
+        this.realItems = {};
+        dojo.empty(this.tBody);
+        this.empty(true);
+
+        this.disableSave();
+    };
+
+    this.hide = function() { openils.Util.hide("acq-po-item-table"); };
+
+    this.show = function() { openils.Util.show("acq-po-item-table"); };
+
+    this.disableSave = function() {
+        dojo.byId("acq-po-item-table-save-new").disabled = true;
+    };
+
+    this.rowIndices = function() {
+        return openils.Util.objectProperties(this.rows);
+    };
+
+    this.newRowIndices = function() {
+        return this.rowIndices().filter(function(o) { return o < 0; });
+    };
+
+    this.saveNew = function() {
+        var virtIds = this.newRowIndices();
+        var po_items = virtIds.map(
+            function(k) {
+                var widgets = self.rows[k];
+                var po_item = new acqpoi();
+                for (var field in widgets)
+                    po_item[field](widgets[field].attr("value"));
+                po_item.purchase_order(self.po.id());
+                return po_item;
+            }
+        );
+
+        progressDialog.show(true);
+
+        pcrud.create(
+            po_items, {
+                "oncomplete": function(r, objs) {
+                    progressDialog.hide();
+                    r = openils.Util.readResponse(r); /* may not use */
+
+                    virtIds.forEach(function(k) { self.deleteRow(k); });
+                    objs.forEach(function(o) { self.addItem(o); });
+                }
+            }
+        );
+    };
+
+    this._deleteRow = function(id) {
+        dojo.destroy(dojo.query("[rowId='" + id + "']")[0]);
+        delete this.rows[id];
+        delete this.realItems[id];
+
+        if (!this.rowIndices().length) this.reset();
+        else if (!this.newRowIndices().length) this.disableSave();
+    };
+
+    this.deleteRow = function(id) {
+        if (id > 0) {
+            progressDialog.show(true);
+            pcrud.eliminate(
+                this.realItems[id], {
+                    "oncomplete": function(r) {
+                        progressDialog.hide();
+                        r = openils.Util.readResponse(r); /* may not use */
+
+                        self._deleteRow(id);
+                    }
+                }
+            );
+        } else {
+            this._deleteRow(id);
+        }
+    };
+
+    this._addItemRow = function(item) {
+        var ourId = item ? item.id() : this.rowId--;
+
+        if (item)
+            this.realItems[ourId] = item;
+
+        this.rows[ourId] = {};
+        var row = dojo.clone(this.template);
+        dojo.attr(row, "rowId", ourId);
+
+        nodeByName("delete", row).onclick = function() {
+            self.deleteRow(ourId);
+        };
+
+        return {"id": ourId, "node": row};
+    };
+
+    /* add a row with widgets for the user to enter new data */
+    this.addItem = function(item) {
+        var row = this._addItemRow(item);
+
+        dojo.query("td[name]", row.node).forEach(
+            function(element) {
+                var field = dojo.attr(element, "name");
+                var em = dojo.attr(element, "em");
+                var awArgs = dojo.mixin(
+                    {
+                        "fmField": field,
+                        "parentNode": dojo.create(
+                            "div", {"style": "width: " +
+                                String(Number(em) + 1) + "em"},
+                            element, "only"
+                        ),
+                        "orgLimitPerms": ["CREATE_PURCHASE_ORDER"],
+                        "dijitArgs": {"style": "width: " + em + "em"},
+                        "readOnly": Boolean(item)
+                    },
+                    (field == "fund" ? self.fundAWArgs : {}),
+                    (item ? {"fmObject": item} : {"fmClass": "acqpoi"})
+                );
+                new openils.widget.AutoFieldWidget(awArgs).build(
+                    function(w) { self.rows[row.id][field] = w; }
+                );
+            }
+        );
+
+        this.empty(false);
+
+        dojo.place(row.node, this.tBody, "last");
+        if (!item)
+            dojo.byId("acq-po-item-table-save-new").disabled = false;
+    };
+
+    this.init.apply(this, arguments);
+}
index c68f1c6..cc3c2a7 100644 (file)
@@ -5,6 +5,7 @@ dojo.require('openils.PermaCrud');
 var pcrud = new openils.PermaCrud();
 var PO = null;
 var liTable;
+var poItemTable;
 var poNoteTable;
 var invoiceLinkDialogManager;
 
@@ -145,10 +146,12 @@ function AcqPoNoteTable() {
     this.hide = function() {
         openils.Util.hide("acq-po-notes-div");
         liTable.show("list");
+        poItemTable.show();
     };
 
     this.show = function() {
         liTable.hide();
+        poItemTable.hide();
         self.drawPoNotes();
         openils.Util.show("acq-po-notes-div");
     };
@@ -325,6 +328,13 @@ function renderPo() {
             openils.Util.show("acq-po-split");
     }
 
+    // XXX we probably don't *always* need to do this...
+    poItemTable.reset();
+    PO.po_items().forEach(
+        function(po_item) { poItemTable.addItem(po_item); }
+    );
+    poItemTable.show();
+
     prepareInvoiceFeatures();
 }
 
@@ -347,10 +357,15 @@ function init() {
                 "flesh_provider": true,
                 "flesh_price_summary": true,
                 "flesh_lineitem_count": true,
-                "flesh_notes": true
+                "flesh_notes": true,
+                "flesh_po_items": true
             }],
             oncomplete: function(r) {
                 PO = openils.Util.readResponse(r); /* save PO globally */
+
+                /* po item table */
+                poItemTable = new PoItemTable(PO, pcrud);
+
                 renderPo();
             }
         }
diff --git a/Open-ILS/web/templates/default/acq/po/item_table.tt2 b/Open-ILS/web/templates/default/acq/po/item_table.tt2
new file mode 100644 (file)
index 0000000..1948b6d
--- /dev/null
@@ -0,0 +1,34 @@
+<div id="acq-po-item-table" class="hidden">
+    <h3>Direct Charges, Taxes, Fees, etc.</h3>
+    <table>
+        <thead id="acq-po-item-table-headings">
+            <tr>
+                <th>Charge Type</th>
+                <th>Fund</th>
+                <th>Title/Description</th>
+                <th>Author</th>
+                <th>Note</th>
+                <th>Estimated Cost</th>
+                <th><!-- Delete --></th>
+            </tr>
+        </thead>
+        <tbody id="acq-po-item-table-items">
+            <tr>
+                <td name="inv_item_type" em="12"></td>
+                <td name="fund" em="10"></td>
+                <td name="title" em="12"></td>
+                <td name="author" em="8"></td>
+                <td name="note" em="12"></td>
+                <td name="estimated_cost" em="8"></td>
+                <td><button name="delete">X</button></td>
+            </tr>
+        </tbody>
+    </table>
+    <div id="acq-po-item-table-i-am-empty" class="hidden">
+        <em>There are no miscellanea attached to this purchase order.</em>
+    </div>
+    <div id="acq-po-item-table-controls">
+        <button id="acq-po-item-table-new-charge">New Charge</button> &nbsp;
+        <button id="acq-po-item-table-save-new">Save New Charges</button>
+    </div>
+</div>
index 24d3e50..5e1c56d 100644 (file)
@@ -1,6 +1,7 @@
 [% WRAPPER 'default/base.tt2' %]
 <script src="[% ctx.media_prefix %]/js/ui/default/acq/common/base64.js"> </script>
 <script src='[% ctx.media_prefix %]/js/ui/default/acq/po/view_po.js'> </script>
+<script src="[% ctx.media_prefix %]/js/ui/default/acq/po/item_table.js"></script>
 <div dojoType="dijit.layout.ContentPane" style="height:100%">
     <div>
         <div id='oils-acq-picklist-header'>
@@ -87,5 +88,6 @@
     </script>
     [% INCLUDE 'default/acq/common/li_table.tt2' %]
     [% INCLUDE "default/acq/common/notes.tt2" which = "Po" %]
+    [% INCLUDE "default/acq/po/item_table.tt2" %]
 </div>
 [% END %]